diff --git a/[refs] b/[refs] index f23e82787614..5224f5e7a54f 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 891cc2283216bf76f387546f0e220caf8ce9fbf9 +refs/heads/master: 6ce1f81f51c7b22f539012e446c01e8c75d20fd9 diff --git a/trunk/Documentation/cgroups/memory.txt b/trunk/Documentation/cgroups/memory.txt index 7781857dc940..bac328c232f5 100644 --- a/trunk/Documentation/cgroups/memory.txt +++ b/trunk/Documentation/cgroups/memory.txt @@ -385,6 +385,10 @@ mapped_file - # of bytes of mapped file (includes tmpfs/shmem) pgpgin - # of pages paged in (equivalent to # of charging events). pgpgout - # of pages paged out (equivalent to # of uncharging events). swap - # of bytes of swap usage +dirty - # of bytes that are waiting to get written back to the disk. +writeback - # of bytes that are actively being written back to the disk. +nfs_unstable - # of bytes sent to the NFS server, but not yet committed to + the actual storage. inactive_anon - # of bytes of anonymous memory and swap cache memory on LRU list. active_anon - # of bytes of anonymous and swap cache memory on active @@ -406,6 +410,9 @@ total_mapped_file - sum of all children's "cache" total_pgpgin - sum of all children's "pgpgin" total_pgpgout - sum of all children's "pgpgout" total_swap - sum of all children's "swap" +total_dirty - sum of all children's "dirty" +total_writeback - sum of all children's "writeback" +total_nfs_unstable - sum of all children's "nfs_unstable" total_inactive_anon - sum of all children's "inactive_anon" total_active_anon - sum of all children's "active_anon" total_inactive_file - sum of all children's "inactive_file" @@ -453,6 +460,73 @@ memory under it will be reclaimed. You can reset failcnt by writing 0 to failcnt file. # echo 0 > .../memory.failcnt +5.5 dirty memory + +Control the maximum amount of dirty pages a cgroup can have at any given time. + +Limiting dirty memory is like fixing the max amount of dirty (hard to reclaim) +page cache used by a cgroup. So, in case of multiple cgroup writers, they will +not be able to consume more than their designated share of dirty pages and will +be forced to perform write-out if they cross that limit. + +The interface is equivalent to the procfs interface: /proc/sys/vm/dirty_*. It +is possible to configure a limit to trigger both a direct writeback or a +background writeback performed by per-bdi flusher threads. The root cgroup +memory.dirty_* control files are read-only and match the contents of +the /proc/sys/vm/dirty_* files. + +Per-cgroup dirty limits can be set using the following files in the cgroupfs: + +- memory.dirty_ratio: the amount of dirty memory (expressed as a percentage of + cgroup memory) at which a process generating dirty pages will itself start + writing out dirty data. + +- memory.dirty_limit_in_bytes: the amount of dirty memory (expressed in bytes) + in the cgroup at which a process generating dirty pages will start itself + writing out dirty data. Suffix (k, K, m, M, g, or G) can be used to indicate + that value is kilo, mega or gigabytes. + + Note: memory.dirty_limit_in_bytes is the counterpart of memory.dirty_ratio. + Only one of them may be specified at a time. When one is written it is + immediately taken into account to evaluate the dirty memory limits and the + other appears as 0 when read. + +- memory.dirty_background_ratio: the amount of dirty memory of the cgroup + (expressed as a percentage of cgroup memory) at which background writeback + kernel threads will start writing out dirty data. + +- memory.dirty_background_limit_in_bytes: the amount of dirty memory (expressed + in bytes) in the cgroup at which background writeback kernel threads will + start writing out dirty data. Suffix (k, K, m, M, g, or G) can be used to + indicate that value is kilo, mega or gigabytes. + + Note: memory.dirty_background_limit_in_bytes is the counterpart of + memory.dirty_background_ratio. Only one of them may be specified at a time. + When one is written it is immediately taken into account to evaluate the dirty + memory limits and the other appears as 0 when read. + +A cgroup may contain more dirty memory than its dirty limit. This is possible +because of the principle that the first cgroup to touch a page is charged for +it. Subsequent page counting events (dirty, writeback, nfs_unstable) are also +counted to the originally charged cgroup. + +Example: If page is allocated by a cgroup A task, then the page is charged to +cgroup A. If the page is later dirtied by a task in cgroup B, then the cgroup A +dirty count will be incremented. If cgroup A is over its dirty limit but cgroup +B is not, then dirtying a cgroup A page from a cgroup B task may push cgroup A +over its dirty limit without throttling the dirtying cgroup B task. + +When use_hierarchy=0, each cgroup has dirty memory usage and limits. +System-wide dirty limits are also consulted. Dirty memory consumption is +checked against both system-wide and per-cgroup dirty limits. + +The current implementation does not enforce per-cgroup dirty limits when +use_hierarchy=1. System-wide dirty limits are used for processes in such +cgroups. Attempts to read memory.dirty_* files return the system-wide +values. Writes to the memory.dirty_* files return error. An enhanced +implementation is needed to check the chain of parents to ensure that no +dirty limit is exceeded. + 6. Hierarchy support The memory controller supports a deep hierarchy and hierarchical accounting. diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 89e4d4b145bb..af656ded404e 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -5272,7 +5272,8 @@ S: Supported F: drivers/s390/net/ S390 ZCRYPT DRIVER -M: Holger Dengler +M: Felix Beck +M: Ralph Wuerthner M: linux390@de.ibm.com L: linux-s390@vger.kernel.org W: http://www.ibm.com/developerworks/linux/linux390/ diff --git a/trunk/arch/ia64/include/asm/page.h b/trunk/arch/ia64/include/asm/page.h index 41b6d31110fd..961a16f43e6b 100644 --- a/trunk/arch/ia64/include/asm/page.h +++ b/trunk/arch/ia64/include/asm/page.h @@ -189,6 +189,7 @@ get_order (unsigned long size) # define pgprot_val(x) ((x).pgprot) # define __pte(x) ((pte_t) { (x) } ) +# define __pmd(x) ((pmd_t) { (x) } ) # define __pgprot(x) ((pgprot_t) { (x) } ) #else /* !STRICT_MM_TYPECHECKS */ diff --git a/trunk/arch/s390/defconfig b/trunk/arch/s390/defconfig index 29c82c640a88..d79697157ac0 100644 --- a/trunk/arch/s390/defconfig +++ b/trunk/arch/s390/defconfig @@ -5,21 +5,10 @@ CONFIG_AUDIT=y CONFIG_RCU_TRACE=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y -CONFIG_CGROUPS=y -CONFIG_CPUSETS=y -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_RT_GROUP_SCHED=y -CONFIG_BLK_CGROUP=y CONFIG_BLK_DEV_INITRD=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -# CONFIG_COMPAT_BRK is not set +CONFIG_PERF_EVENTS=y CONFIG_SLAB=y -CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_KPROBES=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y @@ -30,9 +19,7 @@ CONFIG_HIGH_RES_TIMERS=y CONFIG_PREEMPT=y CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTREMOVE=y -CONFIG_KSM=y CONFIG_BINFMT_MISC=m -CONFIG_CMM=m CONFIG_HZ_100=y CONFIG_KEXEC=y CONFIG_PM=y @@ -118,7 +105,6 @@ CONFIG_DEBUG_LIST=y CONFIG_DEBUG_NOTIFIERS=y # CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_KPROBES_SANITY_TEST=y -CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y CONFIG_CPU_NOTIFIER_ERROR_INJECT=m CONFIG_LATENCYTOP=y CONFIG_SYSCTL_SYSCALL_CHECK=y diff --git a/trunk/arch/s390/include/asm/compat.h b/trunk/arch/s390/include/asm/compat.h index da359ca6fe55..a875c2f542e1 100644 --- a/trunk/arch/s390/include/asm/compat.h +++ b/trunk/arch/s390/include/asm/compat.h @@ -169,7 +169,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) static inline int is_compat_task(void) { - return is_32bit_task(); + return test_thread_flag(TIF_31BIT); } #else diff --git a/trunk/arch/s390/include/asm/elf.h b/trunk/arch/s390/include/asm/elf.h index 10c029cfcc7d..354d42616c7e 100644 --- a/trunk/arch/s390/include/asm/elf.h +++ b/trunk/arch/s390/include/asm/elf.h @@ -161,9 +161,7 @@ extern unsigned int vdso_enabled; use of this is to invoke "./ld.so someprog" to test out a new version of the loader. We need to make sure that it is out of the way of the program that it will "exec", and that there is sufficient room for the brk. */ - -extern unsigned long randomize_et_dyn(unsigned long base); -#define ELF_ET_DYN_BASE (randomize_et_dyn(STACK_TOP / 3 * 2)) +#define ELF_ET_DYN_BASE (STACK_TOP / 3 * 2) /* This yields a mask that user programs can use to figure out what instruction set this CPU supports. */ @@ -208,8 +206,6 @@ do { \ current->mm->context.noexec == 0; \ }) -#define STACK_RND_MASK 0x7ffUL - #define ARCH_DLINFO \ do { \ if (vdso_enabled) \ @@ -222,7 +218,4 @@ struct linux_binprm; #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 int arch_setup_additional_pages(struct linux_binprm *, int); -extern unsigned long arch_randomize_brk(struct mm_struct *mm); -#define arch_randomize_brk arch_randomize_brk - #endif diff --git a/trunk/arch/s390/include/asm/system.h b/trunk/arch/s390/include/asm/system.h index 8f8d759f6a7b..6710b0eac165 100644 --- a/trunk/arch/s390/include/asm/system.h +++ b/trunk/arch/s390/include/asm/system.h @@ -449,7 +449,7 @@ extern void (*_machine_restart)(char *command); extern void (*_machine_halt)(void); extern void (*_machine_power_off)(void); -extern unsigned long arch_align_stack(unsigned long sp); +#define arch_align_stack(x) (x) static inline int tprot(unsigned long addr) { diff --git a/trunk/arch/s390/include/asm/thread_info.h b/trunk/arch/s390/include/asm/thread_info.h index ad1382f7932e..ebc77091466f 100644 --- a/trunk/arch/s390/include/asm/thread_info.h +++ b/trunk/arch/s390/include/asm/thread_info.h @@ -118,12 +118,6 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_SINGLE_STEP (1< #include #include -#include #include #include #include -#include #include #include #include @@ -334,39 +332,3 @@ unsigned long get_wchan(struct task_struct *p) } return 0; } - -unsigned long arch_align_stack(unsigned long sp) -{ - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) - sp -= get_random_int() & ~PAGE_MASK; - return sp & ~0xf; -} - -static inline unsigned long brk_rnd(void) -{ - /* 8MB for 32bit, 1GB for 64bit */ - if (is_32bit_task()) - return (get_random_int() & 0x7ffUL) << PAGE_SHIFT; - else - return (get_random_int() & 0x3ffffUL) << PAGE_SHIFT; -} - -unsigned long arch_randomize_brk(struct mm_struct *mm) -{ - unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd()); - - if (ret < mm->brk) - return mm->brk; - return ret; -} - -unsigned long randomize_et_dyn(unsigned long base) -{ - unsigned long ret = PAGE_ALIGN(base + brk_rnd()); - - if (!(current->flags & PF_RANDOMIZE)) - return base; - if (ret < base) - return base; - return ret; -} diff --git a/trunk/arch/s390/kernel/vdso.c b/trunk/arch/s390/kernel/vdso.c index f438d74dedbd..e3150dd2fe74 100644 --- a/trunk/arch/s390/kernel/vdso.c +++ b/trunk/arch/s390/kernel/vdso.c @@ -203,6 +203,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) if (!uses_interp) return 0; + vdso_base = mm->mmap_base; #ifdef CONFIG_64BIT vdso_pagelist = vdso64_pagelist; vdso_pages = vdso64_pages; @@ -232,7 +233,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) * fail and end up putting it elsewhere. */ down_write(&mm->mmap_sem); - vdso_base = get_unmapped_area(NULL, 0, vdso_pages << PAGE_SHIFT, 0, 0); + vdso_base = get_unmapped_area(NULL, vdso_base, + vdso_pages << PAGE_SHIFT, 0, 0); if (IS_ERR_VALUE(vdso_base)) { rc = vdso_base; goto out_up; diff --git a/trunk/arch/s390/mm/mmap.c b/trunk/arch/s390/mm/mmap.c index c9a9f7f18188..869efbaed3ea 100644 --- a/trunk/arch/s390/mm/mmap.c +++ b/trunk/arch/s390/mm/mmap.c @@ -27,44 +27,17 @@ #include #include #include -#include #include #include -static unsigned long stack_maxrandom_size(void) -{ - if (!(current->flags & PF_RANDOMIZE)) - return 0; - if (current->personality & ADDR_NO_RANDOMIZE) - return 0; - return STACK_RND_MASK << PAGE_SHIFT; -} - /* * Top of mmap area (just below the process stack). * - * Leave at least a ~32 MB hole. + * Leave an at least ~128 MB hole. */ -#define MIN_GAP (32*1024*1024) +#define MIN_GAP (128*1024*1024) #define MAX_GAP (STACK_TOP/6*5) -static inline int mmap_is_legacy(void) -{ - if (current->personality & ADDR_COMPAT_LAYOUT) - return 1; - if (rlimit(RLIMIT_STACK) == RLIM_INFINITY) - return 1; - return sysctl_legacy_va_layout; -} - -static unsigned long mmap_rnd(void) -{ - if (!(current->flags & PF_RANDOMIZE)) - return 0; - /* 8MB randomization for mmap_base */ - return (get_random_int() & 0x7ffUL) << PAGE_SHIFT; -} - static inline unsigned long mmap_base(void) { unsigned long gap = rlimit(RLIMIT_STACK); @@ -73,8 +46,22 @@ static inline unsigned long mmap_base(void) gap = MIN_GAP; else if (gap > MAX_GAP) gap = MAX_GAP; - gap &= PAGE_MASK; - return STACK_TOP - stack_maxrandom_size() - mmap_rnd() - gap; + + return STACK_TOP - (gap & PAGE_MASK); +} + +static inline int mmap_is_legacy(void) +{ +#ifdef CONFIG_64BIT + /* + * Force standard allocation for 64 bit programs. + */ + if (!is_compat_task()) + return 1; +#endif + return sysctl_legacy_va_layout || + (current->personality & ADDR_COMPAT_LAYOUT) || + rlimit(RLIMIT_STACK) == RLIM_INFINITY; } #ifndef CONFIG_64BIT diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index 47ae4a751a59..36ed2e2c896b 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -1934,19 +1934,13 @@ config PCI_MMCONFIG depends on X86_64 && PCI && ACPI config PCI_CNB20LE_QUIRK - bool "Read CNB20LE Host Bridge Windows" if EMBEDDED - default n - depends on PCI && EXPERIMENTAL + 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. - There's no public spec for this chipset, and this functionality - is known to be incomplete. - - You should say N unless you know you need this. - config DMAR bool "Support for DMA Remapping Devices (EXPERIMENTAL)" depends on PCI_MSI && ACPI && EXPERIMENTAL @@ -2074,7 +2068,7 @@ config OLPC config OLPC_XO1 tristate "OLPC XO-1 support" - depends on OLPC && MFD_CS5535 + depends on OLPC && PCI ---help--- Add support for non-essential features of the OLPC XO-1 laptop. diff --git a/trunk/arch/x86/pci/broadcom_bus.c b/trunk/arch/x86/pci/broadcom_bus.c index ab8269b0da29..0846a5bbbfbd 100644 --- a/trunk/arch/x86/pci/broadcom_bus.c +++ b/trunk/arch/x86/pci/broadcom_bus.c @@ -9,7 +9,6 @@ * option) any later version. */ -#include #include #include #include @@ -26,14 +25,12 @@ static void __devinit cnb20le_res(struct pci_dev *dev) u8 fbus, lbus; int i; -#ifdef CONFIG_ACPI /* - * We should get host bridge information from ACPI unless the BIOS - * doesn't support it. + * 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. */ - if (acpi_os_get_root_pointer()) - return; -#endif info = &pci_root_info[pci_root_num]; pci_root_num++; diff --git a/trunk/arch/x86/pci/common.c b/trunk/arch/x86/pci/common.c index 5fe75026ecc2..f7c8a399978c 100644 --- a/trunk/arch/x86/pci/common.c +++ b/trunk/arch/x86/pci/common.c @@ -22,7 +22,6 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | unsigned int pci_early_dump_regs; static int pci_bf_sort; -static int smbios_type_b1_flag; int pci_routeirq; int noioapicquirk; #ifdef CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS @@ -186,39 +185,6 @@ static int __devinit set_bf_sort(const struct dmi_system_id *d) return 0; } -static void __devinit read_dmi_type_b1(const struct dmi_header *dm, - void *private_data) -{ - u8 *d = (u8 *)dm + 4; - - if (dm->type != 0xB1) - return; - switch (((*(u32 *)d) >> 9) & 0x03) { - case 0x00: - printk(KERN_INFO "dmi type 0xB1 record - unknown flag\n"); - break; - case 0x01: /* set pci=bfsort */ - smbios_type_b1_flag = 1; - break; - case 0x02: /* do not set pci=bfsort */ - smbios_type_b1_flag = 2; - break; - default: - break; - } -} - -static int __devinit find_sort_method(const struct dmi_system_id *d) -{ - dmi_walk(read_dmi_type_b1, NULL); - - if (smbios_type_b1_flag == 1) { - set_bf_sort(d); - return 0; - } - return -1; -} - /* * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus) */ @@ -246,13 +212,6 @@ static const struct dmi_system_id __devinitconst pciprobe_dmi_table[] = { }, }, #endif /* __i386__ */ - { - .callback = find_sort_method, - .ident = "Dell System", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - }, - }, { .callback = set_bf_sort, .ident = "Dell PowerEdge 1950", diff --git a/trunk/arch/x86/pci/irq.c b/trunk/arch/x86/pci/irq.c index 87e6c8323117..9f9bfb705cf9 100644 --- a/trunk/arch/x86/pci/irq.c +++ b/trunk/arch/x86/pci/irq.c @@ -589,8 +589,7 @@ 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_PATSBURG_LPC_0: - case PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1: + case PCI_DEVICE_ID_INTEL_PATSBURG_LPC: r->name = "PIIX/ICH"; r->get = pirq_piix_get; r->set = pirq_piix_set; diff --git a/trunk/arch/x86/platform/olpc/olpc-xo1.c b/trunk/arch/x86/platform/olpc/olpc-xo1.c index 127775696d6c..f5442c03abc3 100644 --- a/trunk/arch/x86/platform/olpc/olpc-xo1.c +++ b/trunk/arch/x86/platform/olpc/olpc-xo1.c @@ -1,7 +1,6 @@ /* * Support for features of the OLPC XO-1 laptop * - * Copyright (C) 2010 Andres Salomon * Copyright (C) 2010 One Laptop per Child * Copyright (C) 2006 Red Hat, Inc. * Copyright (C) 2006 Advanced Micro Devices, Inc. @@ -13,6 +12,8 @@ */ #include +#include +#include #include #include @@ -21,6 +22,9 @@ #define DRV_NAME "olpc-xo1" +#define PMS_BAR 4 +#define ACPI_BAR 5 + /* PMC registers (PMS block) */ #define PM_SCLK 0x10 #define PM_IN_SLPCTL 0x20 @@ -53,67 +57,65 @@ static void xo1_power_off(void) outl(0x00002000, acpi_base + PM1_CNT); } -static int __devinit olpc_xo1_probe(struct platform_device *pdev) +/* Read the base addresses from the PCI BAR info */ +static int __devinit setup_bases(struct pci_dev *pdev) { - struct resource *res; - - /* don't run on non-XOs */ - if (!machine_is_olpc()) - return -ENODEV; + int r; - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!res) { - dev_err(&pdev->dev, "can't fetch device resource info\n"); - return -EIO; + r = pci_enable_device_io(pdev); + if (r) { + dev_err(&pdev->dev, "can't enable device IO\n"); + return r; } - if (!request_region(res->start, resource_size(res), DRV_NAME)) { - dev_err(&pdev->dev, "can't request region\n"); - return -EIO; + r = pci_request_region(pdev, ACPI_BAR, DRV_NAME); + if (r) { + dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", ACPI_BAR); + return r; } - if (strcmp(pdev->name, "cs5535-pms") == 0) - pms_base = res->start; - else if (strcmp(pdev->name, "cs5535-acpi") == 0) - acpi_base = res->start; - - /* If we have both addresses, we can override the poweroff hook */ - if (pms_base && acpi_base) { - pm_power_off = xo1_power_off; - printk(KERN_INFO "OLPC XO-1 support registered\n"); + r = pci_request_region(pdev, PMS_BAR, DRV_NAME); + if (r) { + dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", PMS_BAR); + pci_release_region(pdev, ACPI_BAR); + return r; } + acpi_base = pci_resource_start(pdev, ACPI_BAR); + pms_base = pci_resource_start(pdev, PMS_BAR); + return 0; } -static int __devexit olpc_xo1_remove(struct platform_device *pdev) +static int __devinit olpc_xo1_probe(struct platform_device *pdev) { - struct resource *r; + struct pci_dev *pcidev; + int r; - r = platform_get_resource(pdev, IORESOURCE_IO, 0); - release_region(r->start, resource_size(r)); + pcidev = pci_get_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, + NULL); + if (!pdev) + return -ENODEV; - if (strcmp(pdev->name, "cs5535-pms") == 0) - pms_base = 0; - else if (strcmp(pdev->name, "cs5535-acpi") == 0) - acpi_base = 0; + r = setup_bases(pcidev); + if (r) + return r; - pm_power_off = NULL; + pm_power_off = xo1_power_off; + + printk(KERN_INFO "OLPC XO-1 support registered\n"); return 0; } -static struct platform_driver cs5535_pms_drv = { - .driver = { - .name = "cs5535-pms", - .owner = THIS_MODULE, - }, - .probe = olpc_xo1_probe, - .remove = __devexit_p(olpc_xo1_remove), -}; +static int __devexit olpc_xo1_remove(struct platform_device *pdev) +{ + pm_power_off = NULL; + return 0; +} -static struct platform_driver cs5535_acpi_drv = { +static struct platform_driver olpc_xo1_driver = { .driver = { - .name = "cs5535-acpi", + .name = DRV_NAME, .owner = THIS_MODULE, }, .probe = olpc_xo1_probe, @@ -122,23 +124,12 @@ static struct platform_driver cs5535_acpi_drv = { static int __init olpc_xo1_init(void) { - int r; - - r = platform_driver_register(&cs5535_pms_drv); - if (r) - return r; - - r = platform_driver_register(&cs5535_acpi_drv); - if (r) - platform_driver_unregister(&cs5535_pms_drv); - - return r; + return platform_driver_register(&olpc_xo1_driver); } static void __exit olpc_xo1_exit(void) { - platform_driver_unregister(&cs5535_acpi_drv); - platform_driver_unregister(&cs5535_pms_drv); + platform_driver_unregister(&olpc_xo1_driver); } MODULE_AUTHOR("Daniel Drake "); diff --git a/trunk/drivers/acpi/apei/hest.c b/trunk/drivers/acpi/apei/hest.c index 4ee58e72b730..daa7bc63f1d4 100644 --- a/trunk/drivers/acpi/apei/hest.c +++ b/trunk/drivers/acpi/apei/hest.c @@ -195,24 +195,24 @@ static int __init setup_hest_disable(char *str) __setup("hest_disable", setup_hest_disable); -void __init acpi_hest_init(void) +static int __init hest_init(void) { acpi_status status; int rc = -ENODEV; unsigned int ghes_count = 0; if (acpi_disabled) - return; + goto err; if (hest_disable) { - pr_info(HEST_PFX "Table parsing disabled.\n"); - return; + pr_info(HEST_PFX "HEST tabling parsing is disabled.\n"); + goto err; } status = acpi_get_table(ACPI_SIG_HEST, 0, (struct acpi_table_header **)&hest_tab); if (status == AE_NOT_FOUND) { - pr_info(HEST_PFX "Table not found.\n"); + pr_info(HEST_PFX "Table is not found!\n"); goto err; } else if (ACPI_FAILURE(status)) { const char *msg = acpi_format_exception(status); @@ -226,11 +226,15 @@ void __init acpi_hest_init(void) goto err; rc = hest_ghes_dev_register(ghes_count); - if (!rc) { - pr_info(HEST_PFX "Table parsing has been initialized.\n"); - return; - } + if (rc) + goto err; + pr_info(HEST_PFX "HEST table parsing is initialized.\n"); + + return 0; err: hest_disable = 1; + return rc; } + +subsys_initcall(hest_init); diff --git a/trunk/drivers/acpi/pci_root.c b/trunk/drivers/acpi/pci_root.c index d9766797cd98..96668ad09622 100644 --- a/trunk/drivers/acpi/pci_root.c +++ b/trunk/drivers/acpi/pci_root.c @@ -36,7 +36,6 @@ #include #include #include -#include #define PREFIX "ACPI: " @@ -48,11 +47,6 @@ static int acpi_pci_root_add(struct acpi_device *device); static int acpi_pci_root_remove(struct acpi_device *device, int type); static int acpi_pci_root_start(struct acpi_device *device); -#define ACPI_PCIE_REQ_SUPPORT (OSC_EXT_PCI_CONFIG_SUPPORT \ - | OSC_ACTIVE_STATE_PWR_SUPPORT \ - | OSC_CLOCK_PWR_CAPABILITY_SUPPORT \ - | OSC_MSI_SUPPORT) - static const struct acpi_device_id root_device_ids[] = { {"PNP0A03", 0}, {"", 0}, @@ -572,33 +566,6 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) if (flags != base_flags) acpi_pci_osc_support(root, flags); - if (!pcie_ports_disabled - && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { - flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL - | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL - | OSC_PCI_EXPRESS_PME_CONTROL; - - if (pci_aer_available()) { - if (aer_acpi_firmware_first()) - dev_dbg(root->bus->bridge, - "PCIe errors handled by BIOS.\n"); - else - flags |= OSC_PCI_EXPRESS_AER_CONTROL; - } - - dev_info(root->bus->bridge, - "Requesting ACPI _OSC control (0x%02x)\n", flags); - - status = acpi_pci_osc_control_set(device->handle, &flags, - OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); - if (ACPI_SUCCESS(status)) - dev_info(root->bus->bridge, - "ACPI _OSC control (0x%02x) granted\n", flags); - else - dev_dbg(root->bus->bridge, - "ACPI _OSC request failed (code %d)\n", status); - } - pci_acpi_add_bus_pm_notifier(device, root->bus); if (device->wakeup.flags.run_wake) device_set_run_wake(root->bus->bridge, true); @@ -636,8 +603,6 @@ static int __init acpi_pci_root_init(void) if (acpi_pci_disabled) return 0; - acpi_hest_init(); - pci_acpi_crs_quirks(); if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0) return -ENODEV; diff --git a/trunk/drivers/char/agp/intel-agp.c b/trunk/drivers/char/agp/intel-agp.c index 857df10c0428..07e9796fead7 100644 --- a/trunk/drivers/char/agp/intel-agp.c +++ b/trunk/drivers/char/agp/intel-agp.c @@ -717,8 +717,8 @@ static const struct intel_agp_driver_description { { PCI_DEVICE_ID_INTEL_82820_UP_HB, "i820", &intel_820_driver }, { PCI_DEVICE_ID_INTEL_82830_HB, "830M", &intel_830mp_driver }, { PCI_DEVICE_ID_INTEL_82840_HB, "i840", &intel_840_driver }, - { PCI_DEVICE_ID_INTEL_82845_HB, "i845", &intel_845_driver }, - { PCI_DEVICE_ID_INTEL_82845G_HB, "845G", &intel_845_driver }, + { PCI_DEVICE_ID_INTEL_82845_HB, "845G", &intel_845_driver }, + { PCI_DEVICE_ID_INTEL_82845G_HB, "830M", &intel_845_driver }, { PCI_DEVICE_ID_INTEL_82850_HB, "i850", &intel_850_driver }, { PCI_DEVICE_ID_INTEL_82854_HB, "854", &intel_845_driver }, { PCI_DEVICE_ID_INTEL_82855PM_HB, "855PM", &intel_845_driver }, diff --git a/trunk/drivers/char/agp/intel-gtt.c b/trunk/drivers/char/agp/intel-gtt.c index 826ab0939a12..e921b693412b 100644 --- a/trunk/drivers/char/agp/intel-gtt.c +++ b/trunk/drivers/char/agp/intel-gtt.c @@ -1361,7 +1361,7 @@ static const struct intel_gtt_driver_description { &i81x_gtt_driver}, { PCI_DEVICE_ID_INTEL_82830_CGC, "830M", &i8xx_gtt_driver}, - { PCI_DEVICE_ID_INTEL_82845G_IG, "845G", + { PCI_DEVICE_ID_INTEL_82845G_IG, "830M", &i8xx_gtt_driver}, { PCI_DEVICE_ID_INTEL_82854_IG, "854", &i8xx_gtt_driver}, diff --git a/trunk/drivers/gpio/cs5535-gpio.c b/trunk/drivers/gpio/cs5535-gpio.c index 0d05ea7d499b..815d98b2c1ba 100644 --- a/trunk/drivers/gpio/cs5535-gpio.c +++ b/trunk/drivers/gpio/cs5535-gpio.c @@ -11,13 +11,14 @@ #include #include #include -#include +#include #include #include #include #include #define DRV_NAME "cs5535-gpio" +#define GPIO_BAR 1 /* * Some GPIO pins @@ -46,7 +47,7 @@ static struct cs5535_gpio_chip { struct gpio_chip chip; resource_size_t base; - struct platform_device *pdev; + struct pci_dev *pdev; spinlock_t lock; } cs5535_gpio_chip; @@ -300,10 +301,10 @@ static struct cs5535_gpio_chip cs5535_gpio_chip = { }, }; -static int __devinit cs5535_gpio_probe(struct platform_device *pdev) +static int __init cs5535_gpio_probe(struct pci_dev *pdev, + const struct pci_device_id *pci_id) { - struct resource *res; - int err = -EIO; + int err; ulong mask_orig = mask; /* There are two ways to get the GPIO base address; one is by @@ -313,23 +314,25 @@ static int __devinit cs5535_gpio_probe(struct platform_device *pdev) * it turns out to be unreliable in the face of crappy BIOSes, we * can always go back to using MSRs.. */ - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!res) { - dev_err(&pdev->dev, "can't fetch device resource info\n"); + err = pci_enable_device_io(pdev); + if (err) { + dev_err(&pdev->dev, "can't enable device IO\n"); goto done; } - if (!request_region(res->start, resource_size(res), pdev->name)) { - dev_err(&pdev->dev, "can't request region\n"); + err = pci_request_region(pdev, GPIO_BAR, DRV_NAME); + if (err) { + dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", GPIO_BAR); goto done; } /* set up the driver-specific struct */ - cs5535_gpio_chip.base = res->start; + cs5535_gpio_chip.base = pci_resource_start(pdev, GPIO_BAR); cs5535_gpio_chip.pdev = pdev; spin_lock_init(&cs5535_gpio_chip.lock); - dev_info(&pdev->dev, "reserved resource region %pR\n", res); + dev_info(&pdev->dev, "allocated PCI BAR #%d: base 0x%llx\n", GPIO_BAR, + (unsigned long long) cs5535_gpio_chip.base); /* mask out reserved pins */ mask &= 0x1F7FFFFF; @@ -347,49 +350,78 @@ static int __devinit cs5535_gpio_probe(struct platform_device *pdev) if (err) goto release_region; - dev_info(&pdev->dev, "GPIO support successfully loaded.\n"); + dev_info(&pdev->dev, DRV_NAME ": GPIO support successfully loaded.\n"); return 0; release_region: - release_region(res->start, resource_size(res)); + pci_release_region(pdev, GPIO_BAR); done: return err; } -static int __devexit cs5535_gpio_remove(struct platform_device *pdev) +static void __exit cs5535_gpio_remove(struct pci_dev *pdev) { - struct resource *r; int err; err = gpiochip_remove(&cs5535_gpio_chip.chip); if (err) { /* uhh? */ dev_err(&pdev->dev, "unable to remove gpio_chip?\n"); - return err; } - - r = platform_get_resource(pdev, IORESOURCE_IO, 0); - release_region(r->start, resource_size(r)); - return 0; + pci_release_region(pdev, GPIO_BAR); } -static struct platform_driver cs5535_gpio_drv = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, - .probe = cs5535_gpio_probe, - .remove = __devexit_p(cs5535_gpio_remove), +static struct pci_device_id cs5535_gpio_pci_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, + { 0, }, }; +MODULE_DEVICE_TABLE(pci, cs5535_gpio_pci_tbl); + +/* + * We can't use the standard PCI driver registration stuff here, since + * that allows only one driver to bind to each PCI device (and we want + * multiple drivers to be able to bind to the device). Instead, manually + * scan for the PCI device, request a single region, and keep track of the + * devices that we're using. + */ + +static int __init cs5535_gpio_scan_pci(void) +{ + struct pci_dev *pdev; + int err = -ENODEV; + int i; + + for (i = 0; i < ARRAY_SIZE(cs5535_gpio_pci_tbl); i++) { + pdev = pci_get_device(cs5535_gpio_pci_tbl[i].vendor, + cs5535_gpio_pci_tbl[i].device, NULL); + if (pdev) { + err = cs5535_gpio_probe(pdev, &cs5535_gpio_pci_tbl[i]); + if (err) + pci_dev_put(pdev); + + /* we only support a single CS5535/6 southbridge */ + break; + } + } + + return err; +} + +static void __exit cs5535_gpio_free_pci(void) +{ + cs5535_gpio_remove(cs5535_gpio_chip.pdev); + pci_dev_put(cs5535_gpio_chip.pdev); +} static int __init cs5535_gpio_init(void) { - return platform_driver_register(&cs5535_gpio_drv); + return cs5535_gpio_scan_pci(); } static void __exit cs5535_gpio_exit(void) { - platform_driver_unregister(&cs5535_gpio_drv); + cs5535_gpio_free_pci(); } module_init(cs5535_gpio_init); @@ -398,4 +430,3 @@ module_exit(cs5535_gpio_exit); MODULE_AUTHOR("Andres Salomon "); MODULE_DESCRIPTION("AMD CS5535/CS5536 GPIO driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:" DRV_NAME); diff --git a/trunk/drivers/gpio/timbgpio.c b/trunk/drivers/gpio/timbgpio.c index 58c8f30352dd..349131eb1ce0 100644 --- a/trunk/drivers/gpio/timbgpio.c +++ b/trunk/drivers/gpio/timbgpio.c @@ -193,13 +193,13 @@ static int timbgpio_irq_type(struct irq_data *d, unsigned trigger) return ret; } -static void timbgpio_irq(unsigned int irq, struct irq_desc *desc) +static void timbgpio_irq(struct irq_data *d, struct irq_desc *desc) { - struct timbgpio *tgpio = get_irq_data(irq); + struct timbgpio *tgpio = irq_data_get_irq_data(d); unsigned long ipr; int offset; - desc->irq_data.chip->irq_ack(irq_get_irq_data(irq)); + desc->irq_data.chip->ack(irq_get_irq_data(d)); ipr = ioread32(tgpio->membase + TGPIO_IPR); iowrite32(ipr, tgpio->membase + TGPIO_ICR); diff --git a/trunk/drivers/gpu/drm/i915/i915_debugfs.c b/trunk/drivers/gpu/drm/i915/i915_debugfs.c index 3601466c5502..19a3d58044dd 100644 --- a/trunk/drivers/gpu/drm/i915/i915_debugfs.c +++ b/trunk/drivers/gpu/drm/i915/i915_debugfs.c @@ -703,7 +703,7 @@ static void print_error_buffers(struct seq_file *m, seq_printf(m, "%s [%d]:\n", name, count); while (count--) { - seq_printf(m, " %08x %8u %04x %04x %08x%s%s%s%s%s%s", + seq_printf(m, " %08x %8zd %04x %04x %08x%s%s%s%s%s%s", err->gtt_offset, err->size, err->read_domains, diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index 72fea2bcfc4f..0de75a23f8e7 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -49,9 +49,6 @@ module_param_named(powersave, i915_powersave, int, 0600); unsigned int i915_lvds_downclock = 0; module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400); -unsigned int i915_panel_use_ssc = 1; -module_param_named(lvds_use_ssc, i915_panel_use_ssc, int, 0600); - bool i915_try_reset = true; module_param_named(reset, i915_try_reset, bool, 0600); diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index 5969f46ac2d6..385fc7ec39d3 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -954,7 +954,6 @@ extern int i915_max_ioctl; extern unsigned int i915_fbpercrtc; extern unsigned int i915_powersave; extern unsigned int i915_lvds_downclock; -extern unsigned int i915_panel_use_ssc; extern int i915_suspend(struct drm_device *dev, pm_message_t state); extern int i915_resume(struct drm_device *dev); diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c index dcfdf4151b6d..e69834341ef0 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -464,6 +464,8 @@ i915_gem_execbuffer_relocate(struct drm_device *dev, int ret; list_for_each_entry(obj, objects, exec_list) { + obj->base.pending_read_domains = 0; + obj->base.pending_write_domain = 0; ret = i915_gem_execbuffer_relocate_object(obj, eb); if (ret) return ret; @@ -503,9 +505,6 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, list_move(&obj->exec_list, &ordered_objects); else list_move_tail(&obj->exec_list, &ordered_objects); - - obj->base.pending_read_domains = 0; - obj->base.pending_write_domain = 0; } list_splice(&ordered_objects, objects); @@ -637,7 +636,6 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, { struct drm_i915_gem_relocation_entry *reloc; struct drm_i915_gem_object *obj; - int *reloc_offset; int i, total, ret; /* We may process another execbuffer during the unlock... */ @@ -655,11 +653,8 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, for (i = 0; i < count; i++) total += exec[i].relocation_count; - reloc_offset = drm_malloc_ab(count, sizeof(*reloc_offset)); reloc = drm_malloc_ab(total, sizeof(*reloc)); - if (reloc == NULL || reloc_offset == NULL) { - drm_free_large(reloc); - drm_free_large(reloc_offset); + if (reloc == NULL) { mutex_lock(&dev->struct_mutex); return -ENOMEM; } @@ -677,7 +672,6 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, goto err; } - reloc_offset[i] = total; total += exec[i].relocation_count; } @@ -711,12 +705,17 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, if (ret) goto err; + total = 0; list_for_each_entry(obj, objects, exec_list) { - int offset = obj->exec_entry - exec; + obj->base.pending_read_domains = 0; + obj->base.pending_write_domain = 0; ret = i915_gem_execbuffer_relocate_object_slow(obj, eb, - reloc + reloc_offset[offset]); + reloc + total); if (ret) goto err; + + total += exec->relocation_count; + exec++; } /* Leave the user relocations as are, this is the painfully slow path, @@ -727,7 +726,6 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, err: drm_free_large(reloc); - drm_free_large(reloc_offset); return ret; } @@ -772,8 +770,7 @@ i915_gem_execbuffer_sync_rings(struct drm_i915_gem_object *obj, if (from == NULL || to == from) return 0; - /* XXX gpu semaphores are currently causing hard hangs on SNB mobile */ - if (INTEL_INFO(obj->base.dev)->gen < 6 || IS_MOBILE(obj->base.dev)) + if (INTEL_INFO(obj->base.dev)->gen < 6) return i915_gem_object_wait_rendering(obj, true); idx = intel_ring_sync_index(from, to); diff --git a/trunk/drivers/gpu/drm/i915/i915_irq.c b/trunk/drivers/gpu/drm/i915/i915_irq.c index b8e509ae065e..e418e8bb61e6 100644 --- a/trunk/drivers/gpu/drm/i915/i915_irq.c +++ b/trunk/drivers/gpu/drm/i915/i915_irq.c @@ -720,7 +720,7 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, if (obj->ring != ring) continue; - if (i915_seqno_passed(seqno, obj->last_rendering_seqno)) + if (!i915_seqno_passed(obj->last_rendering_seqno, seqno)) continue; if ((obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) == 0) diff --git a/trunk/drivers/gpu/drm/i915/intel_bios.c b/trunk/drivers/gpu/drm/i915/intel_bios.c index 0b44956c336b..b0b1200ed650 100644 --- a/trunk/drivers/gpu/drm/i915/intel_bios.c +++ b/trunk/drivers/gpu/drm/i915/intel_bios.c @@ -264,12 +264,17 @@ parse_general_features(struct drm_i915_private *dev_priv, dev_priv->int_crt_support = general->int_crt_support; dev_priv->lvds_use_ssc = general->enable_ssc; - if (IS_I85X(dev)) - dev_priv->lvds_ssc_freq = general->ssc_freq ? 66 : 48; - else if (IS_GEN5(dev) || IS_GEN6(dev)) - dev_priv->lvds_ssc_freq = general->ssc_freq ? 100 : 120; - else - dev_priv->lvds_ssc_freq = general->ssc_freq ? 100 : 96; + if (dev_priv->lvds_use_ssc) { + if (IS_I85X(dev)) + dev_priv->lvds_ssc_freq = + general->ssc_freq ? 66 : 48; + else if (IS_GEN5(dev) || IS_GEN6(dev)) + dev_priv->lvds_ssc_freq = + general->ssc_freq ? 100 : 120; + else + dev_priv->lvds_ssc_freq = + general->ssc_freq ? 100 : 96; + } } } diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index 98967f3b7724..25d96889d7d2 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -3822,11 +3822,6 @@ static void intel_update_watermarks(struct drm_device *dev) sr_hdisplay, sr_htotal, pixel_size); } -static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) -{ - return dev_priv->lvds_use_ssc && i915_panel_use_ssc; -} - static int intel_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode, @@ -3889,7 +3884,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, num_connectors++; } - if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) { + if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2) { refclk = dev_priv->lvds_ssc_freq * 1000; DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", refclk / 1000); @@ -4064,7 +4059,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, udelay(200); if (has_edp_encoder) { - if (intel_panel_use_ssc(dev_priv)) { + if (dev_priv->lvds_use_ssc) { temp |= DREF_SSC1_ENABLE; I915_WRITE(PCH_DREF_CONTROL, temp); @@ -4075,13 +4070,13 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, /* Enable CPU source on CPU attached eDP */ if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) { - if (intel_panel_use_ssc(dev_priv)) + if (dev_priv->lvds_use_ssc) temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; else temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; } else { /* Enable SSC on PCH eDP if needed */ - if (intel_panel_use_ssc(dev_priv)) { + if (dev_priv->lvds_use_ssc) { DRM_ERROR("enabling SSC on PCH\n"); temp |= DREF_SUPERSPREAD_SOURCE_ENABLE; } @@ -4109,7 +4104,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, int factor = 21; if (is_lvds) { - if ((intel_panel_use_ssc(dev_priv) && + if ((dev_priv->lvds_use_ssc && dev_priv->lvds_ssc_freq == 100) || (I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) factor = 25; @@ -4188,7 +4183,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, /* XXX: just matching BIOS for now */ /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ dpll |= 3; - else if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) + else if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2) dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; else dpll |= PLL_REF_INPUT_DREFCLK; diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c index ace8d5d30dd2..8f4f6bd33ee9 100644 --- a/trunk/drivers/gpu/drm/i915/intel_lvds.c +++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c @@ -702,14 +702,6 @@ static const struct dmi_system_id intel_no_lvds[] = { DMI_MATCH(DMI_BOARD_NAME, "i915GMx-F"), }, }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "AOpen i915GMm-HFS", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), - DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), - }, - }, { .callback = intel_no_lvds_dmi_callback, .ident = "Aopen i945GTt-VFA", diff --git a/trunk/drivers/gpu/drm/i915/intel_panel.c b/trunk/drivers/gpu/drm/i915/intel_panel.c index c65992df458d..e00d200df3db 100644 --- a/trunk/drivers/gpu/drm/i915/intel_panel.c +++ b/trunk/drivers/gpu/drm/i915/intel_panel.c @@ -278,6 +278,6 @@ void intel_panel_setup_backlight(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - dev_priv->backlight_level = intel_panel_get_backlight(dev); + dev_priv->backlight_level = intel_panel_get_max_backlight(dev); dev_priv->backlight_enabled = dev_priv->backlight_level != 0; } diff --git a/trunk/drivers/i2c/busses/scx200_acb.c b/trunk/drivers/i2c/busses/scx200_acb.c index 986e5f62debe..53fab518b3da 100644 --- a/trunk/drivers/i2c/busses/scx200_acb.c +++ b/trunk/drivers/i2c/busses/scx200_acb.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -41,7 +40,6 @@ MODULE_AUTHOR("Christer Weinigel "); MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver"); -MODULE_ALIAS("platform:cs5535-smb"); MODULE_LICENSE("GPL"); #define MAX_DEVICES 4 @@ -86,6 +84,10 @@ struct scx200_acb_iface { u8 *ptr; char needs_reset; unsigned len; + + /* PCI device info */ + struct pci_dev *pdev; + int bar; }; /* Register Definitions */ @@ -389,7 +391,7 @@ static const struct i2c_algorithm scx200_acb_algorithm = { static struct scx200_acb_iface *scx200_acb_list; static DEFINE_MUTEX(scx200_acb_list_mutex); -static __devinit int scx200_acb_probe(struct scx200_acb_iface *iface) +static __init int scx200_acb_probe(struct scx200_acb_iface *iface) { u8 val; @@ -425,7 +427,7 @@ static __devinit int scx200_acb_probe(struct scx200_acb_iface *iface) return 0; } -static __devinit struct scx200_acb_iface *scx200_create_iface(const char *text, +static __init struct scx200_acb_iface *scx200_create_iface(const char *text, struct device *dev, int index) { struct scx200_acb_iface *iface; @@ -450,7 +452,7 @@ static __devinit struct scx200_acb_iface *scx200_create_iface(const char *text, return iface; } -static int __devinit scx200_acb_create(struct scx200_acb_iface *iface) +static int __init scx200_acb_create(struct scx200_acb_iface *iface) { struct i2c_adapter *adapter; int rc; @@ -470,145 +472,183 @@ static int __devinit scx200_acb_create(struct scx200_acb_iface *iface) return -ENODEV; } - if (!adapter->dev.parent) { - /* If there's no dev, we're tracking (ISA) ifaces manually */ - mutex_lock(&scx200_acb_list_mutex); - iface->next = scx200_acb_list; - scx200_acb_list = iface; - mutex_unlock(&scx200_acb_list_mutex); - } + mutex_lock(&scx200_acb_list_mutex); + iface->next = scx200_acb_list; + scx200_acb_list = iface; + mutex_unlock(&scx200_acb_list_mutex); return 0; } -static struct scx200_acb_iface * __devinit scx200_create_dev(const char *text, - unsigned long base, int index, struct device *dev) +static __init int scx200_create_pci(const char *text, struct pci_dev *pdev, + int bar) { struct scx200_acb_iface *iface; int rc; - iface = scx200_create_iface(text, dev, index); + iface = scx200_create_iface(text, &pdev->dev, 0); if (iface == NULL) - return NULL; + return -ENOMEM; - if (!request_region(base, 8, iface->adapter.name)) { - printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n", - base, base + 8 - 1); + iface->pdev = pdev; + iface->bar = bar; + + rc = pci_enable_device_io(iface->pdev); + if (rc) + goto errout_free; + + rc = pci_request_region(iface->pdev, iface->bar, iface->adapter.name); + if (rc) { + printk(KERN_ERR NAME ": can't allocate PCI BAR %d\n", + iface->bar); goto errout_free; } - iface->base = base; + iface->base = pci_resource_start(iface->pdev, iface->bar); rc = scx200_acb_create(iface); if (rc == 0) - return iface; + return 0; - release_region(base, 8); + pci_release_region(iface->pdev, iface->bar); + pci_dev_put(iface->pdev); errout_free: kfree(iface); - return NULL; + return rc; } -static int __devinit scx200_probe(struct platform_device *pdev) +static int __init scx200_create_isa(const char *text, unsigned long base, + int index) { struct scx200_acb_iface *iface; - struct resource *res; - - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!res) { - dev_err(&pdev->dev, "can't fetch device resource info\n"); - return -ENODEV; - } - - iface = scx200_create_dev("CS5535", res->start, 0, &pdev->dev); - if (!iface) - return -EIO; + int rc; - dev_info(&pdev->dev, "SCx200 device '%s' registered\n", - iface->adapter.name); - platform_set_drvdata(pdev, iface); + iface = scx200_create_iface(text, NULL, index); - return 0; -} + if (iface == NULL) + return -ENOMEM; -static void __devexit scx200_cleanup_iface(struct scx200_acb_iface *iface) -{ - i2c_del_adapter(&iface->adapter); - release_region(iface->base, 8); - kfree(iface); -} + if (!request_region(base, 8, iface->adapter.name)) { + printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n", + base, base + 8 - 1); + rc = -EBUSY; + goto errout_free; + } -static int __devexit scx200_remove(struct platform_device *pdev) -{ - struct scx200_acb_iface *iface; + iface->base = base; + rc = scx200_acb_create(iface); - iface = platform_get_drvdata(pdev); - platform_set_drvdata(pdev, NULL); - scx200_cleanup_iface(iface); + if (rc == 0) + return 0; - return 0; + release_region(base, 8); + errout_free: + kfree(iface); + return rc; } -static struct platform_driver scx200_pci_drv = { - .driver = { - .name = "cs5535-smb", - .owner = THIS_MODULE, - }, - .probe = scx200_probe, - .remove = __devexit_p(scx200_remove), +/* Driver data is an index into the scx200_data array that indicates + * the name and the BAR where the I/O address resource is located. ISA + * devices are flagged with a bar value of -1 */ + +static const struct pci_device_id scx200_pci[] __initconst = { + { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE), + .driver_data = 0 }, + { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE), + .driver_data = 0 }, + { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA), + .driver_data = 1 }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA), + .driver_data = 2 }, + { 0, } }; -static const struct pci_device_id scx200_isa[] __initconst = { - { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) }, - { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) }, - { 0, } +static struct { + const char *name; + int bar; +} scx200_data[] = { + { "SCx200", -1 }, + { "CS5535", 0 }, + { "CS5536", 0 } }; -static __init void scx200_scan_isa(void) +static __init int scx200_scan_pci(void) { - int i; + int data, dev; + int rc = -ENODEV; + struct pci_dev *pdev; - if (!pci_dev_present(scx200_isa)) - return; + for(dev = 0; dev < ARRAY_SIZE(scx200_pci); dev++) { + pdev = pci_get_device(scx200_pci[dev].vendor, + scx200_pci[dev].device, NULL); - for (i = 0; i < MAX_DEVICES; ++i) { - if (base[i] == 0) + if (pdev == NULL) continue; - /* XXX: should we care about failures? */ - scx200_create_dev("SCx200", base[i], i, NULL); + data = scx200_pci[dev].driver_data; + + /* if .bar is greater or equal to zero, this is a + * PCI device - otherwise, we assume + that the ports are ISA based + */ + + if (scx200_data[data].bar >= 0) + rc = scx200_create_pci(scx200_data[data].name, pdev, + scx200_data[data].bar); + else { + int i; + + pci_dev_put(pdev); + for (i = 0; i < MAX_DEVICES; ++i) { + if (base[i] == 0) + continue; + + rc = scx200_create_isa(scx200_data[data].name, + base[i], + i); + } + } + + break; } + + return rc; } static int __init scx200_acb_init(void) { + int rc; + pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n"); - /* First scan for ISA-based devices */ - scx200_scan_isa(); /* XXX: should we care about errors? */ + rc = scx200_scan_pci(); /* If at least one bus was created, init must succeed */ if (scx200_acb_list) return 0; - - /* No ISA devices; register the platform driver for PCI-based devices */ - return platform_driver_register(&scx200_pci_drv); + return rc; } static void __exit scx200_acb_cleanup(void) { struct scx200_acb_iface *iface; - platform_driver_unregister(&scx200_pci_drv); - mutex_lock(&scx200_acb_list_mutex); while ((iface = scx200_acb_list) != NULL) { scx200_acb_list = iface->next; mutex_unlock(&scx200_acb_list_mutex); - scx200_cleanup_iface(iface); + i2c_del_adapter(&iface->adapter); + + if (iface->pdev) { + pci_release_region(iface->pdev, iface->bar); + pci_dev_put(iface->pdev); + } + else + release_region(iface->base, 8); + kfree(iface); mutex_lock(&scx200_acb_list_mutex); } mutex_unlock(&scx200_acb_list_mutex); diff --git a/trunk/drivers/media/video/cafe_ccic.c b/trunk/drivers/media/video/cafe_ccic.c index 49f1b8f1418e..789087cd6a9c 100644 --- a/trunk/drivers/media/video/cafe_ccic.c +++ b/trunk/drivers/media/video/cafe_ccic.c @@ -2184,7 +2184,9 @@ static int cafe_pci_resume(struct pci_dev *pdev) struct cafe_camera *cam = to_cam(v4l2_dev); int ret = 0; - pci_restore_state(pdev); + ret = pci_restore_state(pdev); + if (ret) + return ret; ret = pci_enable_device(pdev); if (ret) { diff --git a/trunk/drivers/mfd/88pm860x-core.c b/trunk/drivers/mfd/88pm860x-core.c index 793300c554b4..20895e7a99c9 100644 --- a/trunk/drivers/mfd/88pm860x-core.c +++ b/trunk/drivers/mfd/88pm860x-core.c @@ -361,6 +361,12 @@ static struct pm860x_irq_data pm860x_irqs[] = { }, }; +static inline struct pm860x_irq_data *irq_to_pm860x(struct pm860x_chip *chip, + int irq) +{ + return &pm860x_irqs[irq - chip->irq_base]; +} + static irqreturn_t pm860x_irq(int irq, void *data) { struct pm860x_chip *chip = data; @@ -382,16 +388,16 @@ static irqreturn_t pm860x_irq(int irq, void *data) return IRQ_HANDLED; } -static void pm860x_irq_lock(struct irq_data *data) +static void pm860x_irq_lock(unsigned int irq) { - struct pm860x_chip *chip = irq_data_get_irq_chip_data(data); + struct pm860x_chip *chip = get_irq_chip_data(irq); mutex_lock(&chip->irq_lock); } -static void pm860x_irq_sync_unlock(struct irq_data *data) +static void pm860x_irq_sync_unlock(unsigned int irq) { - struct pm860x_chip *chip = irq_data_get_irq_chip_data(data); + struct pm860x_chip *chip = get_irq_chip_data(irq); struct pm860x_irq_data *irq_data; struct i2c_client *i2c; static unsigned char cached[3] = {0x0, 0x0, 0x0}; @@ -433,25 +439,25 @@ static void pm860x_irq_sync_unlock(struct irq_data *data) mutex_unlock(&chip->irq_lock); } -static void pm860x_irq_enable(struct irq_data *data) +static void pm860x_irq_enable(unsigned int irq) { - struct pm860x_chip *chip = irq_data_get_irq_chip_data(data); - pm860x_irqs[data->irq - chip->irq_base].enable - = pm860x_irqs[data->irq - chip->irq_base].offs; + struct pm860x_chip *chip = get_irq_chip_data(irq); + pm860x_irqs[irq - chip->irq_base].enable + = pm860x_irqs[irq - chip->irq_base].offs; } -static void pm860x_irq_disable(struct irq_data *data) +static void pm860x_irq_disable(unsigned int irq) { - struct pm860x_chip *chip = irq_data_get_irq_chip_data(data); - pm860x_irqs[data->irq - chip->irq_base].enable = 0; + struct pm860x_chip *chip = get_irq_chip_data(irq); + pm860x_irqs[irq - chip->irq_base].enable = 0; } static struct irq_chip pm860x_irq_chip = { .name = "88pm860x", - .irq_bus_lock = pm860x_irq_lock, - .irq_bus_sync_unlock = pm860x_irq_sync_unlock, - .irq_enable = pm860x_irq_enable, - .irq_disable = pm860x_irq_disable, + .bus_lock = pm860x_irq_lock, + .bus_sync_unlock = pm860x_irq_sync_unlock, + .enable = pm860x_irq_enable, + .disable = pm860x_irq_disable, }; static int __devinit device_gpadc_init(struct pm860x_chip *chip, diff --git a/trunk/drivers/mfd/Kconfig b/trunk/drivers/mfd/Kconfig index fd018366d670..da9d2971102e 100644 --- a/trunk/drivers/mfd/Kconfig +++ b/trunk/drivers/mfd/Kconfig @@ -496,13 +496,13 @@ config EZX_PCAP config AB8500_CORE bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" - depends on GENERIC_HARDIRQS && ABX500_CORE + depends on GENERIC_HARDIRQS && ABX500_CORE && SPI_MASTER && ARCH_U8500 select MFD_CORE help Select this option to enable access to AB8500 power management - chip. This connects to U8500 either on the SSP/SPI bus (deprecated - since hardware version v1.0) or the I2C bus via PRCMU. It also adds - the irq_chip parts for handling the Mixed Signal chip events. + chip. This connects to U8500 either on the SSP/SPI bus + or the I2C bus via PRCMU. It also adds the irq_chip + parts for handling the Mixed Signal chip events. This chip embeds various other multimedia funtionalities as well. config AB8500_I2C_CORE @@ -537,14 +537,6 @@ config AB3550_CORE LEDs, vibrator, system power and temperature, power management and ALSA sound. -config MFD_CS5535 - tristate "Support for CS5535 and CS5536 southbridge core functions" - select MFD_CORE - depends on PCI - ---help--- - This is the core driver for CS5535/CS5536 MFD functions. This is - necessary for using the board's GPIO and MFGPT functionality. - config MFD_TIMBERDALE tristate "Support for the Timberdale FPGA" select MFD_CORE diff --git a/trunk/drivers/mfd/Makefile b/trunk/drivers/mfd/Makefile index a54e2c7c6a1c..848e7eac75aa 100644 --- a/trunk/drivers/mfd/Makefile +++ b/trunk/drivers/mfd/Makefile @@ -70,7 +70,7 @@ obj-$(CONFIG_ABX500_CORE) += abx500-core.o obj-$(CONFIG_AB3100_CORE) += ab3100-core.o obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o obj-$(CONFIG_AB3550_CORE) += ab3550-core.o -obj-$(CONFIG_AB8500_CORE) += ab8500-core.o +obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-spi.o obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o @@ -82,4 +82,3 @@ obj-$(CONFIG_MFD_JZ4740_ADC) += jz4740-adc.o obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o obj-$(CONFIG_MFD_VX855) += vx855.o obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o -obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o diff --git a/trunk/drivers/mfd/ab3550-core.c b/trunk/drivers/mfd/ab3550-core.c index 5fbca346b998..8a98739e6d9c 100644 --- a/trunk/drivers/mfd/ab3550-core.c +++ b/trunk/drivers/mfd/ab3550-core.c @@ -1159,16 +1159,15 @@ static void ab3550_mask_work(struct work_struct *work) } } -static void ab3550_mask(struct irq_data *data) +static void ab3550_mask(unsigned int irq) { unsigned long flags; struct ab3550 *ab; struct ab3550_platform_data *plf_data; - int irq; - ab = irq_data_get_irq_chip_data(data); + ab = get_irq_chip_data(irq); plf_data = ab->i2c_client[0]->dev.platform_data; - irq = data->irq - plf_data->irq.base; + irq -= plf_data->irq.base; spin_lock_irqsave(&ab->event_lock, flags); ab->event_mask[irq / 8] |= BIT(irq % 8); @@ -1177,16 +1176,15 @@ static void ab3550_mask(struct irq_data *data) schedule_work(&ab->mask_work); } -static void ab3550_unmask(struct irq_data *data) +static void ab3550_unmask(unsigned int irq) { unsigned long flags; struct ab3550 *ab; struct ab3550_platform_data *plf_data; - int irq; - ab = irq_data_get_irq_chip_data(data); + ab = get_irq_chip_data(irq); plf_data = ab->i2c_client[0]->dev.platform_data; - irq = data->irq - plf_data->irq.base; + irq -= plf_data->irq.base; spin_lock_irqsave(&ab->event_lock, flags); ab->event_mask[irq / 8] &= ~BIT(irq % 8); @@ -1195,16 +1193,20 @@ static void ab3550_unmask(struct irq_data *data) schedule_work(&ab->mask_work); } -static void noop(struct irq_data *data) +static void noop(unsigned int irq) { } static struct irq_chip ab3550_irq_chip = { .name = "ab3550-core", /* Keep the same name as the request */ - .irq_disable = ab3550_mask, /* No default to mask in chip.c */ - .irq_ack = noop, - .irq_mask = ab3550_mask, - .irq_unmask = ab3550_unmask, + .startup = NULL, /* defaults to enable */ + .shutdown = NULL, /* defaults to disable */ + .enable = NULL, /* defaults to unmask */ + .disable = ab3550_mask, /* No default to mask in chip.c */ + .ack = noop, + .mask = ab3550_mask, + .unmask = ab3550_unmask, + .end = NULL, }; struct ab_family_id { diff --git a/trunk/drivers/mfd/ab8500-core.c b/trunk/drivers/mfd/ab8500-core.c index b6887014d687..d9640a623ff4 100644 --- a/trunk/drivers/mfd/ab8500-core.c +++ b/trunk/drivers/mfd/ab8500-core.c @@ -52,7 +52,6 @@ #define AB8500_IT_LATCH8_REG 0x27 #define AB8500_IT_LATCH9_REG 0x28 #define AB8500_IT_LATCH10_REG 0x29 -#define AB8500_IT_LATCH12_REG 0x2B #define AB8500_IT_LATCH19_REG 0x32 #define AB8500_IT_LATCH20_REG 0x33 #define AB8500_IT_LATCH21_REG 0x34 @@ -99,17 +98,13 @@ * offset 0. */ static const int ab8500_irq_regoffset[AB8500_NUM_IRQ_REGS] = { - 0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 18, 19, 20, 21, + 0, 1, 2, 3, 4, 6, 7, 8, 9, 18, 19, 20, 21, }; static int ab8500_get_chip_id(struct device *dev) { - struct ab8500 *ab8500; - - if (!dev) - return -EINVAL; - ab8500 = dev_get_drvdata(dev->parent); - return ab8500 ? (int)ab8500->chip_id : -EINVAL; + struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); + return (int)ab8500->chip_id; } static int set_register_interruptible(struct ab8500 *ab8500, u8 bank, @@ -233,16 +228,16 @@ static struct abx500_ops ab8500_ops = { .startup_irq_enabled = NULL, }; -static void ab8500_irq_lock(struct irq_data *data) +static void ab8500_irq_lock(unsigned int irq) { - struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data); + struct ab8500 *ab8500 = get_irq_chip_data(irq); mutex_lock(&ab8500->irq_lock); } -static void ab8500_irq_sync_unlock(struct irq_data *data) +static void ab8500_irq_sync_unlock(unsigned int irq) { - struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data); + struct ab8500 *ab8500 = get_irq_chip_data(irq); int i; for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) { @@ -253,10 +248,6 @@ static void ab8500_irq_sync_unlock(struct irq_data *data) if (new == old) continue; - /* Interrupt register 12 does'nt exist prior to version 0x20 */ - if (ab8500_irq_regoffset[i] == 11 && ab8500->chip_id < 0x20) - continue; - ab8500->oldmask[i] = new; reg = AB8500_IT_MASK1_REG + ab8500_irq_regoffset[i]; @@ -266,20 +257,20 @@ static void ab8500_irq_sync_unlock(struct irq_data *data) mutex_unlock(&ab8500->irq_lock); } -static void ab8500_irq_mask(struct irq_data *data) +static void ab8500_irq_mask(unsigned int irq) { - struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data); - int offset = data->irq - ab8500->irq_base; + struct ab8500 *ab8500 = get_irq_chip_data(irq); + int offset = irq - ab8500->irq_base; int index = offset / 8; int mask = 1 << (offset % 8); ab8500->mask[index] |= mask; } -static void ab8500_irq_unmask(struct irq_data *data) +static void ab8500_irq_unmask(unsigned int irq) { - struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data); - int offset = data->irq - ab8500->irq_base; + struct ab8500 *ab8500 = get_irq_chip_data(irq); + int offset = irq - ab8500->irq_base; int index = offset / 8; int mask = 1 << (offset % 8); @@ -288,10 +279,10 @@ static void ab8500_irq_unmask(struct irq_data *data) static struct irq_chip ab8500_irq_chip = { .name = "ab8500", - .irq_bus_lock = ab8500_irq_lock, - .irq_bus_sync_unlock = ab8500_irq_sync_unlock, - .irq_mask = ab8500_irq_mask, - .irq_unmask = ab8500_irq_unmask, + .bus_lock = ab8500_irq_lock, + .bus_sync_unlock = ab8500_irq_sync_unlock, + .mask = ab8500_irq_mask, + .unmask = ab8500_irq_unmask, }; static irqreturn_t ab8500_irq(int irq, void *dev) @@ -306,10 +297,6 @@ static irqreturn_t ab8500_irq(int irq, void *dev) int status; u8 value; - /* Interrupt register 12 does'nt exist prior to version 0x20 */ - if (regoffset == 11 && ab8500->chip_id < 0x20) - continue; - status = get_register_interruptible(ab8500, AB8500_INTERRUPT, AB8500_IT_LATCH1_REG + regoffset, &value); if (status < 0 || value == 0) @@ -406,194 +393,12 @@ static struct resource ab8500_poweronkey_db_resources[] = { }, }; -static struct resource ab8500_bm_resources[] = { - { - .name = "MAIN_EXT_CH_NOT_OK", - .start = AB8500_INT_MAIN_EXT_CH_NOT_OK, - .end = AB8500_INT_MAIN_EXT_CH_NOT_OK, - .flags = IORESOURCE_IRQ, - }, - { - .name = "BATT_OVV", - .start = AB8500_INT_BATT_OVV, - .end = AB8500_INT_BATT_OVV, - .flags = IORESOURCE_IRQ, - }, - { - .name = "MAIN_CH_UNPLUG_DET", - .start = AB8500_INT_MAIN_CH_UNPLUG_DET, - .end = AB8500_INT_MAIN_CH_UNPLUG_DET, - .flags = IORESOURCE_IRQ, - }, - { - .name = "MAIN_CHARGE_PLUG_DET", - .start = AB8500_INT_MAIN_CH_PLUG_DET, - .end = AB8500_INT_MAIN_CH_PLUG_DET, - .flags = IORESOURCE_IRQ, - }, - { - .name = "VBUS_DET_F", - .start = AB8500_INT_VBUS_DET_F, - .end = AB8500_INT_VBUS_DET_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "VBUS_DET_R", - .start = AB8500_INT_VBUS_DET_R, - .end = AB8500_INT_VBUS_DET_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "BAT_CTRL_INDB", - .start = AB8500_INT_BAT_CTRL_INDB, - .end = AB8500_INT_BAT_CTRL_INDB, - .flags = IORESOURCE_IRQ, - }, - { - .name = "CH_WD_EXP", - .start = AB8500_INT_CH_WD_EXP, - .end = AB8500_INT_CH_WD_EXP, - .flags = IORESOURCE_IRQ, - }, - { - .name = "VBUS_OVV", - .start = AB8500_INT_VBUS_OVV, - .end = AB8500_INT_VBUS_OVV, - .flags = IORESOURCE_IRQ, - }, - { - .name = "NCONV_ACCU", - .start = AB8500_INT_CCN_CONV_ACC, - .end = AB8500_INT_CCN_CONV_ACC, - .flags = IORESOURCE_IRQ, - }, - { - .name = "LOW_BAT_F", - .start = AB8500_INT_LOW_BAT_F, - .end = AB8500_INT_LOW_BAT_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "LOW_BAT_R", - .start = AB8500_INT_LOW_BAT_R, - .end = AB8500_INT_LOW_BAT_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "BTEMP_LOW", - .start = AB8500_INT_BTEMP_LOW, - .end = AB8500_INT_BTEMP_LOW, - .flags = IORESOURCE_IRQ, - }, - { - .name = "BTEMP_HIGH", - .start = AB8500_INT_BTEMP_HIGH, - .end = AB8500_INT_BTEMP_HIGH, - .flags = IORESOURCE_IRQ, - }, - { - .name = "USB_CHARGER_NOT_OKR", - .start = AB8500_INT_USB_CHARGER_NOT_OK, - .end = AB8500_INT_USB_CHARGER_NOT_OK, - .flags = IORESOURCE_IRQ, - }, - { - .name = "USB_CHARGE_DET_DONE", - .start = AB8500_INT_USB_CHG_DET_DONE, - .end = AB8500_INT_USB_CHG_DET_DONE, - .flags = IORESOURCE_IRQ, - }, - { - .name = "USB_CH_TH_PROT_R", - .start = AB8500_INT_USB_CH_TH_PROT_R, - .end = AB8500_INT_USB_CH_TH_PROT_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "MAIN_CH_TH_PROT_R", - .start = AB8500_INT_MAIN_CH_TH_PROT_R, - .end = AB8500_INT_MAIN_CH_TH_PROT_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "USB_CHARGER_NOT_OKF", - .start = AB8500_INT_USB_CHARGER_NOT_OKF, - .end = AB8500_INT_USB_CHARGER_NOT_OKF, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource ab8500_debug_resources[] = { - { - .name = "IRQ_FIRST", - .start = AB8500_INT_MAIN_EXT_CH_NOT_OK, - .end = AB8500_INT_MAIN_EXT_CH_NOT_OK, - .flags = IORESOURCE_IRQ, - }, - { - .name = "IRQ_LAST", - .start = AB8500_INT_USB_CHARGER_NOT_OKF, - .end = AB8500_INT_USB_CHARGER_NOT_OKF, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource ab8500_usb_resources[] = { - { - .name = "ID_WAKEUP_R", - .start = AB8500_INT_ID_WAKEUP_R, - .end = AB8500_INT_ID_WAKEUP_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ID_WAKEUP_F", - .start = AB8500_INT_ID_WAKEUP_F, - .end = AB8500_INT_ID_WAKEUP_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "VBUS_DET_F", - .start = AB8500_INT_VBUS_DET_F, - .end = AB8500_INT_VBUS_DET_F, - .flags = IORESOURCE_IRQ, - }, - { - .name = "VBUS_DET_R", - .start = AB8500_INT_VBUS_DET_R, - .end = AB8500_INT_VBUS_DET_R, - .flags = IORESOURCE_IRQ, - }, - { - .name = "USB_LINK_STATUS", - .start = AB8500_INT_USB_LINK_STATUS, - .end = AB8500_INT_USB_LINK_STATUS, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource ab8500_temp_resources[] = { - { - .name = "AB8500_TEMP_WARM", - .start = AB8500_INT_TEMP_WARM, - .end = AB8500_INT_TEMP_WARM, - .flags = IORESOURCE_IRQ, - }, -}; - static struct mfd_cell ab8500_devs[] = { #ifdef CONFIG_DEBUG_FS { .name = "ab8500-debug", - .num_resources = ARRAY_SIZE(ab8500_debug_resources), - .resources = ab8500_debug_resources, }, #endif - { - .name = "ab8500-sysctrl", - }, - { - .name = "ab8500-regulator", - }, { .name = "ab8500-gpadc", .num_resources = ARRAY_SIZE(ab8500_gpadc_resources), @@ -604,22 +409,6 @@ static struct mfd_cell ab8500_devs[] = { .num_resources = ARRAY_SIZE(ab8500_rtc_resources), .resources = ab8500_rtc_resources, }, - { - .name = "ab8500-bm", - .num_resources = ARRAY_SIZE(ab8500_bm_resources), - .resources = ab8500_bm_resources, - }, - { .name = "ab8500-codec", }, - { - .name = "ab8500-usb", - .num_resources = ARRAY_SIZE(ab8500_usb_resources), - .resources = ab8500_usb_resources, - }, - { - .name = "ab8500-poweron-key", - .num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources), - .resources = ab8500_poweronkey_db_resources, - }, { .name = "ab8500-pwm", .id = 1, @@ -632,37 +421,17 @@ static struct mfd_cell ab8500_devs[] = { .name = "ab8500-pwm", .id = 3, }, - { .name = "ab8500-leds", }, - { - .name = "ab8500-denc", - }, + { .name = "ab8500-charger", }, + { .name = "ab8500-audio", }, + { .name = "ab8500-usb", }, + { .name = "ab8500-regulator", }, { - .name = "ab8500-temp", - .num_resources = ARRAY_SIZE(ab8500_temp_resources), - .resources = ab8500_temp_resources, + .name = "ab8500-poweron-key", + .num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources), + .resources = ab8500_poweronkey_db_resources, }, }; -static ssize_t show_chip_id(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct ab8500 *ab8500; - - ab8500 = dev_get_drvdata(dev); - return sprintf(buf, "%#x\n", ab8500 ? ab8500->chip_id : -EINVAL); -} - -static DEVICE_ATTR(chip_id, S_IRUGO, show_chip_id, NULL); - -static struct attribute *ab8500_sysfs_entries[] = { - &dev_attr_chip_id.attr, - NULL, -}; - -static struct attribute_group ab8500_attr_group = { - .attrs = ab8500_sysfs_entries, -}; - int __devinit ab8500_init(struct ab8500 *ab8500) { struct ab8500_platform_data *plat = dev_get_platdata(ab8500->dev); @@ -685,9 +454,8 @@ int __devinit ab8500_init(struct ab8500 *ab8500) * 0x0 - Early Drop * 0x10 - Cut 1.0 * 0x11 - Cut 1.1 - * 0x20 - Cut 2.0 */ - if (value == 0x0 || value == 0x10 || value == 0x11 || value == 0x20) { + if (value == 0x0 || value == 0x10 || value == 0x11) { ab8500->revision = value; dev_info(ab8500->dev, "detected chip, revision: %#x\n", value); } else { @@ -700,16 +468,18 @@ int __devinit ab8500_init(struct ab8500 *ab8500) plat->init(ab8500); /* Clear and mask all interrupts */ - for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) { - /* Interrupt register 12 does'nt exist prior to version 0x20 */ - if (ab8500_irq_regoffset[i] == 11 && ab8500->chip_id < 0x20) - continue; + for (i = 0; i < 10; i++) { + get_register_interruptible(ab8500, AB8500_INTERRUPT, + AB8500_IT_LATCH1_REG + i, &value); + set_register_interruptible(ab8500, AB8500_INTERRUPT, + AB8500_IT_MASK1_REG + i, 0xff); + } + for (i = 18; i < 24; i++) { get_register_interruptible(ab8500, AB8500_INTERRUPT, - AB8500_IT_LATCH1_REG + ab8500_irq_regoffset[i], - &value); + AB8500_IT_LATCH1_REG + i, &value); set_register_interruptible(ab8500, AB8500_INTERRUPT, - AB8500_IT_MASK1_REG + ab8500_irq_regoffset[i], 0xff); + AB8500_IT_MASK1_REG + i, 0xff); } ret = abx500_register_ops(ab8500->dev, &ab8500_ops); @@ -725,8 +495,7 @@ int __devinit ab8500_init(struct ab8500 *ab8500) return ret; ret = request_threaded_irq(ab8500->irq, NULL, ab8500_irq, - IRQF_ONESHOT | IRQF_NO_SUSPEND, - "ab8500", ab8500); + IRQF_ONESHOT, "ab8500", ab8500); if (ret) goto out_removeirq; } @@ -737,10 +506,6 @@ int __devinit ab8500_init(struct ab8500 *ab8500) if (ret) goto out_freeirq; - ret = sysfs_create_group(&ab8500->dev->kobj, &ab8500_attr_group); - if (ret) - dev_err(ab8500->dev, "error creating sysfs entries\n"); - return ret; out_freeirq: @@ -754,7 +519,6 @@ int __devinit ab8500_init(struct ab8500 *ab8500) int __devexit ab8500_exit(struct ab8500 *ab8500) { - sysfs_remove_group(&ab8500->dev->kobj, &ab8500_attr_group); mfd_remove_devices(ab8500->dev); if (ab8500->irq_base) { free_irq(ab8500->irq, ab8500); diff --git a/trunk/drivers/mfd/ab8500-debugfs.c b/trunk/drivers/mfd/ab8500-debugfs.c index 3c1541ae7223..8d1e05a39815 100644 --- a/trunk/drivers/mfd/ab8500-debugfs.c +++ b/trunk/drivers/mfd/ab8500-debugfs.c @@ -24,9 +24,9 @@ static u32 debug_address; * @perm: access permissions for the range */ struct ab8500_reg_range { - u8 first; - u8 last; - u8 perm; + u8 first; + u8 last; + u8 perm; }; /** @@ -36,9 +36,9 @@ struct ab8500_reg_range { * @range: the list of register ranges */ struct ab8500_i2c_ranges { - u8 num_ranges; - u8 bankid; - const struct ab8500_reg_range *range; + u8 num_ranges; + u8 bankid; + const struct ab8500_reg_range *range; }; #define AB8500_NAME_STRING "ab8500" @@ -47,521 +47,521 @@ struct ab8500_i2c_ranges { #define AB8500_REV_REG 0x80 static struct ab8500_i2c_ranges debug_ranges[AB8500_NUM_BANKS] = { - [0x0] = { - .num_ranges = 0, - .range = 0, - }, - [AB8500_SYS_CTRL1_BLOCK] = { - .num_ranges = 3, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x02, - }, - { - .first = 0x42, - .last = 0x42, - }, - { - .first = 0x80, - .last = 0x81, - }, - }, - }, - [AB8500_SYS_CTRL2_BLOCK] = { - .num_ranges = 4, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x0D, - }, - { - .first = 0x0F, - .last = 0x17, - }, - { - .first = 0x30, - .last = 0x30, - }, - { - .first = 0x32, - .last = 0x33, - }, - }, - }, - [AB8500_REGU_CTRL1] = { - .num_ranges = 3, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x00, - }, - { - .first = 0x03, - .last = 0x10, - }, - { - .first = 0x80, - .last = 0x84, - }, - }, - }, - [AB8500_REGU_CTRL2] = { - .num_ranges = 5, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x15, - }, - { - .first = 0x17, - .last = 0x19, - }, - { - .first = 0x1B, - .last = 0x1D, - }, - { - .first = 0x1F, - .last = 0x22, - }, - { - .first = 0x40, - .last = 0x44, - }, - /* 0x80-0x8B is SIM registers and should - * not be accessed from here */ - }, - }, - [AB8500_USB] = { - .num_ranges = 2, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x80, - .last = 0x83, - }, - { - .first = 0x87, - .last = 0x8A, - }, - }, - }, - [AB8500_TVOUT] = { - .num_ranges = 9, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x12, - }, - { - .first = 0x15, - .last = 0x17, - }, - { - .first = 0x19, - .last = 0x21, - }, - { - .first = 0x27, - .last = 0x2C, - }, - { - .first = 0x41, - .last = 0x41, - }, - { - .first = 0x45, - .last = 0x5B, - }, - { - .first = 0x5D, - .last = 0x5D, - }, - { - .first = 0x69, - .last = 0x69, - }, - { - .first = 0x80, - .last = 0x81, - }, - }, - }, - [AB8500_DBI] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_ECI_AV_ACC] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x80, - .last = 0x82, - }, - }, - }, - [0x9] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_GPADC] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x08, - }, - }, - }, - [AB8500_CHARGER] = { - .num_ranges = 8, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x03, - }, - { - .first = 0x05, - .last = 0x05, - }, - { - .first = 0x40, - .last = 0x40, - }, - { - .first = 0x42, - .last = 0x42, - }, - { - .first = 0x44, - .last = 0x44, - }, - { - .first = 0x50, - .last = 0x55, - }, - { - .first = 0x80, - .last = 0x82, - }, - { - .first = 0xC0, - .last = 0xC2, - }, - }, - }, - [AB8500_GAS_GAUGE] = { - .num_ranges = 3, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x00, - }, - { - .first = 0x07, - .last = 0x0A, - }, - { - .first = 0x10, - .last = 0x14, - }, - }, - }, - [AB8500_AUDIO] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x6F, - }, - }, - }, - [AB8500_INTERRUPT] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_RTC] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x0F, - }, - }, - }, - [AB8500_MISC] = { - .num_ranges = 8, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x00, - .last = 0x05, - }, - { - .first = 0x10, - .last = 0x15, - }, - { - .first = 0x20, - .last = 0x25, - }, - { - .first = 0x30, - .last = 0x35, - }, - { - .first = 0x40, - .last = 0x45, - }, - { - .first = 0x50, - .last = 0x50, - }, - { - .first = 0x60, - .last = 0x67, - }, - { - .first = 0x80, - .last = 0x80, - }, - }, - }, - [0x11] = { - .num_ranges = 0, - .range = NULL, - }, - [0x12] = { - .num_ranges = 0, - .range = NULL, - }, - [0x13] = { - .num_ranges = 0, - .range = NULL, - }, - [0x14] = { - .num_ranges = 0, - .range = NULL, - }, - [AB8500_OTP_EMUL] = { - .num_ranges = 1, - .range = (struct ab8500_reg_range[]) { - { - .first = 0x01, - .last = 0x0F, - }, - }, - }, + [0x0] = { + .num_ranges = 0, + .range = 0, + }, + [AB8500_SYS_CTRL1_BLOCK] = { + .num_ranges = 3, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x02, + }, + { + .first = 0x42, + .last = 0x42, + }, + { + .first = 0x80, + .last = 0x81, + }, + }, + }, + [AB8500_SYS_CTRL2_BLOCK] = { + .num_ranges = 4, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x0D, + }, + { + .first = 0x0F, + .last = 0x17, + }, + { + .first = 0x30, + .last = 0x30, + }, + { + .first = 0x32, + .last = 0x33, + }, + }, + }, + [AB8500_REGU_CTRL1] = { + .num_ranges = 3, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x00, + }, + { + .first = 0x03, + .last = 0x10, + }, + { + .first = 0x80, + .last = 0x84, + }, + }, + }, + [AB8500_REGU_CTRL2] = { + .num_ranges = 5, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x15, + }, + { + .first = 0x17, + .last = 0x19, + }, + { + .first = 0x1B, + .last = 0x1D, + }, + { + .first = 0x1F, + .last = 0x22, + }, + { + .first = 0x40, + .last = 0x44, + }, + /* 0x80-0x8B is SIM registers and should + * not be accessed from here */ + }, + }, + [AB8500_USB] = { + .num_ranges = 2, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x80, + .last = 0x83, + }, + { + .first = 0x87, + .last = 0x8A, + }, + }, + }, + [AB8500_TVOUT] = { + .num_ranges = 9, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x12, + }, + { + .first = 0x15, + .last = 0x17, + }, + { + .first = 0x19, + .last = 0x21, + }, + { + .first = 0x27, + .last = 0x2C, + }, + { + .first = 0x41, + .last = 0x41, + }, + { + .first = 0x45, + .last = 0x5B, + }, + { + .first = 0x5D, + .last = 0x5D, + }, + { + .first = 0x69, + .last = 0x69, + }, + { + .first = 0x80, + .last = 0x81, + }, + }, + }, + [AB8500_DBI] = { + .num_ranges = 0, + .range = 0, + }, + [AB8500_ECI_AV_ACC] = { + .num_ranges = 1, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x80, + .last = 0x82, + }, + }, + }, + [0x9] = { + .num_ranges = 0, + .range = 0, + }, + [AB8500_GPADC] = { + .num_ranges = 1, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x08, + }, + }, + }, + [AB8500_CHARGER] = { + .num_ranges = 8, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x03, + }, + { + .first = 0x05, + .last = 0x05, + }, + { + .first = 0x40, + .last = 0x40, + }, + { + .first = 0x42, + .last = 0x42, + }, + { + .first = 0x44, + .last = 0x44, + }, + { + .first = 0x50, + .last = 0x55, + }, + { + .first = 0x80, + .last = 0x82, + }, + { + .first = 0xC0, + .last = 0xC2, + }, + }, + }, + [AB8500_GAS_GAUGE] = { + .num_ranges = 3, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x00, + }, + { + .first = 0x07, + .last = 0x0A, + }, + { + .first = 0x10, + .last = 0x14, + }, + }, + }, + [AB8500_AUDIO] = { + .num_ranges = 1, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x6F, + }, + }, + }, + [AB8500_INTERRUPT] = { + .num_ranges = 0, + .range = 0, + }, + [AB8500_RTC] = { + .num_ranges = 1, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x0F, + }, + }, + }, + [AB8500_MISC] = { + .num_ranges = 8, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x00, + .last = 0x05, + }, + { + .first = 0x10, + .last = 0x15, + }, + { + .first = 0x20, + .last = 0x25, + }, + { + .first = 0x30, + .last = 0x35, + }, + { + .first = 0x40, + .last = 0x45, + }, + { + .first = 0x50, + .last = 0x50, + }, + { + .first = 0x60, + .last = 0x67, + }, + { + .first = 0x80, + .last = 0x80, + }, + }, + }, + [0x11] = { + .num_ranges = 0, + .range = 0, + }, + [0x12] = { + .num_ranges = 0, + .range = 0, + }, + [0x13] = { + .num_ranges = 0, + .range = 0, + }, + [0x14] = { + .num_ranges = 0, + .range = 0, + }, + [AB8500_OTP_EMUL] = { + .num_ranges = 1, + .range = (struct ab8500_reg_range[]) { + { + .first = 0x01, + .last = 0x0F, + }, + }, + }, }; static int ab8500_registers_print(struct seq_file *s, void *p) { - struct device *dev = s->private; - unsigned int i; - u32 bank = debug_bank; - - seq_printf(s, AB8500_NAME_STRING " register values:\n"); - - seq_printf(s, " bank %u:\n", bank); - for (i = 0; i < debug_ranges[bank].num_ranges; i++) { - u32 reg; - - for (reg = debug_ranges[bank].range[i].first; - reg <= debug_ranges[bank].range[i].last; - reg++) { - u8 value; - int err; - - err = abx500_get_register_interruptible(dev, - (u8)bank, (u8)reg, &value); - if (err < 0) { - dev_err(dev, "ab->read fail %d\n", err); - return err; - } - - err = seq_printf(s, " [%u/0x%02X]: 0x%02X\n", bank, - reg, value); - if (err < 0) { - dev_err(dev, "seq_printf overflow\n"); - /* Error is not returned here since - * the output is wanted in any case */ - return 0; - } - } - } - return 0; + struct device *dev = s->private; + unsigned int i; + u32 bank = debug_bank; + + seq_printf(s, AB8500_NAME_STRING " register values:\n"); + + seq_printf(s, " bank %u:\n", bank); + for (i = 0; i < debug_ranges[bank].num_ranges; i++) { + u32 reg; + + for (reg = debug_ranges[bank].range[i].first; + reg <= debug_ranges[bank].range[i].last; + reg++) { + u8 value; + int err; + + err = abx500_get_register_interruptible(dev, + (u8)bank, (u8)reg, &value); + if (err < 0) { + dev_err(dev, "ab->read fail %d\n", err); + return err; + } + + err = seq_printf(s, " [%u/0x%02X]: 0x%02X\n", bank, + reg, value); + if (err < 0) { + dev_err(dev, "seq_printf overflow\n"); + /* Error is not returned here since + * the output is wanted in any case */ + return 0; + } + } + } + return 0; } static int ab8500_registers_open(struct inode *inode, struct file *file) { - return single_open(file, ab8500_registers_print, inode->i_private); + return single_open(file, ab8500_registers_print, inode->i_private); } static const struct file_operations ab8500_registers_fops = { - .open = ab8500_registers_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner = THIS_MODULE, + .open = ab8500_registers_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, }; static int ab8500_bank_print(struct seq_file *s, void *p) { - return seq_printf(s, "%d\n", debug_bank); + return seq_printf(s, "%d\n", debug_bank); } static int ab8500_bank_open(struct inode *inode, struct file *file) { - return single_open(file, ab8500_bank_print, inode->i_private); + return single_open(file, ab8500_bank_print, inode->i_private); } static ssize_t ab8500_bank_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) + const char __user *user_buf, + size_t count, loff_t *ppos) { - struct device *dev = ((struct seq_file *)(file->private_data))->private; - char buf[32]; - int buf_size; - unsigned long user_bank; - int err; - - /* Get userspace string and assure termination */ - buf_size = min(count, (sizeof(buf) - 1)); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - buf[buf_size] = 0; - - err = strict_strtoul(buf, 0, &user_bank); - if (err) - return -EINVAL; - - if (user_bank >= AB8500_NUM_BANKS) { - dev_err(dev, "debugfs error input > number of banks\n"); - return -EINVAL; - } - - debug_bank = user_bank; - - return buf_size; + struct device *dev = ((struct seq_file *)(file->private_data))->private; + char buf[32]; + int buf_size; + unsigned long user_bank; + int err; + + /* Get userspace string and assure termination */ + buf_size = min(count, (sizeof(buf) - 1)); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + buf[buf_size] = 0; + + err = strict_strtoul(buf, 0, &user_bank); + if (err) + return -EINVAL; + + if (user_bank >= AB8500_NUM_BANKS) { + dev_err(dev, "debugfs error input > number of banks\n"); + return -EINVAL; + } + + debug_bank = user_bank; + + return buf_size; } static int ab8500_address_print(struct seq_file *s, void *p) { - return seq_printf(s, "0x%02X\n", debug_address); + return seq_printf(s, "0x%02X\n", debug_address); } static int ab8500_address_open(struct inode *inode, struct file *file) { - return single_open(file, ab8500_address_print, inode->i_private); + return single_open(file, ab8500_address_print, inode->i_private); } static ssize_t ab8500_address_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) + const char __user *user_buf, + size_t count, loff_t *ppos) { - struct device *dev = ((struct seq_file *)(file->private_data))->private; - char buf[32]; - int buf_size; - unsigned long user_address; - int err; - - /* Get userspace string and assure termination */ - buf_size = min(count, (sizeof(buf) - 1)); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - buf[buf_size] = 0; - - err = strict_strtoul(buf, 0, &user_address); - if (err) - return -EINVAL; - if (user_address > 0xff) { - dev_err(dev, "debugfs error input > 0xff\n"); - return -EINVAL; - } - debug_address = user_address; - return buf_size; + struct device *dev = ((struct seq_file *)(file->private_data))->private; + char buf[32]; + int buf_size; + unsigned long user_address; + int err; + + /* Get userspace string and assure termination */ + buf_size = min(count, (sizeof(buf) - 1)); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + buf[buf_size] = 0; + + err = strict_strtoul(buf, 0, &user_address); + if (err) + return -EINVAL; + if (user_address > 0xff) { + dev_err(dev, "debugfs error input > 0xff\n"); + return -EINVAL; + } + debug_address = user_address; + return buf_size; } static int ab8500_val_print(struct seq_file *s, void *p) { - struct device *dev = s->private; - int ret; - u8 regvalue; - - ret = abx500_get_register_interruptible(dev, - (u8)debug_bank, (u8)debug_address, ®value); - if (ret < 0) { - dev_err(dev, "abx500_get_reg fail %d, %d\n", - ret, __LINE__); - return -EINVAL; - } - seq_printf(s, "0x%02X\n", regvalue); - - return 0; + struct device *dev = s->private; + int ret; + u8 regvalue; + + ret = abx500_get_register_interruptible(dev, + (u8)debug_bank, (u8)debug_address, ®value); + if (ret < 0) { + dev_err(dev, "abx500_get_reg fail %d, %d\n", + ret, __LINE__); + return -EINVAL; + } + seq_printf(s, "0x%02X\n", regvalue); + + return 0; } static int ab8500_val_open(struct inode *inode, struct file *file) { - return single_open(file, ab8500_val_print, inode->i_private); + return single_open(file, ab8500_val_print, inode->i_private); } static ssize_t ab8500_val_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) + const char __user *user_buf, + size_t count, loff_t *ppos) { - struct device *dev = ((struct seq_file *)(file->private_data))->private; - char buf[32]; - int buf_size; - unsigned long user_val; - int err; - - /* Get userspace string and assure termination */ - buf_size = min(count, (sizeof(buf)-1)); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - buf[buf_size] = 0; - - err = strict_strtoul(buf, 0, &user_val); - if (err) - return -EINVAL; - if (user_val > 0xff) { - dev_err(dev, "debugfs error input > 0xff\n"); - return -EINVAL; - } - err = abx500_set_register_interruptible(dev, - (u8)debug_bank, debug_address, (u8)user_val); - if (err < 0) { - printk(KERN_ERR "abx500_set_reg failed %d, %d", err, __LINE__); - return -EINVAL; - } - - return buf_size; + struct device *dev = ((struct seq_file *)(file->private_data))->private; + char buf[32]; + int buf_size; + unsigned long user_val; + int err; + + /* Get userspace string and assure termination */ + buf_size = min(count, (sizeof(buf)-1)); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + buf[buf_size] = 0; + + err = strict_strtoul(buf, 0, &user_val); + if (err) + return -EINVAL; + if (user_val > 0xff) { + dev_err(dev, "debugfs error input > 0xff\n"); + return -EINVAL; + } + err = abx500_set_register_interruptible(dev, + (u8)debug_bank, debug_address, (u8)user_val); + if (err < 0) { + printk(KERN_ERR "abx500_set_reg failed %d, %d", err, __LINE__); + return -EINVAL; + } + + return buf_size; } static const struct file_operations ab8500_bank_fops = { - .open = ab8500_bank_open, - .write = ab8500_bank_write, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner = THIS_MODULE, + .open = ab8500_bank_open, + .write = ab8500_bank_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, }; static const struct file_operations ab8500_address_fops = { - .open = ab8500_address_open, - .write = ab8500_address_write, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner = THIS_MODULE, + .open = ab8500_address_open, + .write = ab8500_address_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, }; static const struct file_operations ab8500_val_fops = { - .open = ab8500_val_open, - .write = ab8500_val_write, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner = THIS_MODULE, + .open = ab8500_val_open, + .write = ab8500_val_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, }; static struct dentry *ab8500_dir; @@ -572,77 +572,77 @@ static struct dentry *ab8500_val_file; static int __devinit ab8500_debug_probe(struct platform_device *plf) { - debug_bank = AB8500_MISC; - debug_address = AB8500_REV_REG & 0x00FF; + debug_bank = AB8500_MISC; + debug_address = AB8500_REV_REG & 0x00FF; - ab8500_dir = debugfs_create_dir(AB8500_NAME_STRING, NULL); - if (!ab8500_dir) - goto exit_no_debugfs; + ab8500_dir = debugfs_create_dir(AB8500_NAME_STRING, NULL); + if (!ab8500_dir) + goto exit_no_debugfs; - ab8500_reg_file = debugfs_create_file("all-bank-registers", - S_IRUGO, ab8500_dir, &plf->dev, &ab8500_registers_fops); - if (!ab8500_reg_file) - goto exit_destroy_dir; + ab8500_reg_file = debugfs_create_file("all-bank-registers", + S_IRUGO, ab8500_dir, &plf->dev, &ab8500_registers_fops); + if (!ab8500_reg_file) + goto exit_destroy_dir; - ab8500_bank_file = debugfs_create_file("register-bank", - (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, &ab8500_bank_fops); - if (!ab8500_bank_file) - goto exit_destroy_reg; + ab8500_bank_file = debugfs_create_file("register-bank", + (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, &ab8500_bank_fops); + if (!ab8500_bank_file) + goto exit_destroy_reg; - ab8500_address_file = debugfs_create_file("register-address", - (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, - &ab8500_address_fops); - if (!ab8500_address_file) - goto exit_destroy_bank; + ab8500_address_file = debugfs_create_file("register-address", + (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, + &ab8500_address_fops); + if (!ab8500_address_file) + goto exit_destroy_bank; - ab8500_val_file = debugfs_create_file("register-value", - (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, &ab8500_val_fops); - if (!ab8500_val_file) - goto exit_destroy_address; + ab8500_val_file = debugfs_create_file("register-value", + (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, &ab8500_val_fops); + if (!ab8500_val_file) + goto exit_destroy_address; - return 0; + return 0; exit_destroy_address: - debugfs_remove(ab8500_address_file); + debugfs_remove(ab8500_address_file); exit_destroy_bank: - debugfs_remove(ab8500_bank_file); + debugfs_remove(ab8500_bank_file); exit_destroy_reg: - debugfs_remove(ab8500_reg_file); + debugfs_remove(ab8500_reg_file); exit_destroy_dir: - debugfs_remove(ab8500_dir); + debugfs_remove(ab8500_dir); exit_no_debugfs: - dev_err(&plf->dev, "failed to create debugfs entries.\n"); - return -ENOMEM; + dev_err(&plf->dev, "failed to create debugfs entries.\n"); + return -ENOMEM; } static int __devexit ab8500_debug_remove(struct platform_device *plf) { - debugfs_remove(ab8500_val_file); - debugfs_remove(ab8500_address_file); - debugfs_remove(ab8500_bank_file); - debugfs_remove(ab8500_reg_file); - debugfs_remove(ab8500_dir); + debugfs_remove(ab8500_val_file); + debugfs_remove(ab8500_address_file); + debugfs_remove(ab8500_bank_file); + debugfs_remove(ab8500_reg_file); + debugfs_remove(ab8500_dir); - return 0; + return 0; } static struct platform_driver ab8500_debug_driver = { - .driver = { - .name = "ab8500-debug", - .owner = THIS_MODULE, - }, - .probe = ab8500_debug_probe, - .remove = __devexit_p(ab8500_debug_remove) + .driver = { + .name = "ab8500-debug", + .owner = THIS_MODULE, + }, + .probe = ab8500_debug_probe, + .remove = __devexit_p(ab8500_debug_remove) }; static int __init ab8500_debug_init(void) { - return platform_driver_register(&ab8500_debug_driver); + return platform_driver_register(&ab8500_debug_driver); } static void __exit ab8500_debug_exit(void) { - platform_driver_unregister(&ab8500_debug_driver); + platform_driver_unregister(&ab8500_debug_driver); } subsys_initcall(ab8500_debug_init); module_exit(ab8500_debug_exit); diff --git a/trunk/drivers/mfd/ab8500-spi.c b/trunk/drivers/mfd/ab8500-spi.c new file mode 100644 index 000000000000..b1653421edb5 --- /dev/null +++ b/trunk/drivers/mfd/ab8500-spi.c @@ -0,0 +1,143 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License Terms: GNU General Public License v2 + * Author: Srinidhi Kasagar + */ + +#include +#include +#include +#include +#include +#include +#include + +/* + * This funtion writes to any AB8500 registers using + * SPI protocol & before it writes it packs the data + * in the below 24 bit frame format + * + * *|------------------------------------| + * *| 23|22...18|17.......10|9|8|7......0| + * *| r/w bank adr data | + * * ------------------------------------ + * + * This function shouldn't be called from interrupt + * context + */ +static int ab8500_spi_write(struct ab8500 *ab8500, u16 addr, u8 data) +{ + struct spi_device *spi = container_of(ab8500->dev, struct spi_device, + dev); + unsigned long spi_data = addr << 10 | data; + struct spi_transfer xfer; + struct spi_message msg; + + ab8500->tx_buf[0] = spi_data; + ab8500->rx_buf[0] = 0; + + xfer.tx_buf = ab8500->tx_buf; + xfer.rx_buf = NULL; + xfer.len = sizeof(unsigned long); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + + return spi_sync(spi, &msg); +} + +static int ab8500_spi_read(struct ab8500 *ab8500, u16 addr) +{ + struct spi_device *spi = container_of(ab8500->dev, struct spi_device, + dev); + unsigned long spi_data = 1 << 23 | addr << 10; + struct spi_transfer xfer; + struct spi_message msg; + int ret; + + ab8500->tx_buf[0] = spi_data; + ab8500->rx_buf[0] = 0; + + xfer.tx_buf = ab8500->tx_buf; + xfer.rx_buf = ab8500->rx_buf; + xfer.len = sizeof(unsigned long); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + + ret = spi_sync(spi, &msg); + if (!ret) + /* + * Only the 8 lowermost bytes are + * defined with value, the rest may + * vary depending on chip/board noise. + */ + ret = ab8500->rx_buf[0] & 0xFFU; + + return ret; +} + +static int __devinit ab8500_spi_probe(struct spi_device *spi) +{ + struct ab8500 *ab8500; + int ret; + + spi->bits_per_word = 24; + ret = spi_setup(spi); + if (ret < 0) + return ret; + + ab8500 = kzalloc(sizeof *ab8500, GFP_KERNEL); + if (!ab8500) + return -ENOMEM; + + ab8500->dev = &spi->dev; + ab8500->irq = spi->irq; + + ab8500->read = ab8500_spi_read; + ab8500->write = ab8500_spi_write; + + spi_set_drvdata(spi, ab8500); + + ret = ab8500_init(ab8500); + if (ret) + kfree(ab8500); + + return ret; +} + +static int __devexit ab8500_spi_remove(struct spi_device *spi) +{ + struct ab8500 *ab8500 = spi_get_drvdata(spi); + + ab8500_exit(ab8500); + kfree(ab8500); + + return 0; +} + +static struct spi_driver ab8500_spi_driver = { + .driver = { + .name = "ab8500-spi", + .owner = THIS_MODULE, + }, + .probe = ab8500_spi_probe, + .remove = __devexit_p(ab8500_spi_remove) +}; + +static int __init ab8500_spi_init(void) +{ + return spi_register_driver(&ab8500_spi_driver); +} +subsys_initcall(ab8500_spi_init); + +static void __exit ab8500_spi_exit(void) +{ + spi_unregister_driver(&ab8500_spi_driver); +} +module_exit(ab8500_spi_exit); + +MODULE_AUTHOR("Srinidhi KASAGAR > asic->bus_shift)); } -static void asic3_set_register(struct asic3 *asic, u32 reg, u32 bits, bool set) +void asic3_set_register(struct asic3 *asic, u32 reg, u32 bits, bool set) { unsigned long flags; u32 val; @@ -226,14 +226,14 @@ static inline int asic3_irq_to_index(struct asic3 *asic, int irq) return (irq - asic->irq_base) & 0xf; } -static void asic3_mask_gpio_irq(struct irq_data *data) +static void asic3_mask_gpio_irq(unsigned int irq) { - struct asic3 *asic = irq_data_get_irq_chip_data(data); + struct asic3 *asic = get_irq_chip_data(irq); u32 val, bank, index; unsigned long flags; - bank = asic3_irq_to_bank(asic, data->irq); - index = asic3_irq_to_index(asic, data->irq); + bank = asic3_irq_to_bank(asic, irq); + index = asic3_irq_to_index(asic, irq); spin_lock_irqsave(&asic->lock, flags); val = asic3_read_register(asic, bank + ASIC3_GPIO_MASK); @@ -242,9 +242,9 @@ static void asic3_mask_gpio_irq(struct irq_data *data) spin_unlock_irqrestore(&asic->lock, flags); } -static void asic3_mask_irq(struct irq_data *data) +static void asic3_mask_irq(unsigned int irq) { - struct asic3 *asic = irq_data_get_irq_chip_data(data); + struct asic3 *asic = get_irq_chip_data(irq); int regval; unsigned long flags; @@ -254,7 +254,7 @@ static void asic3_mask_irq(struct irq_data *data) ASIC3_INTR_INT_MASK); regval &= ~(ASIC3_INTMASK_MASK0 << - (data->irq - (asic->irq_base + ASIC3_NUM_GPIOS))); + (irq - (asic->irq_base + ASIC3_NUM_GPIOS))); asic3_write_register(asic, ASIC3_INTR_BASE + @@ -263,14 +263,14 @@ static void asic3_mask_irq(struct irq_data *data) spin_unlock_irqrestore(&asic->lock, flags); } -static void asic3_unmask_gpio_irq(struct irq_data *data) +static void asic3_unmask_gpio_irq(unsigned int irq) { - struct asic3 *asic = irq_data_get_irq_chip_data(data); + struct asic3 *asic = get_irq_chip_data(irq); u32 val, bank, index; unsigned long flags; - bank = asic3_irq_to_bank(asic, data->irq); - index = asic3_irq_to_index(asic, data->irq); + bank = asic3_irq_to_bank(asic, irq); + index = asic3_irq_to_index(asic, irq); spin_lock_irqsave(&asic->lock, flags); val = asic3_read_register(asic, bank + ASIC3_GPIO_MASK); @@ -279,9 +279,9 @@ static void asic3_unmask_gpio_irq(struct irq_data *data) spin_unlock_irqrestore(&asic->lock, flags); } -static void asic3_unmask_irq(struct irq_data *data) +static void asic3_unmask_irq(unsigned int irq) { - struct asic3 *asic = irq_data_get_irq_chip_data(data); + struct asic3 *asic = get_irq_chip_data(irq); int regval; unsigned long flags; @@ -291,7 +291,7 @@ static void asic3_unmask_irq(struct irq_data *data) ASIC3_INTR_INT_MASK); regval |= (ASIC3_INTMASK_MASK0 << - (data->irq - (asic->irq_base + ASIC3_NUM_GPIOS))); + (irq - (asic->irq_base + ASIC3_NUM_GPIOS))); asic3_write_register(asic, ASIC3_INTR_BASE + @@ -300,15 +300,15 @@ static void asic3_unmask_irq(struct irq_data *data) spin_unlock_irqrestore(&asic->lock, flags); } -static int asic3_gpio_irq_type(struct irq_data *data, unsigned int type) +static int asic3_gpio_irq_type(unsigned int irq, unsigned int type) { - struct asic3 *asic = irq_data_get_irq_chip_data(data); + struct asic3 *asic = get_irq_chip_data(irq); u32 bank, index; u16 trigger, level, edge, bit; unsigned long flags; - bank = asic3_irq_to_bank(asic, data->irq); - index = asic3_irq_to_index(asic, data->irq); + bank = asic3_irq_to_bank(asic, irq); + index = asic3_irq_to_index(asic, irq); bit = 1<lock, flags); @@ -318,7 +318,7 @@ static int asic3_gpio_irq_type(struct irq_data *data, unsigned int type) bank + ASIC3_GPIO_EDGE_TRIGGER); trigger = asic3_read_register(asic, bank + ASIC3_GPIO_TRIGGER_TYPE); - asic->irq_bothedge[(data->irq - asic->irq_base) >> 4] &= ~bit; + asic->irq_bothedge[(irq - asic->irq_base) >> 4] &= ~bit; if (type == IRQ_TYPE_EDGE_RISING) { trigger |= bit; @@ -328,11 +328,11 @@ static int asic3_gpio_irq_type(struct irq_data *data, unsigned int type) edge &= ~bit; } else if (type == IRQ_TYPE_EDGE_BOTH) { trigger |= bit; - if (asic3_gpio_get(&asic->gpio, data->irq - asic->irq_base)) + if (asic3_gpio_get(&asic->gpio, irq - asic->irq_base)) edge &= ~bit; else edge |= bit; - asic->irq_bothedge[(data->irq - asic->irq_base) >> 4] |= bit; + asic->irq_bothedge[(irq - asic->irq_base) >> 4] |= bit; } else if (type == IRQ_TYPE_LEVEL_LOW) { trigger &= ~bit; level &= ~bit; @@ -359,17 +359,17 @@ static int asic3_gpio_irq_type(struct irq_data *data, unsigned int type) static struct irq_chip asic3_gpio_irq_chip = { .name = "ASIC3-GPIO", - .irq_ack = asic3_mask_gpio_irq, - .irq_mask = asic3_mask_gpio_irq, - .irq_unmask = asic3_unmask_gpio_irq, - .irq_set_type = asic3_gpio_irq_type, + .ack = asic3_mask_gpio_irq, + .mask = asic3_mask_gpio_irq, + .unmask = asic3_unmask_gpio_irq, + .set_type = asic3_gpio_irq_type, }; static struct irq_chip asic3_irq_chip = { .name = "ASIC3", - .irq_ack = asic3_mask_irq, - .irq_mask = asic3_mask_irq, - .irq_unmask = asic3_unmask_irq, + .ack = asic3_mask_irq, + .mask = asic3_mask_irq, + .unmask = asic3_unmask_irq, }; static int __init asic3_irq_probe(struct platform_device *pdev) @@ -635,7 +635,7 @@ static struct resource ds1wm_resources[] = { }, { .start = ASIC3_IRQ_OWM, - .end = ASIC3_IRQ_OWM, + .start = ASIC3_IRQ_OWM, .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, }, }; diff --git a/trunk/drivers/mfd/cs5535-mfd.c b/trunk/drivers/mfd/cs5535-mfd.c deleted file mode 100644 index 59ca6f151e78..000000000000 --- a/trunk/drivers/mfd/cs5535-mfd.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * cs5535-mfd.c - core MFD driver for CS5535/CS5536 southbridges - * - * The CS5535 and CS5536 has an ISA bridge on the PCI bus that is - * used for accessing GPIOs, MFGPTs, ACPI, etc. Each subdevice has - * an IO range that's specified in a single BAR. The BAR order is - * hardcoded in the CS553x specifications. - * - * Copyright (c) 2010 Andres Salomon - * - * 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include - -#define DRV_NAME "cs5535-mfd" - -enum cs5535_mfd_bars { - SMB_BAR = 0, - GPIO_BAR = 1, - MFGPT_BAR = 2, - PMS_BAR = 4, - ACPI_BAR = 5, - NR_BARS, -}; - -static __devinitdata struct resource cs5535_mfd_resources[NR_BARS]; - -static __devinitdata struct mfd_cell cs5535_mfd_cells[] = { - { - .id = SMB_BAR, - .name = "cs5535-smb", - .num_resources = 1, - .resources = &cs5535_mfd_resources[SMB_BAR], - }, - { - .id = GPIO_BAR, - .name = "cs5535-gpio", - .num_resources = 1, - .resources = &cs5535_mfd_resources[GPIO_BAR], - }, - { - .id = MFGPT_BAR, - .name = "cs5535-mfgpt", - .num_resources = 1, - .resources = &cs5535_mfd_resources[MFGPT_BAR], - }, - { - .id = PMS_BAR, - .name = "cs5535-pms", - .num_resources = 1, - .resources = &cs5535_mfd_resources[PMS_BAR], - }, - { - .id = ACPI_BAR, - .name = "cs5535-acpi", - .num_resources = 1, - .resources = &cs5535_mfd_resources[ACPI_BAR], - }, -}; - -static int __devinit cs5535_mfd_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - int err, i; - - err = pci_enable_device(pdev); - if (err) - return err; - - /* fill in IO range for each cell; subdrivers handle the region */ - for (i = 0; i < ARRAY_SIZE(cs5535_mfd_cells); i++) { - int bar = cs5535_mfd_cells[i].id; - struct resource *r = &cs5535_mfd_resources[bar]; - - r->flags = IORESOURCE_IO; - r->start = pci_resource_start(pdev, bar); - r->end = pci_resource_end(pdev, bar); - - /* id is used for temporarily storing BAR; unset it now */ - cs5535_mfd_cells[i].id = 0; - } - - err = mfd_add_devices(&pdev->dev, -1, cs5535_mfd_cells, - ARRAY_SIZE(cs5535_mfd_cells), NULL, 0); - if (err) { - dev_err(&pdev->dev, "MFD add devices failed: %d\n", err); - goto err_disable; - } - - dev_info(&pdev->dev, "%zu devices registered.\n", - ARRAY_SIZE(cs5535_mfd_cells)); - - return 0; - -err_disable: - pci_disable_device(pdev); - return err; -} - -static void __devexit cs5535_mfd_remove(struct pci_dev *pdev) -{ - mfd_remove_devices(&pdev->dev); - pci_disable_device(pdev); -} - -static struct pci_device_id cs5535_mfd_pci_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, - { 0, } -}; -MODULE_DEVICE_TABLE(pci, cs5535_mfd_pci_tbl); - -static struct pci_driver cs5535_mfd_drv = { - .name = DRV_NAME, - .id_table = cs5535_mfd_pci_tbl, - .probe = cs5535_mfd_probe, - .remove = __devexit_p(cs5535_mfd_remove), -}; - -static int __init cs5535_mfd_init(void) -{ - return pci_register_driver(&cs5535_mfd_drv); -} - -static void __exit cs5535_mfd_exit(void) -{ - pci_unregister_driver(&cs5535_mfd_drv); -} - -module_init(cs5535_mfd_init); -module_exit(cs5535_mfd_exit); - -MODULE_AUTHOR("Andres Salomon "); -MODULE_DESCRIPTION("MFD driver for CS5535/CS5536 southbridge's ISA PCI device"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/mfd/ezx-pcap.c b/trunk/drivers/mfd/ezx-pcap.c index 9e2d8dd5f9e5..c2b698d69a93 100644 --- a/trunk/drivers/mfd/ezx-pcap.c +++ b/trunk/drivers/mfd/ezx-pcap.c @@ -144,26 +144,26 @@ int pcap_to_irq(struct pcap_chip *pcap, int irq) } EXPORT_SYMBOL_GPL(pcap_to_irq); -static void pcap_mask_irq(struct irq_data *d) +static void pcap_mask_irq(unsigned int irq) { - struct pcap_chip *pcap = irq_data_get_irq_chip_data(d); + struct pcap_chip *pcap = get_irq_chip_data(irq); - pcap->msr |= 1 << irq_to_pcap(pcap, d->irq); + pcap->msr |= 1 << irq_to_pcap(pcap, irq); queue_work(pcap->workqueue, &pcap->msr_work); } -static void pcap_unmask_irq(struct irq_data *d) +static void pcap_unmask_irq(unsigned int irq) { - struct pcap_chip *pcap = irq_data_get_irq_chip_data(d); + struct pcap_chip *pcap = get_irq_chip_data(irq); - pcap->msr &= ~(1 << irq_to_pcap(pcap, d->irq)); + pcap->msr &= ~(1 << irq_to_pcap(pcap, irq)); queue_work(pcap->workqueue, &pcap->msr_work); } static struct irq_chip pcap_irq_chip = { - .name = "pcap", - .irq_mask = pcap_mask_irq, - .irq_unmask = pcap_unmask_irq, + .name = "pcap", + .mask = pcap_mask_irq, + .unmask = pcap_unmask_irq, }; static void pcap_msr_work(struct work_struct *work) @@ -199,7 +199,8 @@ static void pcap_isr_work(struct work_struct *work) if (service & 1) { struct irq_desc *desc = irq_to_desc(irq); - if (WARN(!desc, "Invalid PCAP IRQ %d\n", irq)) + if (WARN(!desc, KERN_WARNING + "Invalid PCAP IRQ %d\n", irq)) break; if (desc->status & IRQ_DISABLED) @@ -217,7 +218,7 @@ static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc) { struct pcap_chip *pcap = get_irq_data(irq); - desc->irq_data.chip->irq_ack(&desc->irq_data); + desc->chip->ack(irq); queue_work(pcap->workqueue, &pcap->isr_work); return; } @@ -281,7 +282,7 @@ static irqreturn_t pcap_adc_irq(int irq, void *_pcap) mutex_lock(&pcap->adc_mutex); req = pcap->adc_queue[pcap->adc_head]; - if (WARN(!req, "adc irq without pending request\n")) { + if (WARN(!req, KERN_WARNING "adc irq without pending request\n")) { mutex_unlock(&pcap->adc_mutex); return IRQ_HANDLED; } diff --git a/trunk/drivers/mfd/htc-egpio.c b/trunk/drivers/mfd/htc-egpio.c index d00b6d1a69e5..d3e74f8585e0 100644 --- a/trunk/drivers/mfd/htc-egpio.c +++ b/trunk/drivers/mfd/htc-egpio.c @@ -70,32 +70,31 @@ static inline void ack_irqs(struct egpio_info *ei) ei->ack_write, ei->ack_register << ei->bus_shift); } -static void egpio_ack(struct irq_data *data) +static void egpio_ack(unsigned int irq) { } /* There does not appear to be a way to proactively mask interrupts * on the egpio chip itself. So, we simply ignore interrupts that * aren't desired. */ -static void egpio_mask(struct irq_data *data) +static void egpio_mask(unsigned int irq) { - struct egpio_info *ei = irq_data_get_irq_chip_data(data); - ei->irqs_enabled &= ~(1 << (data->irq - ei->irq_start)); - pr_debug("EGPIO mask %d %04x\n", data->irq, ei->irqs_enabled); + struct egpio_info *ei = get_irq_chip_data(irq); + ei->irqs_enabled &= ~(1 << (irq - ei->irq_start)); + pr_debug("EGPIO mask %d %04x\n", irq, ei->irqs_enabled); } - -static void egpio_unmask(struct irq_data *data) +static void egpio_unmask(unsigned int irq) { - struct egpio_info *ei = irq_data_get_irq_chip_data(data); - ei->irqs_enabled |= 1 << (data->irq - ei->irq_start); - pr_debug("EGPIO unmask %d %04x\n", data->irq, ei->irqs_enabled); + struct egpio_info *ei = get_irq_chip_data(irq); + ei->irqs_enabled |= 1 << (irq - ei->irq_start); + pr_debug("EGPIO unmask %d %04x\n", irq, ei->irqs_enabled); } static struct irq_chip egpio_muxed_chip = { - .name = "htc-egpio", - .irq_ack = egpio_ack, - .irq_mask = egpio_mask, - .irq_unmask = egpio_unmask, + .name = "htc-egpio", + .ack = egpio_ack, + .mask = egpio_mask, + .unmask = egpio_unmask, }; static void egpio_handler(unsigned int irq, struct irq_desc *desc) diff --git a/trunk/drivers/mfd/htc-i2cpld.c b/trunk/drivers/mfd/htc-i2cpld.c index 296ad1562f69..594c9a8e25e1 100644 --- a/trunk/drivers/mfd/htc-i2cpld.c +++ b/trunk/drivers/mfd/htc-i2cpld.c @@ -82,25 +82,25 @@ struct htcpld_data { /* There does not appear to be a way to proactively mask interrupts * on the htcpld chip itself. So, we simply ignore interrupts that * aren't desired. */ -static void htcpld_mask(struct irq_data *data) +static void htcpld_mask(unsigned int irq) { - struct htcpld_chip *chip = irq_data_get_irq_chip_data(data); - chip->irqs_enabled &= ~(1 << (data->irq - chip->irq_start)); - pr_debug("HTCPLD mask %d %04x\n", data->irq, chip->irqs_enabled); + struct htcpld_chip *chip = get_irq_chip_data(irq); + chip->irqs_enabled &= ~(1 << (irq - chip->irq_start)); + pr_debug("HTCPLD mask %d %04x\n", irq, chip->irqs_enabled); } -static void htcpld_unmask(struct irq_data *data) +static void htcpld_unmask(unsigned int irq) { - struct htcpld_chip *chip = irq_data_get_irq_chip_data(data); - chip->irqs_enabled |= 1 << (data->irq - chip->irq_start); - pr_debug("HTCPLD unmask %d %04x\n", data->irq, chip->irqs_enabled); + struct htcpld_chip *chip = get_irq_chip_data(irq); + chip->irqs_enabled |= 1 << (irq - chip->irq_start); + pr_debug("HTCPLD unmask %d %04x\n", irq, chip->irqs_enabled); } -static int htcpld_set_type(struct irq_data *data, unsigned int flags) +static int htcpld_set_type(unsigned int irq, unsigned int flags) { - struct irq_desc *d = irq_to_desc(data->irq); + struct irq_desc *d = irq_to_desc(irq); if (!d) { - pr_err("HTCPLD invalid IRQ: %d\n", data->irq); + pr_err("HTCPLD invalid IRQ: %d\n", irq); return -EINVAL; } @@ -118,10 +118,10 @@ static int htcpld_set_type(struct irq_data *data, unsigned int flags) } static struct irq_chip htcpld_muxed_chip = { - .name = "htcpld", - .irq_mask = htcpld_mask, - .irq_unmask = htcpld_unmask, - .irq_set_type = htcpld_set_type, + .name = "htcpld", + .mask = htcpld_mask, + .unmask = htcpld_unmask, + .set_type = htcpld_set_type, }; /* To properly dispatch IRQ events, we need to read from the @@ -235,7 +235,7 @@ static irqreturn_t htcpld_handler(int irq, void *dev) * and that work is scheduled in the set routine. The kernel can then run * the I2C functions, which will sleep, in process context. */ -static void htcpld_chip_set(struct gpio_chip *chip, unsigned offset, int val) +void htcpld_chip_set(struct gpio_chip *chip, unsigned offset, int val) { struct i2c_client *client; struct htcpld_chip *chip_data; @@ -259,7 +259,7 @@ static void htcpld_chip_set(struct gpio_chip *chip, unsigned offset, int val) schedule_work(&(chip_data->set_val_work)); } -static void htcpld_chip_set_ni(struct work_struct *work) +void htcpld_chip_set_ni(struct work_struct *work) { struct htcpld_chip *chip_data; struct i2c_client *client; @@ -269,7 +269,7 @@ static void htcpld_chip_set_ni(struct work_struct *work) i2c_smbus_read_byte_data(client, chip_data->cache_out); } -static int htcpld_chip_get(struct gpio_chip *chip, unsigned offset) +int htcpld_chip_get(struct gpio_chip *chip, unsigned offset) { struct htcpld_chip *chip_data; int val = 0; @@ -316,7 +316,7 @@ static int htcpld_direction_input(struct gpio_chip *chip, return (offset < chip->ngpio) ? 0 : -EINVAL; } -static int htcpld_chip_to_irq(struct gpio_chip *chip, unsigned offset) +int htcpld_chip_to_irq(struct gpio_chip *chip, unsigned offset) { struct htcpld_chip *chip_data; @@ -328,7 +328,7 @@ static int htcpld_chip_to_irq(struct gpio_chip *chip, unsigned offset) return -EINVAL; } -static void htcpld_chip_reset(struct i2c_client *client) +void htcpld_chip_reset(struct i2c_client *client) { struct htcpld_chip *chip_data = i2c_get_clientdata(client); if (!chip_data) diff --git a/trunk/drivers/mfd/jz4740-adc.c b/trunk/drivers/mfd/jz4740-adc.c index 0cc59795f600..9dd1b33f2275 100644 --- a/trunk/drivers/mfd/jz4740-adc.c +++ b/trunk/drivers/mfd/jz4740-adc.c @@ -84,30 +84,31 @@ static inline void jz4740_adc_irq_set_masked(struct jz4740_adc *adc, int irq, spin_unlock_irqrestore(&adc->lock, flags); } -static void jz4740_adc_irq_mask(struct irq_data *data) +static void jz4740_adc_irq_mask(unsigned int irq) { - struct jz4740_adc *adc = irq_data_get_irq_chip_data(data); - jz4740_adc_irq_set_masked(adc, data->irq, true); + struct jz4740_adc *adc = get_irq_chip_data(irq); + jz4740_adc_irq_set_masked(adc, irq, true); } -static void jz4740_adc_irq_unmask(struct irq_data *data) +static void jz4740_adc_irq_unmask(unsigned int irq) { - struct jz4740_adc *adc = irq_data_get_irq_chip_data(data); - jz4740_adc_irq_set_masked(adc, data->irq, false); + struct jz4740_adc *adc = get_irq_chip_data(irq); + jz4740_adc_irq_set_masked(adc, irq, false); } -static void jz4740_adc_irq_ack(struct irq_data *data) +static void jz4740_adc_irq_ack(unsigned int irq) { - struct jz4740_adc *adc = irq_data_get_irq_chip_data(data); - unsigned int irq = data->irq - adc->irq_base; + struct jz4740_adc *adc = get_irq_chip_data(irq); + + irq -= adc->irq_base; writeb(BIT(irq), adc->base + JZ_REG_ADC_STATUS); } static struct irq_chip jz4740_adc_irq_chip = { .name = "jz4740-adc", - .irq_mask = jz4740_adc_irq_mask, - .irq_unmask = jz4740_adc_irq_unmask, - .irq_ack = jz4740_adc_irq_ack, + .mask = jz4740_adc_irq_mask, + .unmask = jz4740_adc_irq_unmask, + .ack = jz4740_adc_irq_ack, }; static void jz4740_adc_irq_demux(unsigned int irq, struct irq_desc *desc) diff --git a/trunk/drivers/mfd/max8925-core.c b/trunk/drivers/mfd/max8925-core.c index 0e998dc4e7d8..44695f5a1800 100644 --- a/trunk/drivers/mfd/max8925-core.c +++ b/trunk/drivers/mfd/max8925-core.c @@ -407,16 +407,16 @@ static irqreturn_t max8925_tsc_irq(int irq, void *data) return IRQ_HANDLED; } -static void max8925_irq_lock(struct irq_data *data) +static void max8925_irq_lock(unsigned int irq) { - struct max8925_chip *chip = irq_data_get_irq_chip_data(data); + struct max8925_chip *chip = get_irq_chip_data(irq); mutex_lock(&chip->irq_lock); } -static void max8925_irq_sync_unlock(struct irq_data *data) +static void max8925_irq_sync_unlock(unsigned int irq) { - struct max8925_chip *chip = irq_data_get_irq_chip_data(data); + struct max8925_chip *chip = get_irq_chip_data(irq); struct max8925_irq_data *irq_data; static unsigned char cache_chg[2] = {0xff, 0xff}; static unsigned char cache_on[2] = {0xff, 0xff}; @@ -492,25 +492,25 @@ static void max8925_irq_sync_unlock(struct irq_data *data) mutex_unlock(&chip->irq_lock); } -static void max8925_irq_enable(struct irq_data *data) +static void max8925_irq_enable(unsigned int irq) { - struct max8925_chip *chip = irq_data_get_irq_chip_data(data); - max8925_irqs[data->irq - chip->irq_base].enable - = max8925_irqs[data->irq - chip->irq_base].offs; + struct max8925_chip *chip = get_irq_chip_data(irq); + max8925_irqs[irq - chip->irq_base].enable + = max8925_irqs[irq - chip->irq_base].offs; } -static void max8925_irq_disable(struct irq_data *data) +static void max8925_irq_disable(unsigned int irq) { - struct max8925_chip *chip = irq_data_get_irq_chip_data(data); - max8925_irqs[data->irq - chip->irq_base].enable = 0; + struct max8925_chip *chip = get_irq_chip_data(irq); + max8925_irqs[irq - chip->irq_base].enable = 0; } static struct irq_chip max8925_irq_chip = { .name = "max8925", - .irq_bus_lock = max8925_irq_lock, - .irq_bus_sync_unlock = max8925_irq_sync_unlock, - .irq_enable = max8925_irq_enable, - .irq_disable = max8925_irq_disable, + .bus_lock = max8925_irq_lock, + .bus_sync_unlock = max8925_irq_sync_unlock, + .enable = max8925_irq_enable, + .disable = max8925_irq_disable, }; static int max8925_irq_init(struct max8925_chip *chip, int irq, diff --git a/trunk/drivers/mfd/max8998-irq.c b/trunk/drivers/mfd/max8998-irq.c index 3903e1fbb334..45bfe77b639b 100644 --- a/trunk/drivers/mfd/max8998-irq.c +++ b/trunk/drivers/mfd/max8998-irq.c @@ -102,16 +102,16 @@ irq_to_max8998_irq(struct max8998_dev *max8998, int irq) return &max8998_irqs[irq - max8998->irq_base]; } -static void max8998_irq_lock(struct irq_data *data) +static void max8998_irq_lock(unsigned int irq) { - struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data); + struct max8998_dev *max8998 = get_irq_chip_data(irq); mutex_lock(&max8998->irqlock); } -static void max8998_irq_sync_unlock(struct irq_data *data) +static void max8998_irq_sync_unlock(unsigned int irq) { - struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data); + struct max8998_dev *max8998 = get_irq_chip_data(irq); int i; for (i = 0; i < ARRAY_SIZE(max8998->irq_masks_cur); i++) { @@ -129,30 +129,28 @@ static void max8998_irq_sync_unlock(struct irq_data *data) mutex_unlock(&max8998->irqlock); } -static void max8998_irq_unmask(struct irq_data *data) +static void max8998_irq_unmask(unsigned int irq) { - struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data); - struct max8998_irq_data *irq_data = irq_to_max8998_irq(max8998, - data->irq); + struct max8998_dev *max8998 = get_irq_chip_data(irq); + struct max8998_irq_data *irq_data = irq_to_max8998_irq(max8998, irq); max8998->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; } -static void max8998_irq_mask(struct irq_data *data) +static void max8998_irq_mask(unsigned int irq) { - struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data); - struct max8998_irq_data *irq_data = irq_to_max8998_irq(max8998, - data->irq); + struct max8998_dev *max8998 = get_irq_chip_data(irq); + struct max8998_irq_data *irq_data = irq_to_max8998_irq(max8998, irq); max8998->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; } static struct irq_chip max8998_irq_chip = { .name = "max8998", - .irq_bus_lock = max8998_irq_lock, - .irq_bus_sync_unlock = max8998_irq_sync_unlock, - .irq_mask = max8998_irq_mask, - .irq_unmask = max8998_irq_unmask, + .bus_lock = max8998_irq_lock, + .bus_sync_unlock = max8998_irq_sync_unlock, + .mask = max8998_irq_mask, + .unmask = max8998_irq_unmask, }; static irqreturn_t max8998_irq_thread(int irq, void *data) @@ -183,13 +181,6 @@ static irqreturn_t max8998_irq_thread(int irq, void *data) return IRQ_HANDLED; } -int max8998_irq_resume(struct max8998_dev *max8998) -{ - if (max8998->irq && max8998->irq_base) - max8998_irq_thread(max8998->irq_base, max8998); - return 0; -} - int max8998_irq_init(struct max8998_dev *max8998) { int i; diff --git a/trunk/drivers/mfd/max8998.c b/trunk/drivers/mfd/max8998.c index bbfe86732602..bb9977bebe78 100644 --- a/trunk/drivers/mfd/max8998.c +++ b/trunk/drivers/mfd/max8998.c @@ -25,8 +25,6 @@ #include #include #include -#include -#include #include #include #include @@ -42,14 +40,6 @@ static struct mfd_cell max8998_devs[] = { }, }; -static struct mfd_cell lp3974_devs[] = { - { - .name = "lp3974-pmic", - }, { - .name = "lp3974-rtc", - }, -}; - int max8998_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest) { struct max8998_dev *max8998 = i2c_get_clientdata(i2c); @@ -145,7 +135,6 @@ static int max8998_i2c_probe(struct i2c_client *i2c, if (pdata) { max8998->ono = pdata->ono; max8998->irq_base = pdata->irq_base; - max8998->wakeup = pdata->wakeup; } mutex_init(&max8998->iolock); @@ -154,23 +143,9 @@ static int max8998_i2c_probe(struct i2c_client *i2c, max8998_irq_init(max8998); - pm_runtime_set_active(max8998->dev); - - switch (id->driver_data) { - case TYPE_LP3974: - ret = mfd_add_devices(max8998->dev, -1, - lp3974_devs, ARRAY_SIZE(lp3974_devs), - NULL, 0); - break; - case TYPE_MAX8998: - ret = mfd_add_devices(max8998->dev, -1, - max8998_devs, ARRAY_SIZE(max8998_devs), - NULL, 0); - break; - default: - ret = -EINVAL; - } - + ret = mfd_add_devices(max8998->dev, -1, + max8998_devs, ARRAY_SIZE(max8998_devs), + NULL, 0); if (ret < 0) goto err; @@ -203,113 +178,10 @@ static const struct i2c_device_id max8998_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, max8998_i2c_id); -static int max8998_suspend(struct device *dev) -{ - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); - struct max8998_dev *max8998 = i2c_get_clientdata(i2c); - - if (max8998->wakeup) - set_irq_wake(max8998->irq, 1); - return 0; -} - -static int max8998_resume(struct device *dev) -{ - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); - struct max8998_dev *max8998 = i2c_get_clientdata(i2c); - - if (max8998->wakeup) - set_irq_wake(max8998->irq, 0); - /* - * In LP3974, if IRQ registers are not "read & clear" - * when it's set during sleep, the interrupt becomes - * disabled. - */ - return max8998_irq_resume(i2c_get_clientdata(i2c)); -} - -struct max8998_reg_dump { - u8 addr; - u8 val; -}; -#define SAVE_ITEM(x) { .addr = (x), .val = 0x0, } -struct max8998_reg_dump max8998_dump[] = { - SAVE_ITEM(MAX8998_REG_IRQM1), - SAVE_ITEM(MAX8998_REG_IRQM2), - SAVE_ITEM(MAX8998_REG_IRQM3), - SAVE_ITEM(MAX8998_REG_IRQM4), - SAVE_ITEM(MAX8998_REG_STATUSM1), - SAVE_ITEM(MAX8998_REG_STATUSM2), - SAVE_ITEM(MAX8998_REG_CHGR1), - SAVE_ITEM(MAX8998_REG_CHGR2), - SAVE_ITEM(MAX8998_REG_LDO_ACTIVE_DISCHARGE1), - SAVE_ITEM(MAX8998_REG_LDO_ACTIVE_DISCHARGE1), - SAVE_ITEM(MAX8998_REG_BUCK_ACTIVE_DISCHARGE3), - SAVE_ITEM(MAX8998_REG_ONOFF1), - SAVE_ITEM(MAX8998_REG_ONOFF2), - SAVE_ITEM(MAX8998_REG_ONOFF3), - SAVE_ITEM(MAX8998_REG_ONOFF4), - SAVE_ITEM(MAX8998_REG_BUCK1_VOLTAGE1), - SAVE_ITEM(MAX8998_REG_BUCK1_VOLTAGE2), - SAVE_ITEM(MAX8998_REG_BUCK1_VOLTAGE3), - SAVE_ITEM(MAX8998_REG_BUCK1_VOLTAGE4), - SAVE_ITEM(MAX8998_REG_BUCK2_VOLTAGE1), - SAVE_ITEM(MAX8998_REG_BUCK2_VOLTAGE2), - SAVE_ITEM(MAX8998_REG_LDO2_LDO3), - SAVE_ITEM(MAX8998_REG_LDO4), - SAVE_ITEM(MAX8998_REG_LDO5), - SAVE_ITEM(MAX8998_REG_LDO6), - SAVE_ITEM(MAX8998_REG_LDO7), - SAVE_ITEM(MAX8998_REG_LDO8_LDO9), - SAVE_ITEM(MAX8998_REG_LDO10_LDO11), - SAVE_ITEM(MAX8998_REG_LDO12), - SAVE_ITEM(MAX8998_REG_LDO13), - SAVE_ITEM(MAX8998_REG_LDO14), - SAVE_ITEM(MAX8998_REG_LDO15), - SAVE_ITEM(MAX8998_REG_LDO16), - SAVE_ITEM(MAX8998_REG_LDO17), - SAVE_ITEM(MAX8998_REG_BKCHR), - SAVE_ITEM(MAX8998_REG_LBCNFG1), - SAVE_ITEM(MAX8998_REG_LBCNFG2), -}; -/* Save registers before hibernation */ -static int max8998_freeze(struct device *dev) -{ - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); - int i; - - for (i = 0; i < ARRAY_SIZE(max8998_dump); i++) - max8998_read_reg(i2c, max8998_dump[i].addr, - &max8998_dump[i].val); - - return 0; -} - -/* Restore registers after hibernation */ -static int max8998_restore(struct device *dev) -{ - struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); - int i; - - for (i = 0; i < ARRAY_SIZE(max8998_dump); i++) - max8998_write_reg(i2c, max8998_dump[i].addr, - max8998_dump[i].val); - - return 0; -} - -const struct dev_pm_ops max8998_pm = { - .suspend = max8998_suspend, - .resume = max8998_resume, - .freeze = max8998_freeze, - .restore = max8998_restore, -}; - static struct i2c_driver max8998_i2c_driver = { .driver = { .name = "max8998", .owner = THIS_MODULE, - .pm = &max8998_pm, }, .probe = max8998_i2c_probe, .remove = max8998_i2c_remove, diff --git a/trunk/drivers/mfd/mc13xxx-core.c b/trunk/drivers/mfd/mc13xxx-core.c index b9fcaf0004da..a2ac2ed6d64c 100644 --- a/trunk/drivers/mfd/mc13xxx-core.c +++ b/trunk/drivers/mfd/mc13xxx-core.c @@ -749,7 +749,7 @@ static int mc13xxx_probe(struct spi_device *spi) if (ret) { err_mask: err_revision: - mc13xxx_unlock(mc13xxx); + mutex_unlock(&mc13xxx->lock); dev_set_drvdata(&spi->dev, NULL); kfree(mc13xxx); return ret; diff --git a/trunk/drivers/mfd/mfd-core.c b/trunk/drivers/mfd/mfd-core.c index d83ad0f141af..ec99f681e773 100644 --- a/trunk/drivers/mfd/mfd-core.c +++ b/trunk/drivers/mfd/mfd-core.c @@ -15,7 +15,6 @@ #include #include #include -#include #include static int mfd_add_device(struct device *parent, int id, @@ -83,9 +82,6 @@ static int mfd_add_device(struct device *parent, int id, if (ret) goto fail_res; - if (cell->pm_runtime_no_callbacks) - pm_runtime_no_callbacks(&pdev->dev); - kfree(res); return 0; diff --git a/trunk/drivers/mfd/sm501.c b/trunk/drivers/mfd/sm501.c index 5de3a760ea1e..bc9275c12133 100644 --- a/trunk/drivers/mfd/sm501.c +++ b/trunk/drivers/mfd/sm501.c @@ -26,7 +26,7 @@ #include #include -#include +#include struct sm501_device { struct list_head list; @@ -745,8 +745,11 @@ static int sm501_register_device(struct sm501_devdata *sm, int ret; for (ptr = 0; ptr < pdev->num_resources; ptr++) { - printk(KERN_DEBUG "%s[%d] %pR\n", - pdev->name, ptr, &pdev->resource[ptr]); + printk(KERN_DEBUG "%s[%d] flags %08lx: %08llx..%08llx\n", + pdev->name, ptr, + pdev->resource[ptr].flags, + (unsigned long long)pdev->resource[ptr].start, + (unsigned long long)pdev->resource[ptr].end); } ret = platform_device_register(pdev); diff --git a/trunk/drivers/mfd/stmpe.c b/trunk/drivers/mfd/stmpe.c index 3e5732b58c49..b11487f1e1cb 100644 --- a/trunk/drivers/mfd/stmpe.c +++ b/trunk/drivers/mfd/stmpe.c @@ -699,16 +699,16 @@ static irqreturn_t stmpe_irq(int irq, void *data) return IRQ_HANDLED; } -static void stmpe_irq_lock(struct irq_data *data) +static void stmpe_irq_lock(unsigned int irq) { - struct stmpe *stmpe = irq_data_get_irq_chip_data(data); + struct stmpe *stmpe = get_irq_chip_data(irq); mutex_lock(&stmpe->irq_lock); } -static void stmpe_irq_sync_unlock(struct irq_data *data) +static void stmpe_irq_sync_unlock(unsigned int irq) { - struct stmpe *stmpe = irq_data_get_irq_chip_data(data); + struct stmpe *stmpe = get_irq_chip_data(irq); struct stmpe_variant_info *variant = stmpe->variant; int num = DIV_ROUND_UP(variant->num_irqs, 8); int i; @@ -727,20 +727,20 @@ static void stmpe_irq_sync_unlock(struct irq_data *data) mutex_unlock(&stmpe->irq_lock); } -static void stmpe_irq_mask(struct irq_data *data) +static void stmpe_irq_mask(unsigned int irq) { - struct stmpe *stmpe = irq_data_get_irq_chip_data(data); - int offset = data->irq - stmpe->irq_base; + struct stmpe *stmpe = get_irq_chip_data(irq); + int offset = irq - stmpe->irq_base; int regoffset = offset / 8; int mask = 1 << (offset % 8); stmpe->ier[regoffset] &= ~mask; } -static void stmpe_irq_unmask(struct irq_data *data) +static void stmpe_irq_unmask(unsigned int irq) { - struct stmpe *stmpe = irq_data_get_irq_chip_data(data); - int offset = data->irq - stmpe->irq_base; + struct stmpe *stmpe = get_irq_chip_data(irq); + int offset = irq - stmpe->irq_base; int regoffset = offset / 8; int mask = 1 << (offset % 8); @@ -749,10 +749,10 @@ static void stmpe_irq_unmask(struct irq_data *data) static struct irq_chip stmpe_irq_chip = { .name = "stmpe", - .irq_bus_lock = stmpe_irq_lock, - .irq_bus_sync_unlock = stmpe_irq_sync_unlock, - .irq_mask = stmpe_irq_mask, - .irq_unmask = stmpe_irq_unmask, + .bus_lock = stmpe_irq_lock, + .bus_sync_unlock = stmpe_irq_sync_unlock, + .mask = stmpe_irq_mask, + .unmask = stmpe_irq_unmask, }; static int __devinit stmpe_irq_init(struct stmpe *stmpe) diff --git a/trunk/drivers/mfd/t7l66xb.c b/trunk/drivers/mfd/t7l66xb.c index 9caeb4ac6ea6..006c121f3f0d 100644 --- a/trunk/drivers/mfd/t7l66xb.c +++ b/trunk/drivers/mfd/t7l66xb.c @@ -199,37 +199,37 @@ static void t7l66xb_irq(unsigned int irq, struct irq_desc *desc) generic_handle_irq(irq_base + i); } -static void t7l66xb_irq_mask(struct irq_data *data) +static void t7l66xb_irq_mask(unsigned int irq) { - struct t7l66xb *t7l66xb = irq_data_get_irq_chip_data(data); + struct t7l66xb *t7l66xb = get_irq_chip_data(irq); unsigned long flags; u8 imr; spin_lock_irqsave(&t7l66xb->lock, flags); imr = tmio_ioread8(t7l66xb->scr + SCR_IMR); - imr |= 1 << (data->irq - t7l66xb->irq_base); + imr |= 1 << (irq - t7l66xb->irq_base); tmio_iowrite8(imr, t7l66xb->scr + SCR_IMR); spin_unlock_irqrestore(&t7l66xb->lock, flags); } -static void t7l66xb_irq_unmask(struct irq_data *data) +static void t7l66xb_irq_unmask(unsigned int irq) { - struct t7l66xb *t7l66xb = irq_data_get_irq_chip_data(data); + struct t7l66xb *t7l66xb = get_irq_chip_data(irq); unsigned long flags; u8 imr; spin_lock_irqsave(&t7l66xb->lock, flags); imr = tmio_ioread8(t7l66xb->scr + SCR_IMR); - imr &= ~(1 << (data->irq - t7l66xb->irq_base)); + imr &= ~(1 << (irq - t7l66xb->irq_base)); tmio_iowrite8(imr, t7l66xb->scr + SCR_IMR); spin_unlock_irqrestore(&t7l66xb->lock, flags); } static struct irq_chip t7l66xb_chip = { - .name = "t7l66xb", - .irq_ack = t7l66xb_irq_mask, - .irq_mask = t7l66xb_irq_mask, - .irq_unmask = t7l66xb_irq_unmask, + .name = "t7l66xb", + .ack = t7l66xb_irq_mask, + .mask = t7l66xb_irq_mask, + .unmask = t7l66xb_irq_unmask, }; /*--------------------------------------------------------------------------*/ diff --git a/trunk/drivers/mfd/tc6393xb.c b/trunk/drivers/mfd/tc6393xb.c index 9a238633a54d..1ea80d8ad915 100644 --- a/trunk/drivers/mfd/tc6393xb.c +++ b/trunk/drivers/mfd/tc6393xb.c @@ -527,41 +527,41 @@ tc6393xb_irq(unsigned int irq, struct irq_desc *desc) } } -static void tc6393xb_irq_ack(struct irq_data *data) +static void tc6393xb_irq_ack(unsigned int irq) { } -static void tc6393xb_irq_mask(struct irq_data *data) +static void tc6393xb_irq_mask(unsigned int irq) { - struct tc6393xb *tc6393xb = irq_data_get_irq_chip_data(data); + struct tc6393xb *tc6393xb = get_irq_chip_data(irq); unsigned long flags; u8 imr; spin_lock_irqsave(&tc6393xb->lock, flags); imr = tmio_ioread8(tc6393xb->scr + SCR_IMR); - imr |= 1 << (data->irq - tc6393xb->irq_base); + imr |= 1 << (irq - tc6393xb->irq_base); tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR); spin_unlock_irqrestore(&tc6393xb->lock, flags); } -static void tc6393xb_irq_unmask(struct irq_data *data) +static void tc6393xb_irq_unmask(unsigned int irq) { - struct tc6393xb *tc6393xb = irq_data_get_irq_chip_data(data); + struct tc6393xb *tc6393xb = get_irq_chip_data(irq); unsigned long flags; u8 imr; spin_lock_irqsave(&tc6393xb->lock, flags); imr = tmio_ioread8(tc6393xb->scr + SCR_IMR); - imr &= ~(1 << (data->irq - tc6393xb->irq_base)); + imr &= ~(1 << (irq - tc6393xb->irq_base)); tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR); spin_unlock_irqrestore(&tc6393xb->lock, flags); } static struct irq_chip tc6393xb_chip = { - .name = "tc6393xb", - .irq_ack = tc6393xb_irq_ack, - .irq_mask = tc6393xb_irq_mask, - .irq_unmask = tc6393xb_irq_unmask, + .name = "tc6393xb", + .ack = tc6393xb_irq_ack, + .mask = tc6393xb_irq_mask, + .unmask = tc6393xb_irq_unmask, }; static void tc6393xb_attach_irq(struct platform_device *dev) diff --git a/trunk/drivers/mfd/tps65010.c b/trunk/drivers/mfd/tps65010.c index 93d5fdf020c7..90187fe33e04 100644 --- a/trunk/drivers/mfd/tps65010.c +++ b/trunk/drivers/mfd/tps65010.c @@ -34,7 +34,7 @@ #include -#include +#include /*-------------------------------------------------------------------------*/ diff --git a/trunk/drivers/mfd/tps6586x.c b/trunk/drivers/mfd/tps6586x.c index 627cf577b16d..b4931ab34929 100644 --- a/trunk/drivers/mfd/tps6586x.c +++ b/trunk/drivers/mfd/tps6586x.c @@ -46,6 +46,8 @@ /* device id */ #define TPS6586X_VERSIONCRC 0xcd +#define TPS658621A_VERSIONCRC 0x15 +#define TPS658621C_VERSIONCRC 0x2c struct tps6586x_irq_data { u8 mask_reg; @@ -323,37 +325,37 @@ static int tps6586x_remove_subdevs(struct tps6586x *tps6586x) return device_for_each_child(tps6586x->dev, NULL, __remove_subdev); } -static void tps6586x_irq_lock(struct irq_data *data) +static void tps6586x_irq_lock(unsigned int irq) { - struct tps6586x *tps6586x = irq_data_get_irq_chip_data(data); + struct tps6586x *tps6586x = get_irq_chip_data(irq); mutex_lock(&tps6586x->irq_lock); } -static void tps6586x_irq_enable(struct irq_data *irq_data) +static void tps6586x_irq_enable(unsigned int irq) { - struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data); - unsigned int __irq = irq_data->irq - tps6586x->irq_base; + struct tps6586x *tps6586x = get_irq_chip_data(irq); + unsigned int __irq = irq - tps6586x->irq_base; const struct tps6586x_irq_data *data = &tps6586x_irqs[__irq]; tps6586x->mask_reg[data->mask_reg] &= ~data->mask_mask; tps6586x->irq_en |= (1 << __irq); } -static void tps6586x_irq_disable(struct irq_data *irq_data) +static void tps6586x_irq_disable(unsigned int irq) { - struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data); + struct tps6586x *tps6586x = get_irq_chip_data(irq); - unsigned int __irq = irq_data->irq - tps6586x->irq_base; + unsigned int __irq = irq - tps6586x->irq_base; const struct tps6586x_irq_data *data = &tps6586x_irqs[__irq]; tps6586x->mask_reg[data->mask_reg] |= data->mask_mask; tps6586x->irq_en &= ~(1 << __irq); } -static void tps6586x_irq_sync_unlock(struct irq_data *data) +static void tps6586x_irq_sync_unlock(unsigned int irq) { - struct tps6586x *tps6586x = irq_data_get_irq_chip_data(data); + struct tps6586x *tps6586x = get_irq_chip_data(irq); int i; for (i = 0; i < ARRAY_SIZE(tps6586x->mask_reg); i++) { @@ -419,10 +421,10 @@ static int __devinit tps6586x_irq_init(struct tps6586x *tps6586x, int irq, tps6586x->irq_base = irq_base; tps6586x->irq_chip.name = "tps6586x"; - tps6586x->irq_chip.irq_enable = tps6586x_irq_enable; - tps6586x->irq_chip.irq_disable = tps6586x_irq_disable; - tps6586x->irq_chip.irq_bus_lock = tps6586x_irq_lock; - tps6586x->irq_chip.irq_bus_sync_unlock = tps6586x_irq_sync_unlock; + tps6586x->irq_chip.enable = tps6586x_irq_enable; + tps6586x->irq_chip.disable = tps6586x_irq_disable; + tps6586x->irq_chip.bus_lock = tps6586x_irq_lock; + tps6586x->irq_chip.bus_sync_unlock = tps6586x_irq_sync_unlock; for (i = 0; i < ARRAY_SIZE(tps6586x_irqs); i++) { int __irq = i + tps6586x->irq_base; @@ -496,7 +498,11 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client, return -EIO; } - dev_info(&client->dev, "VERSIONCRC is %02x\n", ret); + if ((ret != TPS658621A_VERSIONCRC) && + (ret != TPS658621C_VERSIONCRC)) { + dev_err(&client->dev, "Unsupported chip ID: %x\n", ret); + return -ENODEV; + } tps6586x = kzalloc(sizeof(struct tps6586x), GFP_KERNEL); if (tps6586x == NULL) diff --git a/trunk/drivers/mfd/twl-core.c b/trunk/drivers/mfd/twl-core.c index a35fa7dcbf53..12abd5b924b3 100644 --- a/trunk/drivers/mfd/twl-core.c +++ b/trunk/drivers/mfd/twl-core.c @@ -1003,7 +1003,7 @@ static int twl_remove(struct i2c_client *client) } /* NOTE: this driver only handles a single twl4030/tps659x0 chip */ -static int __devinit +static int __init twl_probe(struct i2c_client *client, const struct i2c_device_id *id) { int status; diff --git a/trunk/drivers/mfd/twl4030-irq.c b/trunk/drivers/mfd/twl4030-irq.c index 63a30e88908f..5d3a1478004b 100644 --- a/trunk/drivers/mfd/twl4030-irq.c +++ b/trunk/drivers/mfd/twl4030-irq.c @@ -599,38 +599,38 @@ static void twl4030_sih_do_edge(struct work_struct *work) * completion, potentially including some re-ordering, of these requests. */ -static void twl4030_sih_mask(struct irq_data *data) +static void twl4030_sih_mask(unsigned irq) { - struct sih_agent *sih = irq_data_get_irq_chip_data(data); + struct sih_agent *sih = get_irq_chip_data(irq); unsigned long flags; spin_lock_irqsave(&sih_agent_lock, flags); - sih->imr |= BIT(data->irq - sih->irq_base); + sih->imr |= BIT(irq - sih->irq_base); sih->imr_change_pending = true; queue_work(wq, &sih->mask_work); spin_unlock_irqrestore(&sih_agent_lock, flags); } -static void twl4030_sih_unmask(struct irq_data *data) +static void twl4030_sih_unmask(unsigned irq) { - struct sih_agent *sih = irq_data_get_irq_chip_data(data); + struct sih_agent *sih = get_irq_chip_data(irq); unsigned long flags; spin_lock_irqsave(&sih_agent_lock, flags); - sih->imr &= ~BIT(data->irq - sih->irq_base); + sih->imr &= ~BIT(irq - sih->irq_base); sih->imr_change_pending = true; queue_work(wq, &sih->mask_work); spin_unlock_irqrestore(&sih_agent_lock, flags); } -static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger) +static int twl4030_sih_set_type(unsigned irq, unsigned trigger) { - struct sih_agent *sih = irq_data_get_irq_chip_data(data); - struct irq_desc *desc = irq_to_desc(data->irq); + struct sih_agent *sih = get_irq_chip_data(irq); + struct irq_desc *desc = irq_to_desc(irq); unsigned long flags; if (!desc) { - pr_err("twl4030: Invalid IRQ: %d\n", data->irq); + pr_err("twl4030: Invalid IRQ: %d\n", irq); return -EINVAL; } @@ -641,7 +641,7 @@ static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger) if ((desc->status & IRQ_TYPE_SENSE_MASK) != trigger) { desc->status &= ~IRQ_TYPE_SENSE_MASK; desc->status |= trigger; - sih->edge_change |= BIT(data->irq - sih->irq_base); + sih->edge_change |= BIT(irq - sih->irq_base); queue_work(wq, &sih->edge_work); } spin_unlock_irqrestore(&sih_agent_lock, flags); @@ -650,9 +650,9 @@ static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger) static struct irq_chip twl4030_sih_irq_chip = { .name = "twl4030", - .irq_mask = twl4030_sih_mask, - .irq_unmask = twl4030_sih_unmask, - .irq_set_type = twl4030_sih_set_type, + .mask = twl4030_sih_mask, + .unmask = twl4030_sih_unmask, + .set_type = twl4030_sih_set_type, }; /*----------------------------------------------------------------------*/ diff --git a/trunk/drivers/mfd/twl6030-irq.c b/trunk/drivers/mfd/twl6030-irq.c index 4082ed73613f..06c8955907e9 100644 --- a/trunk/drivers/mfd/twl6030-irq.c +++ b/trunk/drivers/mfd/twl6030-irq.c @@ -332,7 +332,7 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) */ twl6030_irq_chip = dummy_irq_chip; twl6030_irq_chip.name = "twl6030"; - twl6030_irq_chip.irq_set_type = NULL; + twl6030_irq_chip.set_type = NULL; for (i = irq_base; i < irq_end; i++) { set_irq_chip_and_handler(i, &twl6030_irq_chip, diff --git a/trunk/drivers/mfd/vx855.c b/trunk/drivers/mfd/vx855.c index 348052aa5dbf..ebb059765edd 100644 --- a/trunk/drivers/mfd/vx855.c +++ b/trunk/drivers/mfd/vx855.c @@ -112,7 +112,7 @@ static __devinit int vx855_probe(struct pci_dev *pdev, return ret; } -static void __devexit vx855_remove(struct pci_dev *pdev) +static void vx855_remove(struct pci_dev *pdev) { mfd_remove_devices(&pdev->dev); pci_disable_device(pdev); diff --git a/trunk/drivers/mfd/wm831x-core.c b/trunk/drivers/mfd/wm831x-core.c index 3fe9a58fe6c7..76cadcf3b1fe 100644 --- a/trunk/drivers/mfd/wm831x-core.c +++ b/trunk/drivers/mfd/wm831x-core.c @@ -1541,12 +1541,6 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) dev_info(wm831x->dev, "WM8325 revision %c\n", 'A' + rev); break; - case WM8326: - parent = WM8326; - wm831x->num_gpio = 12; - dev_info(wm831x->dev, "WM8326 revision %c\n", 'A' + rev); - break; - default: dev_err(wm831x->dev, "Unknown WM831x device %04x\n", ret); ret = -EINVAL; @@ -1616,9 +1610,18 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) break; case WM8320: + ret = mfd_add_devices(wm831x->dev, -1, + wm8320_devs, ARRAY_SIZE(wm8320_devs), + NULL, 0); + break; + case WM8321: + ret = mfd_add_devices(wm831x->dev, -1, + wm8320_devs, ARRAY_SIZE(wm8320_devs), + NULL, 0); + break; + case WM8325: - case WM8326: ret = mfd_add_devices(wm831x->dev, -1, wm8320_devs, ARRAY_SIZE(wm8320_devs), NULL, wm831x->irq_base); diff --git a/trunk/drivers/mfd/wm831x-i2c.c b/trunk/drivers/mfd/wm831x-i2c.c index 3853fa8e7cc2..156b19859e81 100644 --- a/trunk/drivers/mfd/wm831x-i2c.c +++ b/trunk/drivers/mfd/wm831x-i2c.c @@ -94,9 +94,9 @@ static int wm831x_i2c_remove(struct i2c_client *i2c) return 0; } -static int wm831x_i2c_suspend(struct device *dev) +static int wm831x_i2c_suspend(struct i2c_client *i2c, pm_message_t mesg) { - struct wm831x *wm831x = dev_get_drvdata(dev); + struct wm831x *wm831x = i2c_get_clientdata(i2c); return wm831x_device_suspend(wm831x); } @@ -108,23 +108,19 @@ static const struct i2c_device_id wm831x_i2c_id[] = { { "wm8320", WM8320 }, { "wm8321", WM8321 }, { "wm8325", WM8325 }, - { "wm8326", WM8326 }, { } }; MODULE_DEVICE_TABLE(i2c, wm831x_i2c_id); -static const struct dev_pm_ops wm831x_pm_ops = { - .suspend = wm831x_i2c_suspend, -}; static struct i2c_driver wm831x_i2c_driver = { .driver = { - .name = "wm831x", - .owner = THIS_MODULE, - .pm = &wm831x_pm_ops, + .name = "wm831x", + .owner = THIS_MODULE, }, .probe = wm831x_i2c_probe, .remove = wm831x_i2c_remove, + .suspend = wm831x_i2c_suspend, .id_table = wm831x_i2c_id, }; diff --git a/trunk/drivers/mfd/wm831x-irq.c b/trunk/drivers/mfd/wm831x-irq.c index f7192d438aab..294183b6260b 100644 --- a/trunk/drivers/mfd/wm831x-irq.c +++ b/trunk/drivers/mfd/wm831x-irq.c @@ -345,16 +345,16 @@ static inline struct wm831x_irq_data *irq_to_wm831x_irq(struct wm831x *wm831x, return &wm831x_irqs[irq - wm831x->irq_base]; } -static void wm831x_irq_lock(struct irq_data *data) +static void wm831x_irq_lock(unsigned int irq) { - struct wm831x *wm831x = irq_data_get_irq_chip_data(data); + struct wm831x *wm831x = get_irq_chip_data(irq); mutex_lock(&wm831x->irq_lock); } -static void wm831x_irq_sync_unlock(struct irq_data *data) +static void wm831x_irq_sync_unlock(unsigned int irq) { - struct wm831x *wm831x = irq_data_get_irq_chip_data(data); + struct wm831x *wm831x = get_irq_chip_data(irq); int i; for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) { @@ -371,30 +371,28 @@ static void wm831x_irq_sync_unlock(struct irq_data *data) mutex_unlock(&wm831x->irq_lock); } -static void wm831x_irq_unmask(struct irq_data *data) +static void wm831x_irq_unmask(unsigned int irq) { - struct wm831x *wm831x = irq_data_get_irq_chip_data(data); - struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, - data->irq); + struct wm831x *wm831x = get_irq_chip_data(irq); + struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, irq); wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; } -static void wm831x_irq_mask(struct irq_data *data) +static void wm831x_irq_mask(unsigned int irq) { - struct wm831x *wm831x = irq_data_get_irq_chip_data(data); - struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, - data->irq); + struct wm831x *wm831x = get_irq_chip_data(irq); + struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, irq); wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; } -static int wm831x_irq_set_type(struct irq_data *data, unsigned int type) +static int wm831x_irq_set_type(unsigned int irq, unsigned int type) { - struct wm831x *wm831x = irq_data_get_irq_chip_data(data); - int val, irq; + struct wm831x *wm831x = get_irq_chip_data(irq); + int val; - irq = data->irq - wm831x->irq_base; + irq = irq - wm831x->irq_base; if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) { /* Ignore internal-only IRQs */ @@ -423,12 +421,12 @@ static int wm831x_irq_set_type(struct irq_data *data, unsigned int type) } static struct irq_chip wm831x_irq_chip = { - .name = "wm831x", - .irq_bus_lock = wm831x_irq_lock, - .irq_bus_sync_unlock = wm831x_irq_sync_unlock, - .irq_mask = wm831x_irq_mask, - .irq_unmask = wm831x_irq_unmask, - .irq_set_type = wm831x_irq_set_type, + .name = "wm831x", + .bus_lock = wm831x_irq_lock, + .bus_sync_unlock = wm831x_irq_sync_unlock, + .mask = wm831x_irq_mask, + .unmask = wm831x_irq_unmask, + .set_type = wm831x_irq_set_type, }; /* The processing of the primary interrupt occurs in a thread so that @@ -517,17 +515,6 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq) return 0; } - /* Try to flag /IRQ as a wake source; there are a number of - * unconditional wake sources in the PMIC so this isn't - * conditional but we don't actually care *too* much if it - * fails. - */ - ret = enable_irq_wake(irq); - if (ret != 0) { - dev_warn(wm831x->dev, "Can't enable IRQ as wake source: %d\n", - ret); - } - wm831x->irq = irq; wm831x->irq_base = pdata->irq_base; diff --git a/trunk/drivers/mfd/wm831x-spi.c b/trunk/drivers/mfd/wm831x-spi.c index 0a8f772be88c..2789b151b0f9 100644 --- a/trunk/drivers/mfd/wm831x-spi.c +++ b/trunk/drivers/mfd/wm831x-spi.c @@ -81,8 +81,6 @@ static int __devinit wm831x_spi_probe(struct spi_device *spi) type = WM8321; else if (strcmp(spi->modalias, "wm8325") == 0) type = WM8325; - else if (strcmp(spi->modalias, "wm8326") == 0) - type = WM8326; else { dev_err(&spi->dev, "Unknown device type\n"); return -EINVAL; @@ -186,17 +184,6 @@ static struct spi_driver wm8325_spi_driver = { .suspend = wm831x_spi_suspend, }; -static struct spi_driver wm8326_spi_driver = { - .driver = { - .name = "wm8326", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - .probe = wm831x_spi_probe, - .remove = __devexit_p(wm831x_spi_remove), - .suspend = wm831x_spi_suspend, -}; - static int __init wm831x_spi_init(void) { int ret; @@ -225,17 +212,12 @@ static int __init wm831x_spi_init(void) if (ret != 0) pr_err("Failed to register WM8325 SPI driver: %d\n", ret); - ret = spi_register_driver(&wm8326_spi_driver); - if (ret != 0) - pr_err("Failed to register WM8326 SPI driver: %d\n", ret); - return 0; } subsys_initcall(wm831x_spi_init); static void __exit wm831x_spi_exit(void) { - spi_unregister_driver(&wm8326_spi_driver); spi_unregister_driver(&wm8325_spi_driver); spi_unregister_driver(&wm8321_spi_driver); spi_unregister_driver(&wm8320_spi_driver); diff --git a/trunk/drivers/mfd/wm8350-irq.c b/trunk/drivers/mfd/wm8350-irq.c index 5839966ebd85..f56c9adf9493 100644 --- a/trunk/drivers/mfd/wm8350-irq.c +++ b/trunk/drivers/mfd/wm8350-irq.c @@ -417,16 +417,16 @@ static irqreturn_t wm8350_irq(int irq, void *irq_data) return IRQ_HANDLED; } -static void wm8350_irq_lock(struct irq_data *data) +static void wm8350_irq_lock(unsigned int irq) { - struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data); + struct wm8350 *wm8350 = get_irq_chip_data(irq); mutex_lock(&wm8350->irq_lock); } -static void wm8350_irq_sync_unlock(struct irq_data *data) +static void wm8350_irq_sync_unlock(unsigned int irq) { - struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data); + struct wm8350 *wm8350 = get_irq_chip_data(irq); int i; for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) { @@ -442,30 +442,28 @@ static void wm8350_irq_sync_unlock(struct irq_data *data) mutex_unlock(&wm8350->irq_lock); } -static void wm8350_irq_enable(struct irq_data *data) +static void wm8350_irq_enable(unsigned int irq) { - struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data); - struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, - data->irq); + struct wm8350 *wm8350 = get_irq_chip_data(irq); + struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, irq); wm8350->irq_masks[irq_data->reg] &= ~irq_data->mask; } -static void wm8350_irq_disable(struct irq_data *data) +static void wm8350_irq_disable(unsigned int irq) { - struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data); - struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, - data->irq); + struct wm8350 *wm8350 = get_irq_chip_data(irq); + struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, irq); wm8350->irq_masks[irq_data->reg] |= irq_data->mask; } static struct irq_chip wm8350_irq_chip = { - .name = "wm8350", - .irq_bus_lock = wm8350_irq_lock, - .irq_bus_sync_unlock = wm8350_irq_sync_unlock, - .irq_disable = wm8350_irq_disable, - .irq_enable = wm8350_irq_enable, + .name = "wm8350", + .bus_lock = wm8350_irq_lock, + .bus_sync_unlock = wm8350_irq_sync_unlock, + .disable = wm8350_irq_disable, + .enable = wm8350_irq_enable, }; int wm8350_irq_init(struct wm8350 *wm8350, int irq, diff --git a/trunk/drivers/mfd/wm8994-core.c b/trunk/drivers/mfd/wm8994-core.c index 41233c7fa581..8d221ba5e38d 100644 --- a/trunk/drivers/mfd/wm8994-core.c +++ b/trunk/drivers/mfd/wm8994-core.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -170,16 +169,8 @@ int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg, EXPORT_SYMBOL_GPL(wm8994_set_bits); static struct mfd_cell wm8994_regulator_devs[] = { - { - .name = "wm8994-ldo", - .id = 1, - .pm_runtime_no_callbacks = true, - }, - { - .name = "wm8994-ldo", - .id = 2, - .pm_runtime_no_callbacks = true, - }, + { .name = "wm8994-ldo", .id = 1 }, + { .name = "wm8994-ldo", .id = 2 }, }; static struct resource wm8994_codec_resources[] = { @@ -209,7 +200,6 @@ static struct mfd_cell wm8994_devs[] = { .name = "wm8994-gpio", .num_resources = ARRAY_SIZE(wm8994_gpio_resources), .resources = wm8994_gpio_resources, - .pm_runtime_no_callbacks = true, }, }; @@ -241,7 +231,7 @@ static const char *wm8958_main_supplies[] = { }; #ifdef CONFIG_PM -static int wm8994_suspend(struct device *dev) +static int wm8994_device_suspend(struct device *dev) { struct wm8994 *wm8994 = dev_get_drvdata(dev); int ret; @@ -271,7 +261,7 @@ static int wm8994_suspend(struct device *dev) return 0; } -static int wm8994_resume(struct device *dev) +static int wm8994_device_resume(struct device *dev) { struct wm8994 *wm8994 = dev_get_drvdata(dev); int ret; @@ -481,9 +471,6 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq) goto err_irq; } - pm_runtime_enable(wm8994->dev); - pm_runtime_resume(wm8994->dev); - return 0; err_irq: @@ -503,7 +490,6 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq) static void wm8994_device_exit(struct wm8994 *wm8994) { - pm_runtime_disable(wm8994->dev); mfd_remove_devices(wm8994->dev); wm8994_irq_exit(wm8994); regulator_bulk_disable(wm8994->num_supplies, @@ -587,6 +573,21 @@ static int wm8994_i2c_remove(struct i2c_client *i2c) return 0; } +#ifdef CONFIG_PM +static int wm8994_i2c_suspend(struct i2c_client *i2c, pm_message_t state) +{ + return wm8994_device_suspend(&i2c->dev); +} + +static int wm8994_i2c_resume(struct i2c_client *i2c) +{ + return wm8994_device_resume(&i2c->dev); +} +#else +#define wm8994_i2c_suspend NULL +#define wm8994_i2c_resume NULL +#endif + static const struct i2c_device_id wm8994_i2c_id[] = { { "wm8994", WM8994 }, { "wm8958", WM8958 }, @@ -594,16 +595,15 @@ static const struct i2c_device_id wm8994_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id); -UNIVERSAL_DEV_PM_OPS(wm8994_pm_ops, wm8994_suspend, wm8994_resume, NULL); - static struct i2c_driver wm8994_i2c_driver = { .driver = { - .name = "wm8994", - .owner = THIS_MODULE, - .pm = &wm8994_pm_ops, + .name = "wm8994", + .owner = THIS_MODULE, }, .probe = wm8994_i2c_probe, .remove = wm8994_i2c_remove, + .suspend = wm8994_i2c_suspend, + .resume = wm8994_i2c_resume, .id_table = wm8994_i2c_id, }; diff --git a/trunk/drivers/mfd/wm8994-irq.c b/trunk/drivers/mfd/wm8994-irq.c index 29e8faf9c01c..8400eb1ee5db 100644 --- a/trunk/drivers/mfd/wm8994-irq.c +++ b/trunk/drivers/mfd/wm8994-irq.c @@ -156,16 +156,16 @@ static inline struct wm8994_irq_data *irq_to_wm8994_irq(struct wm8994 *wm8994, return &wm8994_irqs[irq - wm8994->irq_base]; } -static void wm8994_irq_lock(struct irq_data *data) +static void wm8994_irq_lock(unsigned int irq) { - struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data); + struct wm8994 *wm8994 = get_irq_chip_data(irq); mutex_lock(&wm8994->irq_lock); } -static void wm8994_irq_sync_unlock(struct irq_data *data) +static void wm8994_irq_sync_unlock(unsigned int irq) { - struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data); + struct wm8994 *wm8994 = get_irq_chip_data(irq); int i; for (i = 0; i < ARRAY_SIZE(wm8994->irq_masks_cur); i++) { @@ -182,30 +182,28 @@ static void wm8994_irq_sync_unlock(struct irq_data *data) mutex_unlock(&wm8994->irq_lock); } -static void wm8994_irq_unmask(struct irq_data *data) +static void wm8994_irq_unmask(unsigned int irq) { - struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data); - struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994, - data->irq); + struct wm8994 *wm8994 = get_irq_chip_data(irq); + struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994, irq); wm8994->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; } -static void wm8994_irq_mask(struct irq_data *data) +static void wm8994_irq_mask(unsigned int irq) { - struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data); - struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994, - data->irq); + struct wm8994 *wm8994 = get_irq_chip_data(irq); + struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994, irq); wm8994->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; } static struct irq_chip wm8994_irq_chip = { - .name = "wm8994", - .irq_bus_lock = wm8994_irq_lock, - .irq_bus_sync_unlock = wm8994_irq_sync_unlock, - .irq_mask = wm8994_irq_mask, - .irq_unmask = wm8994_irq_unmask, + .name = "wm8994", + .bus_lock = wm8994_irq_lock, + .bus_sync_unlock = wm8994_irq_sync_unlock, + .mask = wm8994_irq_mask, + .unmask = wm8994_irq_unmask, }; /* The processing of the primary interrupt occurs in a thread so that diff --git a/trunk/drivers/misc/Kconfig b/trunk/drivers/misc/Kconfig index cc8e49db45fe..1e1a4be8eb6c 100644 --- a/trunk/drivers/misc/Kconfig +++ b/trunk/drivers/misc/Kconfig @@ -64,7 +64,7 @@ config ATMEL_PWM config AB8500_PWM bool "AB8500 PWM support" - depends on AB8500_CORE && ARCH_U8500 + depends on AB8500_CORE select HAVE_PWM help This driver exports functions to enable/disble/config/free Pulse diff --git a/trunk/drivers/misc/cs5535-mfgpt.c b/trunk/drivers/misc/cs5535-mfgpt.c index d02d302ee6d5..6f6218061b0d 100644 --- a/trunk/drivers/misc/cs5535-mfgpt.c +++ b/trunk/drivers/misc/cs5535-mfgpt.c @@ -16,11 +16,12 @@ #include #include #include -#include +#include #include #include #define DRV_NAME "cs5535-mfgpt" +#define MFGPT_BAR 2 static int mfgpt_reset_timers; module_param_named(mfgptfix, mfgpt_reset_timers, int, 0644); @@ -36,7 +37,7 @@ static struct cs5535_mfgpt_chip { DECLARE_BITMAP(avail, MFGPT_MAX_TIMERS); resource_size_t base; - struct platform_device *pdev; + struct pci_dev *pdev; spinlock_t lock; int initialized; } cs5535_mfgpt_chip; @@ -289,10 +290,10 @@ static int __init scan_timers(struct cs5535_mfgpt_chip *mfgpt) return timers; } -static int __devinit cs5535_mfgpt_probe(struct platform_device *pdev) +static int __init cs5535_mfgpt_probe(struct pci_dev *pdev, + const struct pci_device_id *pci_id) { - struct resource *res; - int err = -EIO, t; + int err, t; /* There are two ways to get the MFGPT base address; one is by * fetching it from MSR_LBAR_MFGPT, the other is by reading the @@ -301,27 +302,29 @@ static int __devinit cs5535_mfgpt_probe(struct platform_device *pdev) * it turns out to be unreliable in the face of crappy BIOSes, we * can always go back to using MSRs.. */ - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!res) { - dev_err(&pdev->dev, "can't fetch device resource info\n"); + err = pci_enable_device_io(pdev); + if (err) { + dev_err(&pdev->dev, "can't enable device IO\n"); goto done; } - if (!request_region(res->start, resource_size(res), pdev->name)) { - dev_err(&pdev->dev, "can't request region\n"); + err = pci_request_region(pdev, MFGPT_BAR, DRV_NAME); + if (err) { + dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", MFGPT_BAR); goto done; } /* set up the driver-specific struct */ - cs5535_mfgpt_chip.base = res->start; + cs5535_mfgpt_chip.base = pci_resource_start(pdev, MFGPT_BAR); cs5535_mfgpt_chip.pdev = pdev; spin_lock_init(&cs5535_mfgpt_chip.lock); - dev_info(&pdev->dev, "reserved resource region %pR\n", res); + dev_info(&pdev->dev, "allocated PCI BAR #%d: base 0x%llx\n", MFGPT_BAR, + (unsigned long long) cs5535_mfgpt_chip.base); /* detect the available timers */ t = scan_timers(&cs5535_mfgpt_chip); - dev_info(&pdev->dev, "%d MFGPT timers available\n", t); + dev_info(&pdev->dev, DRV_NAME ": %d MFGPT timers available\n", t); cs5535_mfgpt_chip.initialized = 1; return 0; @@ -329,18 +332,47 @@ static int __devinit cs5535_mfgpt_probe(struct platform_device *pdev) return err; } -static struct platform_driver cs5535_mfgpt_drv = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, - .probe = cs5535_mfgpt_probe, +static struct pci_device_id cs5535_mfgpt_pci_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, + { 0, }, }; +MODULE_DEVICE_TABLE(pci, cs5535_mfgpt_pci_tbl); +/* + * Just like with the cs5535-gpio driver, we can't use the standard PCI driver + * registration stuff. It only allows only one driver to bind to each PCI + * device, and we want the GPIO and MFGPT drivers to be able to share a PCI + * device. Instead, we manually scan for the PCI device, request a single + * region, and keep track of the devices that we're using. + */ + +static int __init cs5535_mfgpt_scan_pci(void) +{ + struct pci_dev *pdev; + int err = -ENODEV; + int i; + + for (i = 0; i < ARRAY_SIZE(cs5535_mfgpt_pci_tbl); i++) { + pdev = pci_get_device(cs5535_mfgpt_pci_tbl[i].vendor, + cs5535_mfgpt_pci_tbl[i].device, NULL); + if (pdev) { + err = cs5535_mfgpt_probe(pdev, + &cs5535_mfgpt_pci_tbl[i]); + if (err) + pci_dev_put(pdev); + + /* we only support a single CS5535/6 southbridge */ + break; + } + } + + return err; +} static int __init cs5535_mfgpt_init(void) { - return platform_driver_register(&cs5535_mfgpt_drv); + return cs5535_mfgpt_scan_pci(); } module_init(cs5535_mfgpt_init); @@ -348,4 +380,3 @@ module_init(cs5535_mfgpt_init); MODULE_AUTHOR("Andres Salomon "); MODULE_DESCRIPTION("CS5535/CS5536 MFGPT timer driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:" DRV_NAME); diff --git a/trunk/drivers/net/myri10ge/myri10ge.c b/trunk/drivers/net/myri10ge/myri10ge.c index ea5cfe2c3a04..a37fcf11ab36 100644 --- a/trunk/drivers/net/myri10ge/myri10ge.c +++ b/trunk/drivers/net/myri10ge/myri10ge.c @@ -3403,7 +3403,9 @@ static int myri10ge_resume(struct pci_dev *pdev) return -EIO; } - pci_restore_state(pdev); + status = pci_restore_state(pdev); + if (status) + return status; status = pci_enable_device(pdev); if (status) { diff --git a/trunk/drivers/net/sfc/falcon.c b/trunk/drivers/net/sfc/falcon.c index 61ddd2c6e750..70e4f7dcce81 100644 --- a/trunk/drivers/net/sfc/falcon.c +++ b/trunk/drivers/net/sfc/falcon.c @@ -1107,9 +1107,22 @@ static int __falcon_reset_hw(struct efx_nic *efx, enum reset_type method) /* Restore PCI configuration if needed */ if (method == RESET_TYPE_WORLD) { - if (efx_nic_is_dual_func(efx)) - pci_restore_state(nic_data->pci_dev2); - pci_restore_state(efx->pci_dev); + if (efx_nic_is_dual_func(efx)) { + rc = pci_restore_state(nic_data->pci_dev2); + if (rc) { + netif_err(efx, drv, efx->net_dev, + "failed to restore PCI config for " + "the secondary function\n"); + goto fail3; + } + } + rc = pci_restore_state(efx->pci_dev); + if (rc) { + netif_err(efx, drv, efx->net_dev, + "failed to restore PCI config for the " + "primary function\n"); + goto fail4; + } netif_dbg(efx, drv, efx->net_dev, "successfully restored PCI config\n"); } @@ -1120,7 +1133,7 @@ static int __falcon_reset_hw(struct efx_nic *efx, enum reset_type method) rc = -ETIMEDOUT; netif_err(efx, hw, efx->net_dev, "timed out waiting for hardware reset\n"); - goto fail3; + goto fail5; } netif_dbg(efx, hw, efx->net_dev, "hardware reset complete\n"); @@ -1128,9 +1141,11 @@ static int __falcon_reset_hw(struct efx_nic *efx, enum reset_type method) /* pci_save_state() and pci_restore_state() MUST be called in pairs */ fail2: +fail3: pci_restore_state(efx->pci_dev); fail1: -fail3: +fail4: +fail5: return rc; } diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00pci.c b/trunk/drivers/net/wireless/rt2x00/rt2x00pci.c index ace0b668c04e..73631c6fbb30 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -363,12 +363,12 @@ int rt2x00pci_resume(struct pci_dev *pci_dev) struct rt2x00_dev *rt2x00dev = hw->priv; if (pci_set_power_state(pci_dev, PCI_D0) || - pci_enable_device(pci_dev)) { + pci_enable_device(pci_dev) || + pci_restore_state(pci_dev)) { ERROR(rt2x00dev, "Failed to resume device.\n"); return -EIO; } - pci_restore_state(pci_dev); return rt2x00lib_resume(rt2x00dev); } EXPORT_SYMBOL_GPL(rt2x00pci_resume); diff --git a/trunk/drivers/pci/msi.c b/trunk/drivers/pci/msi.c index 44b0aeee83e5..7c24dcef2989 100644 --- a/trunk/drivers/pci/msi.c +++ b/trunk/drivers/pci/msi.c @@ -168,9 +168,8 @@ static u32 __msix_mask_irq(struct msi_desc *desc, u32 flag) u32 mask_bits = desc->masked; unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL; - mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; - if (flag) - mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; + mask_bits &= ~1; + mask_bits |= flag; writel(mask_bits, desc->mask_base + offset); return mask_bits; diff --git a/trunk/drivers/pci/msi.h b/trunk/drivers/pci/msi.h index 65c42f80f23e..feff3bee6fe5 100644 --- a/trunk/drivers/pci/msi.h +++ b/trunk/drivers/pci/msi.h @@ -6,6 +6,12 @@ #ifndef MSI_H #define MSI_H +#define PCI_MSIX_ENTRY_SIZE 16 +#define PCI_MSIX_ENTRY_LOWER_ADDR 0 +#define PCI_MSIX_ENTRY_UPPER_ADDR 4 +#define PCI_MSIX_ENTRY_DATA 8 +#define PCI_MSIX_ENTRY_VECTOR_CTRL 12 + #define msi_control_reg(base) (base + PCI_MSI_FLAGS) #define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO) #define msi_upper_address_reg(base) (base + PCI_MSI_ADDRESS_HI) diff --git a/trunk/drivers/pci/pci-acpi.c b/trunk/drivers/pci/pci-acpi.c index 6fe0772e0e7d..24e19c594e57 100644 --- a/trunk/drivers/pci/pci-acpi.c +++ b/trunk/drivers/pci/pci-acpi.c @@ -46,9 +46,9 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) struct pci_dev *pci_dev = context; if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_dev) { - pci_wakeup_event(pci_dev); pci_check_pme_status(pci_dev); pm_runtime_resume(&pci_dev->dev); + pci_wakeup_event(pci_dev); if (pci_dev->subordinate) pci_pme_wakeup_bus(pci_dev->subordinate); } @@ -399,7 +399,6 @@ static int __init acpi_pci_init(void) if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n"); - pcie_clear_aspm(); pcie_no_aspm(); } diff --git a/trunk/drivers/pci/pci-driver.c b/trunk/drivers/pci/pci-driver.c index 88246dd46452..8a6f797de8e5 100644 --- a/trunk/drivers/pci/pci-driver.c +++ b/trunk/drivers/pci/pci-driver.c @@ -338,7 +338,7 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, } /** - * __pci_device_probe - check if a driver wants to claim a specific PCI device + * __pci_device_probe() * @drv: driver to call to check if it wants the PCI device * @pci_dev: PCI device being probed * @@ -449,8 +449,7 @@ static int pci_restore_standard_config(struct pci_dev *pci_dev) return error; } - pci_restore_state(pci_dev); - return 0; + return pci_restore_state(pci_dev); } static void pci_pm_default_resume_early(struct pci_dev *pci_dev) diff --git a/trunk/drivers/pci/pci-stub.c b/trunk/drivers/pci/pci-stub.c index 775e933c2225..f7b68ca6cc98 100644 --- a/trunk/drivers/pci/pci-stub.c +++ b/trunk/drivers/pci/pci-stub.c @@ -47,10 +47,6 @@ static int __init pci_stub_init(void) if (rc) return rc; - /* no ids passed actually */ - if (ids[0] == '\0') - return 0; - /* add ids specified in the module parameter */ p = ids; while ((id = strsep(&p, ","))) { @@ -58,9 +54,6 @@ static int __init pci_stub_init(void) subdevice = PCI_ANY_ID, class=0, class_mask=0; int fields; - if (!strlen(id)) - continue; - fields = sscanf(id, "%x:%x:%x:%x:%x:%x", &vendor, &device, &subvendor, &subdevice, &class, &class_mask); diff --git a/trunk/drivers/pci/pci-sysfs.c b/trunk/drivers/pci/pci-sysfs.c index 8ecaac983923..63d5042f2079 100644 --- a/trunk/drivers/pci/pci-sysfs.c +++ b/trunk/drivers/pci/pci-sysfs.c @@ -1149,7 +1149,7 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) sysfs_bin_attr_init(attr); attr->size = rom_size; attr->attr.name = "rom"; - attr->attr.mode = S_IRUSR | S_IWUSR; + attr->attr.mode = S_IRUSR; attr->read = pci_read_rom; attr->write = pci_write_rom; retval = sysfs_create_bin_file(&pdev->dev.kobj, attr); diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index b714d787bddd..710c8a29be0d 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -937,13 +937,14 @@ pci_save_state(struct pci_dev *dev) * pci_restore_state - Restore the saved state of a PCI device * @dev: - PCI device that we're dealing with */ -void pci_restore_state(struct pci_dev *dev) +int +pci_restore_state(struct pci_dev *dev) { int i; u32 val; if (!dev->state_saved) - return; + return 0; /* PCI Express register must be restored first */ pci_restore_pcie_state(dev); @@ -967,6 +968,8 @@ void pci_restore_state(struct pci_dev *dev) pci_restore_iov_state(dev); dev->state_saved = false; + + return 0; } static int do_pci_enable_device(struct pci_dev *dev, int bars) @@ -1297,6 +1300,22 @@ bool pci_check_pme_status(struct pci_dev *dev) return ret; } +/* + * Time to wait before the system can be put into a sleep state after reporting + * a wakeup event signaled by a PCI device. + */ +#define PCI_WAKEUP_COOLDOWN 100 + +/** + * pci_wakeup_event - Report a wakeup event related to a given PCI device. + * @dev: Device to report the wakeup event for. + */ +void pci_wakeup_event(struct pci_dev *dev) +{ + if (device_may_wakeup(&dev->dev)) + pm_wakeup_event(&dev->dev, PCI_WAKEUP_COOLDOWN); +} + /** * pci_pme_wakeup - Wake up a PCI device if its PME Status bit is set. * @dev: Device to handle. @@ -1308,8 +1327,8 @@ bool pci_check_pme_status(struct pci_dev *dev) static int pci_pme_wakeup(struct pci_dev *dev, void *ign) { if (pci_check_pme_status(dev)) { - pci_wakeup_event(dev); pm_request_resume(&dev->dev); + pci_wakeup_event(dev); } return 0; } diff --git a/trunk/drivers/pci/pci.h b/trunk/drivers/pci/pci.h index f69d6e0fda75..7d33f6673868 100644 --- a/trunk/drivers/pci/pci.h +++ b/trunk/drivers/pci/pci.h @@ -74,12 +74,6 @@ extern void pci_pm_init(struct pci_dev *dev); extern void platform_pci_wakeup_init(struct pci_dev *dev); extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); -static inline void pci_wakeup_event(struct pci_dev *dev) -{ - /* Wait 100 ms before the system can be put into a sleep state. */ - pm_wakeup_event(&dev->dev, 100); -} - static inline bool pci_is_bridge(struct pci_dev *pci_dev) { return !!(pci_dev->subordinate); @@ -146,6 +140,14 @@ static inline void pci_no_msi(void) { } static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } #endif +#ifdef CONFIG_PCIEAER +void pci_no_aer(void); +bool pci_aer_available(void); +#else +static inline void pci_no_aer(void) { } +static inline bool pci_aer_available(void) { return false; } +#endif + static inline int pci_no_d1d2(struct pci_dev *dev) { unsigned int parent_dstates = 0; diff --git a/trunk/drivers/pci/pcie/aer/aerdrv.c b/trunk/drivers/pci/pcie/aer/aerdrv.c index 58ad7917553c..2b2b6508efde 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv.c @@ -17,7 +17,6 @@ #include #include -#include #include #include #include diff --git a/trunk/drivers/pci/pcie/aer/aerdrv.h b/trunk/drivers/pci/pcie/aer/aerdrv.h index 80c11d131499..9656e3060412 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv.h +++ b/trunk/drivers/pci/pcie/aer/aerdrv.h @@ -132,6 +132,7 @@ static inline int aer_osc_setup(struct pcie_device *pciedev) #ifdef CONFIG_ACPI_APEI extern int pcie_aer_get_firmware_first(struct pci_dev *pci_dev); +extern bool aer_acpi_firmware_first(void); #else static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev) { @@ -139,6 +140,8 @@ static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev) return pci_dev->__aer_firmware_first; return 0; } + +static inline bool aer_acpi_firmware_first(void) { return false; } #endif static inline void pcie_aer_force_firmware_first(struct pci_dev *pci_dev, diff --git a/trunk/drivers/pci/pcie/aspm.c b/trunk/drivers/pci/pcie/aspm.c index 3188cd96b338..71222814c1ec 100644 --- a/trunk/drivers/pci/pcie/aspm.c +++ b/trunk/drivers/pci/pcie/aspm.c @@ -68,7 +68,7 @@ struct pcie_link_state { struct aspm_latency acceptable[8]; }; -static int aspm_disabled, aspm_force, aspm_clear_state; +static int aspm_disabled, aspm_force; static DEFINE_MUTEX(aspm_lock); static LIST_HEAD(link_list); @@ -139,7 +139,7 @@ static void pcie_set_clkpm(struct pcie_link_state *link, int enable) { /* Don't enable Clock PM if the link is not Clock PM capable */ if (!link->clkpm_capable && enable) - enable = 0; + return; /* Need nothing if the specified equals to current state */ if (link->clkpm_enabled == enable) return; @@ -498,10 +498,6 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) struct pci_dev *child; int pos; u32 reg32; - - if (aspm_clear_state) - return -EINVAL; - /* * Some functions in a slot might not all be PCIe functions, * very strange. Disable ASPM for the whole slot @@ -567,15 +563,12 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev) struct pcie_link_state *link; int blacklist = !!pcie_aspm_sanity_check(pdev); - if (!pci_is_pcie(pdev) || pdev->link_state) + if (aspm_disabled || !pci_is_pcie(pdev) || pdev->link_state) return; if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) return; - if (aspm_disabled && !aspm_clear_state) - return; - /* VIA has a strange chipset, root port is under a bridge */ if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT && pdev->bus->self) @@ -648,7 +641,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev) struct pci_dev *parent = pdev->bus->self; struct pcie_link_state *link, *root, *parent_link; - if ((aspm_disabled && !aspm_clear_state) || !pci_is_pcie(pdev) || + if (aspm_disabled || !pci_is_pcie(pdev) || !parent || !parent->link_state) return; if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && @@ -906,12 +899,6 @@ static int __init pcie_aspm_disable(char *str) __setup("pcie_aspm=", pcie_aspm_disable); -void pcie_clear_aspm(void) -{ - if (!aspm_force) - aspm_clear_state = 1; -} - void pcie_no_aspm(void) { if (!aspm_force) diff --git a/trunk/drivers/pci/pcie/pme.c b/trunk/drivers/pci/pcie/pme.c index 0057344a3fcb..2f3c90407227 100644 --- a/trunk/drivers/pci/pcie/pme.c +++ b/trunk/drivers/pci/pcie/pme.c @@ -26,6 +26,9 @@ #include "../pci.h" #include "portdrv.h" +#define PCI_EXP_RTSTA_PME 0x10000 /* PME status */ +#define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */ + /* * If this switch is set, MSI will not be used for PCIe PME signaling. This * causes the PCIe port driver to use INTx interrupts only, but it turns out @@ -70,6 +73,22 @@ void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable) pci_write_config_word(dev, rtctl_pos, rtctl); } +/** + * pcie_pme_clear_status - Clear root port PME interrupt status. + * @dev: PCIe root port or event collector. + */ +static void pcie_pme_clear_status(struct pci_dev *dev) +{ + int rtsta_pos; + u32 rtsta; + + rtsta_pos = pci_pcie_cap(dev) + PCI_EXP_RTSTA; + + pci_read_config_dword(dev, rtsta_pos, &rtsta); + rtsta |= PCI_EXP_RTSTA_PME; + pci_write_config_dword(dev, rtsta_pos, rtsta); +} + /** * pcie_pme_walk_bus - Scan a PCI bus for devices asserting PME#. * @bus: PCI bus to scan. @@ -84,8 +103,8 @@ static bool pcie_pme_walk_bus(struct pci_bus *bus) list_for_each_entry(dev, &bus->devices, bus_list) { /* Skip PCIe devices in case we started from a root port. */ if (!pci_is_pcie(dev) && pci_check_pme_status(dev)) { - pci_wakeup_event(dev); pm_request_resume(&dev->dev); + pci_wakeup_event(dev); ret = true; } @@ -187,8 +206,8 @@ static void pcie_pme_handle_request(struct pci_dev *port, u16 req_id) /* The device is there, but we have to check its PME status. */ found = pci_check_pme_status(dev); if (found) { - pci_wakeup_event(dev); pm_request_resume(&dev->dev); + pci_wakeup_event(dev); } pci_dev_put(dev); } else if (devfn) { @@ -234,7 +253,7 @@ static void pcie_pme_work_fn(struct work_struct *work) * Clear PME status of the port. If there are other * pending PMEs, the status will be set again. */ - pcie_clear_root_pme_status(port); + pcie_pme_clear_status(port); spin_unlock_irq(&data->lock); pcie_pme_handle_request(port, rtsta & 0xffff); @@ -359,7 +378,7 @@ static int pcie_pme_probe(struct pcie_device *srv) port = srv->port; pcie_pme_interrupt_enable(port, false); - pcie_clear_root_pme_status(port); + pcie_pme_clear_status(port); ret = request_irq(srv->irq, pcie_pme_irq, IRQF_SHARED, "PCIe PME", srv); if (ret) { @@ -383,7 +402,7 @@ static int pcie_pme_suspend(struct pcie_device *srv) spin_lock_irq(&data->lock); pcie_pme_interrupt_enable(port, false); - pcie_clear_root_pme_status(port); + pcie_pme_clear_status(port); data->noirq = true; spin_unlock_irq(&data->lock); @@ -403,7 +422,7 @@ static int pcie_pme_resume(struct pcie_device *srv) spin_lock_irq(&data->lock); data->noirq = false; - pcie_clear_root_pme_status(port); + pcie_pme_clear_status(port); pcie_pme_interrupt_enable(port, true); spin_unlock_irq(&data->lock); diff --git a/trunk/drivers/pci/pcie/portdrv.h b/trunk/drivers/pci/pcie/portdrv.h index bd00a01aef14..7b5aba0a3291 100644 --- a/trunk/drivers/pci/pcie/portdrv.h +++ b/trunk/drivers/pci/pcie/portdrv.h @@ -20,6 +20,9 @@ #define get_descriptor_id(type, service) (((type - 4) << 4) | service) +extern bool pcie_ports_disabled; +extern bool pcie_ports_auto; + extern struct bus_type pcie_port_bus_type; extern int pcie_port_device_register(struct pci_dev *dev); #ifdef CONFIG_PM @@ -32,8 +35,6 @@ extern void pcie_port_bus_unregister(void); struct pci_dev; -extern void pcie_clear_root_pme_status(struct pci_dev *dev); - #ifdef CONFIG_PCIE_PME extern bool pcie_pme_msi_disabled; diff --git a/trunk/drivers/pci/pcie/portdrv_acpi.c b/trunk/drivers/pci/pcie/portdrv_acpi.c index a86b56e5f2f2..5982b6a63b89 100644 --- a/trunk/drivers/pci/pcie/portdrv_acpi.c +++ b/trunk/drivers/pci/pcie/portdrv_acpi.c @@ -33,7 +33,7 @@ */ int pcie_port_acpi_setup(struct pci_dev *port, int *srv_mask) { - struct acpi_pci_root *root; + acpi_status status; acpi_handle handle; u32 flags; @@ -44,11 +44,26 @@ int pcie_port_acpi_setup(struct pci_dev *port, int *srv_mask) if (!handle) return -EINVAL; - root = acpi_pci_find_root(handle); - if (!root) + flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL + | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL + | OSC_PCI_EXPRESS_PME_CONTROL; + + if (pci_aer_available()) { + if (aer_acpi_firmware_first()) + dev_dbg(&port->dev, "PCIe errors handled by BIOS.\n"); + else + flags |= OSC_PCI_EXPRESS_AER_CONTROL; + } + + status = acpi_pci_osc_control_set(handle, &flags, + OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); + if (ACPI_FAILURE(status)) { + dev_dbg(&port->dev, "ACPI _OSC request failed (code %d)\n", + status); return -ENODEV; + } - flags = root->osc_control_set; + dev_info(&port->dev, "ACPI _OSC control granted for 0x%02x\n", flags); *srv_mask = PCIE_PORT_SERVICE_VC; if (flags & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL) diff --git a/trunk/drivers/pci/pcie/portdrv_core.c b/trunk/drivers/pci/pcie/portdrv_core.c index 5130d0d22390..a9c222d79ebc 100644 --- a/trunk/drivers/pci/pcie/portdrv_core.c +++ b/trunk/drivers/pci/pcie/portdrv_core.c @@ -241,17 +241,17 @@ static int get_port_device_capability(struct pci_dev *dev) int cap_mask; int err; - if (pcie_ports_disabled) - return 0; - err = pcie_port_platform_notify(dev, &cap_mask); - if (!pcie_ports_auto) { + if (pcie_ports_auto) { + if (err) { + pcie_no_aspm(); + return 0; + } + } else { cap_mask = PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP | PCIE_PORT_SERVICE_VC; if (pci_aer_available()) cap_mask |= PCIE_PORT_SERVICE_AER; - } else if (err) { - return 0; } pos = pci_pcie_cap(dev); @@ -349,18 +349,15 @@ int pcie_port_device_register(struct pci_dev *dev) int status, capabilities, i, nr_service; int irqs[PCIE_PORT_DEVICE_MAXSERVICES]; + /* Get and check PCI Express port services */ + capabilities = get_port_device_capability(dev); + if (!capabilities) + return -ENODEV; + /* Enable PCI Express port device */ status = pci_enable_device(dev); if (status) return status; - - /* Get and check PCI Express port services */ - capabilities = get_port_device_capability(dev); - if (!capabilities) { - pcie_no_aspm(); - return 0; - } - pci_set_master(dev); /* * Initialize service irqs. Don't use service devices that diff --git a/trunk/drivers/pci/pcie/portdrv_pci.c b/trunk/drivers/pci/pcie/portdrv_pci.c index e0610bda1dea..f9033e190fb6 100644 --- a/trunk/drivers/pci/pcie/portdrv_pci.c +++ b/trunk/drivers/pci/pcie/portdrv_pci.c @@ -57,22 +57,6 @@ __setup("pcie_ports=", pcie_port_setup); /* global data */ -/** - * pcie_clear_root_pme_status - Clear root port PME interrupt status. - * @dev: PCIe root port or event collector. - */ -void pcie_clear_root_pme_status(struct pci_dev *dev) -{ - int rtsta_pos; - u32 rtsta; - - rtsta_pos = pci_pcie_cap(dev) + PCI_EXP_RTSTA; - - pci_read_config_dword(dev, rtsta_pos, &rtsta); - rtsta |= PCI_EXP_RTSTA_PME; - pci_write_config_dword(dev, rtsta_pos, rtsta); -} - static int pcie_portdrv_restore_config(struct pci_dev *dev) { int retval; @@ -85,20 +69,6 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev) } #ifdef CONFIG_PM -static int pcie_port_resume_noirq(struct device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev); - - /* - * Some BIOSes forget to clear Root PME Status bits after system wakeup - * which breaks ACPI-based runtime wakeup on PCI Express, so clear those - * bits now just in case (shouldn't hurt). - */ - if(pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) - pcie_clear_root_pme_status(pdev); - return 0; -} - static const struct dev_pm_ops pcie_portdrv_pm_ops = { .suspend = pcie_port_device_suspend, .resume = pcie_port_device_resume, @@ -106,7 +76,6 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = { .thaw = pcie_port_device_resume, .poweroff = pcie_port_device_suspend, .restore = pcie_port_device_resume, - .resume_noirq = pcie_port_resume_noirq, }; #define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) @@ -358,8 +327,10 @@ static int __init pcie_portdrv_init(void) { int retval; - if (pcie_ports_disabled) - return pci_register_driver(&pcie_portdriver); + if (pcie_ports_disabled) { + pcie_no_aspm(); + return -EACCES; + } dmi_check_system(pcie_portdrv_dmi_table); diff --git a/trunk/drivers/power/Kconfig b/trunk/drivers/power/Kconfig index 61bf5d724139..60d83d983a36 100644 --- a/trunk/drivers/power/Kconfig +++ b/trunk/drivers/power/Kconfig @@ -136,16 +136,6 @@ config BATTERY_MAX17040 in handheld and portable equipment. The MAX17040 is configured to operate with a single lithium cell -config BATTERY_MAX17042 - tristate "Maxim MAX17042/8997/8966 Fuel Gauge" - depends on I2C - help - MAX17042 is fuel-gauge systems for lithium-ion (Li+) batteries - in handheld and portable equipment. The MAX17042 is configured - to operate with a single lithium cell. MAX8997 and MAX8966 are - multi-function devices that include fuel gauages that are compatible - with MAX17042. - config BATTERY_Z2 tristate "Z2 battery driver" depends on I2C && MACH_ZIPIT2 @@ -195,14 +185,4 @@ config CHARGER_TWL4030 help Say Y here to enable support for TWL4030 Battery Charge Interface. -config CHARGER_GPIO - tristate "GPIO charger" - depends on GPIOLIB - help - Say Y to include support for chargers which report their online status - through a GPIO pin. - - This driver can be build as a module. If so, the module will be - called gpio-charger. - endif # POWER_SUPPLY diff --git a/trunk/drivers/power/Makefile b/trunk/drivers/power/Makefile index 8385bfae8728..c75772eb157c 100644 --- a/trunk/drivers/power/Makefile +++ b/trunk/drivers/power/Makefile @@ -25,7 +25,6 @@ obj-$(CONFIG_BATTERY_BQ20Z75) += bq20z75.o obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o -obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o obj-$(CONFIG_BATTERY_Z2) += z2_battery.o obj-$(CONFIG_BATTERY_S3C_ADC) += s3c_adc_battery.o obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o @@ -33,4 +32,3 @@ obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o obj-$(CONFIG_BATTERY_INTEL_MID) += intel_mid_battery.o obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o -obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o diff --git a/trunk/drivers/power/collie_battery.c b/trunk/drivers/power/collie_battery.c index 548d263b1ad0..039f41ae217d 100644 --- a/trunk/drivers/power/collie_battery.c +++ b/trunk/drivers/power/collie_battery.c @@ -295,7 +295,7 @@ static struct { static int collie_bat_suspend(struct ucb1x00_dev *dev, pm_message_t state) { /* flush all pending status updates */ - flush_work_sync(&bat_work); + flush_scheduled_work(); return 0; } @@ -362,7 +362,7 @@ static int __devinit collie_bat_probe(struct ucb1x00_dev *dev) err_psy_reg_main: /* see comment in collie_bat_remove */ - cancel_work_sync(&bat_work); + flush_scheduled_work(); i--; err_gpio: @@ -382,11 +382,12 @@ static void __devexit collie_bat_remove(struct ucb1x00_dev *dev) power_supply_unregister(&collie_bat_main.psy); /* - * Now cancel the bat_work. We won't get any more schedules, - * since all sources (isr and external_power_changed) are - * unregistered now. + * now flush all pending work. + * we won't get any more schedules, since all + * sources (isr and external_power_changed) + * are unregistered now. */ - cancel_work_sync(&bat_work); + flush_scheduled_work(); for (i = ARRAY_SIZE(gpios) - 1; i >= 0; i--) gpio_free(gpios[i].gpio); diff --git a/trunk/drivers/power/ds2760_battery.c b/trunk/drivers/power/ds2760_battery.c index e534290f3256..e7f89785beef 100644 --- a/trunk/drivers/power/ds2760_battery.c +++ b/trunk/drivers/power/ds2760_battery.c @@ -212,7 +212,7 @@ static int ds2760_battery_read_status(struct ds2760_device_info *di) if (di->rem_capacity > 100) di->rem_capacity = 100; - if (di->current_uA < -100L) + if (di->current_uA >= 100L) di->life_sec = -((di->accum_current_uAh - di->empty_uAh) * 36L) / (di->current_uA / 100L); else diff --git a/trunk/drivers/power/gpio-charger.c b/trunk/drivers/power/gpio-charger.c deleted file mode 100644 index 25b88ac1d44c..000000000000 --- a/trunk/drivers/power/gpio-charger.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (C) 2010, Lars-Peter Clausen - * Driver for chargers which report their online status through a GPIO pin - * - * 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. - * - * 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 - -struct gpio_charger { - const struct gpio_charger_platform_data *pdata; - unsigned int irq; - - struct power_supply charger; -}; - -static irqreturn_t gpio_charger_irq(int irq, void *devid) -{ - struct power_supply *charger = devid; - - power_supply_changed(charger); - - return IRQ_HANDLED; -} - -static inline struct gpio_charger *psy_to_gpio_charger(struct power_supply *psy) -{ - return container_of(psy, struct gpio_charger, charger); -} - -static int gpio_charger_get_property(struct power_supply *psy, - enum power_supply_property psp, union power_supply_propval *val) -{ - struct gpio_charger *gpio_charger = psy_to_gpio_charger(psy); - const struct gpio_charger_platform_data *pdata = gpio_charger->pdata; - - switch (psp) { - case POWER_SUPPLY_PROP_ONLINE: - val->intval = gpio_get_value(pdata->gpio); - val->intval ^= pdata->gpio_active_low; - break; - default: - return -EINVAL; - } - - return 0; -} - -static enum power_supply_property gpio_charger_properties[] = { - POWER_SUPPLY_PROP_ONLINE, -}; - -static int __devinit gpio_charger_probe(struct platform_device *pdev) -{ - const struct gpio_charger_platform_data *pdata = pdev->dev.platform_data; - struct gpio_charger *gpio_charger; - struct power_supply *charger; - int ret; - int irq; - - if (!pdata) { - dev_err(&pdev->dev, "No platform data\n"); - return -EINVAL; - } - - if (!gpio_is_valid(pdata->gpio)) { - dev_err(&pdev->dev, "Invalid gpio pin\n"); - return -EINVAL; - } - - gpio_charger = kzalloc(sizeof(*gpio_charger), GFP_KERNEL); - if (!gpio_charger) { - dev_err(&pdev->dev, "Failed to alloc driver structure\n"); - return -ENOMEM; - } - - charger = &gpio_charger->charger; - - charger->name = pdata->name ? pdata->name : "gpio-charger"; - charger->type = pdata->type; - charger->properties = gpio_charger_properties; - charger->num_properties = ARRAY_SIZE(gpio_charger_properties); - charger->get_property = gpio_charger_get_property; - charger->supplied_to = pdata->supplied_to; - charger->num_supplicants = pdata->num_supplicants; - - ret = gpio_request(pdata->gpio, dev_name(&pdev->dev)); - if (ret) { - dev_err(&pdev->dev, "Failed to request gpio pin: %d\n", ret); - goto err_free; - } - ret = gpio_direction_input(pdata->gpio); - if (ret) { - dev_err(&pdev->dev, "Failed to set gpio to input: %d\n", ret); - goto err_gpio_free; - } - - gpio_charger->pdata = pdata; - - ret = power_supply_register(&pdev->dev, charger); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to register power supply: %d\n", - ret); - goto err_gpio_free; - } - - irq = gpio_to_irq(pdata->gpio); - if (irq > 0) { - ret = request_any_context_irq(irq, gpio_charger_irq, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - dev_name(&pdev->dev), charger); - if (ret) - dev_warn(&pdev->dev, "Failed to request irq: %d\n", ret); - else - gpio_charger->irq = irq; - } - - platform_set_drvdata(pdev, gpio_charger); - - return 0; - -err_gpio_free: - gpio_free(pdata->gpio); -err_free: - kfree(gpio_charger); - return ret; -} - -static int __devexit gpio_charger_remove(struct platform_device *pdev) -{ - struct gpio_charger *gpio_charger = platform_get_drvdata(pdev); - - if (gpio_charger->irq) - free_irq(gpio_charger->irq, &gpio_charger->charger); - - power_supply_unregister(&gpio_charger->charger); - - gpio_free(gpio_charger->pdata->gpio); - - platform_set_drvdata(pdev, NULL); - kfree(gpio_charger); - - return 0; -} - -static struct platform_driver gpio_charger_driver = { - .probe = gpio_charger_probe, - .remove = __devexit_p(gpio_charger_remove), - .driver = { - .name = "gpio-charger", - .owner = THIS_MODULE, - }, -}; - -static int __init gpio_charger_init(void) -{ - return platform_driver_register(&gpio_charger_driver); -} -module_init(gpio_charger_init); - -static void __exit gpio_charger_exit(void) -{ - platform_driver_unregister(&gpio_charger_driver); -} -module_exit(gpio_charger_exit); - -MODULE_AUTHOR("Lars-Peter Clausen "); -MODULE_DESCRIPTION("Driver for chargers which report their online status through a GPIO"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:gpio-charger"); diff --git a/trunk/drivers/power/intel_mid_battery.c b/trunk/drivers/power/intel_mid_battery.c index bce3a01da2f0..36cf402c0677 100644 --- a/trunk/drivers/power/intel_mid_battery.c +++ b/trunk/drivers/power/intel_mid_battery.c @@ -765,7 +765,7 @@ static int __devexit platform_pmic_battery_remove(struct platform_device *pdev) power_supply_unregister(&pbi->usb); power_supply_unregister(&pbi->batt); - cancel_work_sync(&pbi->handler); + flush_scheduled_work(); kfree(pbi); return 0; } diff --git a/trunk/drivers/power/isp1704_charger.c b/trunk/drivers/power/isp1704_charger.c index 2ad9b14a5ce3..72512185f3e2 100644 --- a/trunk/drivers/power/isp1704_charger.c +++ b/trunk/drivers/power/isp1704_charger.c @@ -59,60 +59,10 @@ struct isp1704_charger { struct notifier_block nb; struct work_struct work; - /* properties */ - char model[8]; + char model[7]; unsigned present:1; - unsigned online:1; - unsigned current_max; - - /* temp storage variables */ - unsigned long event; - unsigned max_power; }; -/* - * Determine is the charging port DCP (dedicated charger) or CDP (Host/HUB - * chargers). - * - * REVISIT: The method is defined in Battery Charging Specification and is - * applicable to any ULPI transceiver. Nothing isp170x specific here. - */ -static inline int isp1704_charger_type(struct isp1704_charger *isp) -{ - u8 reg; - u8 func_ctrl; - u8 otg_ctrl; - int type = POWER_SUPPLY_TYPE_USB_DCP; - - func_ctrl = otg_io_read(isp->otg, ULPI_FUNC_CTRL); - otg_ctrl = otg_io_read(isp->otg, ULPI_OTG_CTRL); - - /* disable pulldowns */ - reg = ULPI_OTG_CTRL_DM_PULLDOWN | ULPI_OTG_CTRL_DP_PULLDOWN; - otg_io_write(isp->otg, ULPI_CLR(ULPI_OTG_CTRL), reg); - - /* full speed */ - otg_io_write(isp->otg, ULPI_CLR(ULPI_FUNC_CTRL), - ULPI_FUNC_CTRL_XCVRSEL_MASK); - otg_io_write(isp->otg, ULPI_SET(ULPI_FUNC_CTRL), - ULPI_FUNC_CTRL_FULL_SPEED); - - /* Enable strong pull-up on DP (1.5K) and reset */ - reg = ULPI_FUNC_CTRL_TERMSELECT | ULPI_FUNC_CTRL_RESET; - otg_io_write(isp->otg, ULPI_SET(ULPI_FUNC_CTRL), reg); - usleep_range(1000, 2000); - - reg = otg_io_read(isp->otg, ULPI_DEBUG); - if ((reg & 3) != 3) - type = POWER_SUPPLY_TYPE_USB_CDP; - - /* recover original state */ - otg_io_write(isp->otg, ULPI_FUNC_CTRL, func_ctrl); - otg_io_write(isp->otg, ULPI_OTG_CTRL, otg_ctrl); - - return type; -} - /* * ISP1704 detects PS/2 adapters as charger. To make sure the detected charger * is actually a dedicated charger, the following steps need to be taken. @@ -177,19 +127,16 @@ static inline int isp1704_charger_verify(struct isp1704_charger *isp) static inline int isp1704_charger_detect(struct isp1704_charger *isp) { unsigned long timeout; - u8 pwr_ctrl; + u8 r; int ret = 0; - pwr_ctrl = otg_io_read(isp->otg, ISP1704_PWR_CTRL); - /* set SW control bit in PWR_CTRL register */ otg_io_write(isp->otg, ISP1704_PWR_CTRL, ISP1704_PWR_CTRL_SWCTRL); /* enable manual charger detection */ - otg_io_write(isp->otg, ULPI_SET(ISP1704_PWR_CTRL), - ISP1704_PWR_CTRL_SWCTRL - | ISP1704_PWR_CTRL_DPVSRC_EN); + r = (ISP1704_PWR_CTRL_SWCTRL | ISP1704_PWR_CTRL_DPVSRC_EN); + otg_io_write(isp->otg, ULPI_SET(ISP1704_PWR_CTRL), r); usleep_range(1000, 2000); timeout = jiffies + msecs_to_jiffies(300); @@ -200,10 +147,7 @@ static inline int isp1704_charger_detect(struct isp1704_charger *isp) ret = isp1704_charger_verify(isp); break; } - } while (!time_after(jiffies, timeout) && isp->online); - - /* recover original state */ - otg_io_write(isp->otg, ISP1704_PWR_CTRL, pwr_ctrl); + } while (!time_after(jiffies, timeout)); return ret; } @@ -211,92 +155,52 @@ static inline int isp1704_charger_detect(struct isp1704_charger *isp) static void isp1704_charger_work(struct work_struct *data) { int detect; - unsigned long event; - unsigned power; struct isp1704_charger *isp = container_of(data, struct isp1704_charger, work); - static DEFINE_MUTEX(lock); - - event = isp->event; - power = isp->max_power; - - mutex_lock(&lock); - - switch (event) { - case USB_EVENT_VBUS: - isp->online = true; - /* detect charger */ - detect = isp1704_charger_detect(isp); + /* + * FIXME Only supporting dedicated chargers even though isp1704 can + * detect HUB and HOST chargers. If the device has already been + * enumerated, the detection will break the connection. + */ + if (isp->otg->state != OTG_STATE_B_IDLE) + return; - if (detect) { - isp->present = detect; - isp->psy.type = isp1704_charger_type(isp); - } + /* disable data pullups */ + if (isp->otg->gadget) + usb_gadget_disconnect(isp->otg->gadget); - switch (isp->psy.type) { - case POWER_SUPPLY_TYPE_USB_DCP: - isp->current_max = 1800; - break; - case POWER_SUPPLY_TYPE_USB_CDP: - /* - * Only 500mA here or high speed chirp - * handshaking may break - */ - isp->current_max = 500; - /* FALLTHROUGH */ - case POWER_SUPPLY_TYPE_USB: - default: - /* enable data pullups */ - if (isp->otg->gadget) - usb_gadget_connect(isp->otg->gadget); - } - break; - case USB_EVENT_NONE: - isp->online = false; - isp->current_max = 0; - isp->present = 0; - isp->current_max = 0; - isp->psy.type = POWER_SUPPLY_TYPE_USB; - - /* - * Disable data pullups. We need to prevent the controller from - * enumerating. - * - * FIXME: This is here to allow charger detection with Host/HUB - * chargers. The pullups may be enabled elsewhere, so this can - * not be the final solution. - */ - if (isp->otg->gadget) - usb_gadget_disconnect(isp->otg->gadget); - break; - case USB_EVENT_ENUMERATED: - if (isp->present) - isp->current_max = 1800; - else - isp->current_max = power; - break; - default: - goto out; + /* detect charger */ + detect = isp1704_charger_detect(isp); + if (detect) { + isp->present = detect; + power_supply_changed(&isp->psy); } - power_supply_changed(&isp->psy); -out: - mutex_unlock(&lock); + /* enable data pullups */ + if (isp->otg->gadget) + usb_gadget_connect(isp->otg->gadget); } static int isp1704_notifier_call(struct notifier_block *nb, - unsigned long event, void *power) + unsigned long event, void *unused) { struct isp1704_charger *isp = container_of(nb, struct isp1704_charger, nb); - isp->event = event; - - if (power) - isp->max_power = *((unsigned *)power); - - schedule_work(&isp->work); + switch (event) { + case USB_EVENT_VBUS: + schedule_work(&isp->work); + break; + case USB_EVENT_NONE: + if (isp->present) { + isp->present = 0; + power_supply_changed(&isp->psy); + } + break; + default: + return NOTIFY_DONE; + } return NOTIFY_OK; } @@ -312,12 +216,6 @@ static int isp1704_charger_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_PRESENT: val->intval = isp->present; break; - case POWER_SUPPLY_PROP_ONLINE: - val->intval = isp->online; - break; - case POWER_SUPPLY_PROP_CURRENT_MAX: - val->intval = isp->current_max; - break; case POWER_SUPPLY_PROP_MODEL_NAME: val->strval = isp->model; break; @@ -332,8 +230,6 @@ static int isp1704_charger_get_property(struct power_supply *psy, static enum power_supply_property power_props[] = { POWER_SUPPLY_PROP_PRESENT, - POWER_SUPPLY_PROP_ONLINE, - POWER_SUPPLY_PROP_CURRENT_MAX, POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_MANUFACTURER, }; @@ -391,13 +287,13 @@ static int __devinit isp1704_charger_probe(struct platform_device *pdev) if (!isp->otg) goto fail0; - isp->dev = &pdev->dev; - platform_set_drvdata(pdev, isp); - ret = isp1704_test_ulpi(isp); if (ret < 0) goto fail1; + isp->dev = &pdev->dev; + platform_set_drvdata(pdev, isp); + isp->psy.name = "isp1704"; isp->psy.type = POWER_SUPPLY_TYPE_USB; isp->psy.properties = power_props; @@ -422,23 +318,6 @@ static int __devinit isp1704_charger_probe(struct platform_device *pdev) dev_info(isp->dev, "registered with product id %s\n", isp->model); - /* - * Taking over the D+ pullup. - * - * FIXME: The device will be disconnected if it was already - * enumerated. The charger driver should be always loaded before any - * gadget is loaded. - */ - if (isp->otg->gadget) - usb_gadget_disconnect(isp->otg->gadget); - - /* Detect charger if VBUS is valid (the cable was already plugged). */ - ret = otg_io_read(isp->otg, ULPI_USB_INT_STS); - if ((ret & ULPI_INT_VBUS_VALID) && !isp->otg->default_a) { - isp->event = USB_EVENT_VBUS; - schedule_work(&isp->work); - } - return 0; fail2: power_supply_unregister(&isp->psy); diff --git a/trunk/drivers/power/jz4740-battery.c b/trunk/drivers/power/jz4740-battery.c index 02414db6a94c..a8108a73593e 100644 --- a/trunk/drivers/power/jz4740-battery.c +++ b/trunk/drivers/power/jz4740-battery.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -48,8 +47,6 @@ struct jz_battery { struct power_supply battery; struct delayed_work work; - - struct mutex lock; }; static inline struct jz_battery *psy_to_jz_battery(struct power_supply *psy) @@ -71,8 +68,6 @@ static long jz_battery_read_voltage(struct jz_battery *battery) unsigned long val; long voltage; - mutex_lock(&battery->lock); - INIT_COMPLETION(battery->read_completion); enable_irq(battery->irq); @@ -96,8 +91,6 @@ static long jz_battery_read_voltage(struct jz_battery *battery) battery->cell->disable(battery->pdev); disable_irq(battery->irq); - mutex_unlock(&battery->lock); - return voltage; } @@ -247,11 +240,6 @@ static int __devinit jz_battery_probe(struct platform_device *pdev) struct jz_battery *jz_battery; struct power_supply *battery; - if (!pdata) { - dev_err(&pdev->dev, "No platform_data supplied\n"); - return -ENXIO; - } - jz_battery = kzalloc(sizeof(*jz_battery), GFP_KERNEL); if (!jz_battery) { dev_err(&pdev->dev, "Failed to allocate driver structure\n"); @@ -303,7 +291,6 @@ static int __devinit jz_battery_probe(struct platform_device *pdev) jz_battery->pdev = pdev; init_completion(&jz_battery->read_completion); - mutex_init(&jz_battery->lock); INIT_DELAYED_WORK(&jz_battery->work, jz_battery_work); diff --git a/trunk/drivers/power/max17042_battery.c b/trunk/drivers/power/max17042_battery.c deleted file mode 100644 index c5c8805156cb..000000000000 --- a/trunk/drivers/power/max17042_battery.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Fuel gauge driver for Maxim 17042 / 8966 / 8997 - * Note that Maxim 8966 and 8997 are mfd and this is its subdevice. - * - * Copyright (C) 2011 Samsung Electronics - * MyungJoo Ham - * - * 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 - * - * This driver is based on max17040_battery.c - */ - -#include -#include -#include -#include -#include -#include - -enum max17042_register { - MAX17042_STATUS = 0x00, - MAX17042_VALRT_Th = 0x01, - MAX17042_TALRT_Th = 0x02, - MAX17042_SALRT_Th = 0x03, - MAX17042_AtRate = 0x04, - MAX17042_RepCap = 0x05, - MAX17042_RepSOC = 0x06, - MAX17042_Age = 0x07, - MAX17042_TEMP = 0x08, - MAX17042_VCELL = 0x09, - MAX17042_Current = 0x0A, - MAX17042_AvgCurrent = 0x0B, - MAX17042_Qresidual = 0x0C, - MAX17042_SOC = 0x0D, - MAX17042_AvSOC = 0x0E, - MAX17042_RemCap = 0x0F, - MAX17402_FullCAP = 0x10, - MAX17042_TTE = 0x11, - MAX17042_V_empty = 0x12, - - MAX17042_RSLOW = 0x14, - - MAX17042_AvgTA = 0x16, - MAX17042_Cycles = 0x17, - MAX17042_DesignCap = 0x18, - MAX17042_AvgVCELL = 0x19, - MAX17042_MinMaxTemp = 0x1A, - MAX17042_MinMaxVolt = 0x1B, - MAX17042_MinMaxCurr = 0x1C, - MAX17042_CONFIG = 0x1D, - MAX17042_ICHGTerm = 0x1E, - MAX17042_AvCap = 0x1F, - MAX17042_ManName = 0x20, - MAX17042_DevName = 0x21, - MAX17042_DevChem = 0x22, - - MAX17042_TempNom = 0x24, - MAX17042_TempCold = 0x25, - MAX17042_TempHot = 0x26, - MAX17042_AIN = 0x27, - MAX17042_LearnCFG = 0x28, - MAX17042_SHFTCFG = 0x29, - MAX17042_RelaxCFG = 0x2A, - MAX17042_MiscCFG = 0x2B, - MAX17042_TGAIN = 0x2C, - MAx17042_TOFF = 0x2D, - MAX17042_CGAIN = 0x2E, - MAX17042_COFF = 0x2F, - - MAX17042_Q_empty = 0x33, - MAX17042_T_empty = 0x34, - - MAX17042_RCOMP0 = 0x38, - MAX17042_TempCo = 0x39, - MAX17042_Rx = 0x3A, - MAX17042_T_empty0 = 0x3B, - MAX17042_TaskPeriod = 0x3C, - MAX17042_FSTAT = 0x3D, - - MAX17042_SHDNTIMER = 0x3F, - - MAX17042_VFRemCap = 0x4A, - - MAX17042_QH = 0x4D, - MAX17042_QL = 0x4E, -}; - -struct max17042_chip { - struct i2c_client *client; - struct power_supply battery; - struct max17042_platform_data *pdata; -}; - -static int max17042_write_reg(struct i2c_client *client, u8 reg, u16 value) -{ - int ret = i2c_smbus_write_word_data(client, reg, value); - - if (ret < 0) - dev_err(&client->dev, "%s: err %d\n", __func__, ret); - - return ret; -} - -static int max17042_read_reg(struct i2c_client *client, u8 reg) -{ - int ret = i2c_smbus_read_word_data(client, reg); - - if (ret < 0) - dev_err(&client->dev, "%s: err %d\n", __func__, ret); - - return ret; -} - -static enum power_supply_property max17042_battery_props[] = { - POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_VOLTAGE_AVG, - POWER_SUPPLY_PROP_CAPACITY, -}; - -static int max17042_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct max17042_chip *chip = container_of(psy, - struct max17042_chip, battery); - - switch (psp) { - case POWER_SUPPLY_PROP_VOLTAGE_NOW: - val->intval = max17042_read_reg(chip->client, - MAX17042_VCELL) * 83; /* 1000 / 12 = 83 */ - break; - case POWER_SUPPLY_PROP_VOLTAGE_AVG: - val->intval = max17042_read_reg(chip->client, - MAX17042_AvgVCELL) * 83; - break; - case POWER_SUPPLY_PROP_CAPACITY: - val->intval = max17042_read_reg(chip->client, - MAX17042_SOC) / 256; - break; - default: - return -EINVAL; - } - return 0; -} - -static int __devinit max17042_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct max17042_chip *chip; - int ret; - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) - return -EIO; - - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (!chip) - return -ENOMEM; - - chip->client = client; - chip->pdata = client->dev.platform_data; - - i2c_set_clientdata(client, chip); - - chip->battery.name = "max17042_battery"; - chip->battery.type = POWER_SUPPLY_TYPE_BATTERY; - chip->battery.get_property = max17042_get_property; - chip->battery.properties = max17042_battery_props; - chip->battery.num_properties = ARRAY_SIZE(max17042_battery_props); - - ret = power_supply_register(&client->dev, &chip->battery); - if (ret) { - dev_err(&client->dev, "failed: power supply register\n"); - i2c_set_clientdata(client, NULL); - kfree(chip); - return ret; - } - - if (!chip->pdata->enable_current_sense) { - max17042_write_reg(client, MAX17042_CGAIN, 0x0000); - max17042_write_reg(client, MAX17042_MiscCFG, 0x0003); - max17042_write_reg(client, MAX17042_LearnCFG, 0x0007); - } - - return 0; -} - -static int __devexit max17042_remove(struct i2c_client *client) -{ - struct max17042_chip *chip = i2c_get_clientdata(client); - - power_supply_unregister(&chip->battery); - i2c_set_clientdata(client, NULL); - kfree(chip); - return 0; -} - -static const struct i2c_device_id max17042_id[] = { - { "max17042", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, max17042_id); - -static struct i2c_driver max17042_i2c_driver = { - .driver = { - .name = "max17042", - }, - .probe = max17042_probe, - .remove = __devexit_p(max17042_remove), - .id_table = max17042_id, -}; - -static int __init max17042_init(void) -{ - return i2c_add_driver(&max17042_i2c_driver); -} -module_init(max17042_init); - -static void __exit max17042_exit(void) -{ - i2c_del_driver(&max17042_i2c_driver); -} -module_exit(max17042_exit); - -MODULE_AUTHOR("MyungJoo Ham "); -MODULE_DESCRIPTION("MAX17042 Fuel Gauge"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/power/olpc_battery.c b/trunk/drivers/power/olpc_battery.c index 0b0ff3a936a6..5bc1dcf7785e 100644 --- a/trunk/drivers/power/olpc_battery.c +++ b/trunk/drivers/power/olpc_battery.c @@ -201,72 +201,6 @@ static int olpc_bat_get_tech(union power_supply_propval *val) return ret; } -static int olpc_bat_get_charge_full_design(union power_supply_propval *val) -{ - uint8_t ec_byte; - union power_supply_propval tech; - int ret, mfr; - - ret = olpc_bat_get_tech(&tech); - if (ret) - return ret; - - ec_byte = BAT_ADDR_MFR_TYPE; - ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1); - if (ret) - return ret; - - mfr = ec_byte >> 4; - - switch (tech.intval) { - case POWER_SUPPLY_TECHNOLOGY_NiMH: - switch (mfr) { - case 1: /* Gold Peak */ - val->intval = 3000000*.8; - break; - default: - return -EIO; - } - break; - - case POWER_SUPPLY_TECHNOLOGY_LiFe: - switch (mfr) { - case 1: /* Gold Peak */ - val->intval = 2800000; - break; - case 2: /* BYD */ - val->intval = 3100000; - break; - default: - return -EIO; - } - break; - - default: - return -EIO; - } - - return ret; -} - -static int olpc_bat_get_charge_now(union power_supply_propval *val) -{ - uint8_t soc; - union power_supply_propval full; - int ret; - - ret = olpc_ec_cmd(EC_BAT_SOC, NULL, 0, &soc, 1); - if (ret) - return ret; - - ret = olpc_bat_get_charge_full_design(&full); - if (ret) - return ret; - - val->intval = soc * (full.intval / 100); - return 0; -} - /********************************************************************* * Battery properties *********************************************************************/ @@ -333,7 +267,6 @@ static int olpc_bat_get_property(struct power_supply *psy, return ret; break; case POWER_SUPPLY_PROP_VOLTAGE_AVG: - case POWER_SUPPLY_PROP_VOLTAGE_NOW: ret = olpc_ec_cmd(EC_BAT_VOLTAGE, NULL, 0, (void *)&ec_word, 2); if (ret) return ret; @@ -341,7 +274,6 @@ static int olpc_bat_get_property(struct power_supply *psy, val->intval = (s16)be16_to_cpu(ec_word) * 9760L / 32; break; case POWER_SUPPLY_PROP_CURRENT_AVG: - case POWER_SUPPLY_PROP_CURRENT_NOW: ret = olpc_ec_cmd(EC_BAT_CURRENT, NULL, 0, (void *)&ec_word, 2); if (ret) return ret; @@ -362,16 +294,6 @@ static int olpc_bat_get_property(struct power_supply *psy, else val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; break; - case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: - ret = olpc_bat_get_charge_full_design(val); - if (ret) - return ret; - break; - case POWER_SUPPLY_PROP_CHARGE_NOW: - ret = olpc_bat_get_charge_now(val); - if (ret) - return ret; - break; case POWER_SUPPLY_PROP_TEMP: ret = olpc_ec_cmd(EC_BAT_TEMP, NULL, 0, (void *)&ec_word, 2); if (ret) @@ -409,20 +331,16 @@ static int olpc_bat_get_property(struct power_supply *psy, return ret; } -static enum power_supply_property olpc_xo1_bat_props[] = { +static enum power_supply_property olpc_bat_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_CHARGE_TYPE, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_PROP_TECHNOLOGY, POWER_SUPPLY_PROP_VOLTAGE_AVG, - POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_CURRENT_AVG, - POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_CAPACITY, POWER_SUPPLY_PROP_CAPACITY_LEVEL, - POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, - POWER_SUPPLY_PROP_CHARGE_NOW, POWER_SUPPLY_PROP_TEMP, POWER_SUPPLY_PROP_TEMP_AMBIENT, POWER_SUPPLY_PROP_MANUFACTURER, @@ -430,27 +348,6 @@ static enum power_supply_property olpc_xo1_bat_props[] = { POWER_SUPPLY_PROP_CHARGE_COUNTER, }; -/* XO-1.5 does not have ambient temperature property */ -static enum power_supply_property olpc_xo15_bat_props[] = { - POWER_SUPPLY_PROP_STATUS, - POWER_SUPPLY_PROP_CHARGE_TYPE, - POWER_SUPPLY_PROP_PRESENT, - POWER_SUPPLY_PROP_HEALTH, - POWER_SUPPLY_PROP_TECHNOLOGY, - POWER_SUPPLY_PROP_VOLTAGE_AVG, - POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_CURRENT_AVG, - POWER_SUPPLY_PROP_CURRENT_NOW, - POWER_SUPPLY_PROP_CAPACITY, - POWER_SUPPLY_PROP_CAPACITY_LEVEL, - POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, - POWER_SUPPLY_PROP_CHARGE_NOW, - POWER_SUPPLY_PROP_TEMP, - POWER_SUPPLY_PROP_MANUFACTURER, - POWER_SUPPLY_PROP_SERIAL_NUMBER, - POWER_SUPPLY_PROP_CHARGE_COUNTER, -}; - /* EEPROM reading goes completely around the power_supply API, sadly */ #define EEPROM_START 0x20 @@ -522,6 +419,8 @@ static struct device_attribute olpc_bat_error = { static struct platform_device *bat_pdev; static struct power_supply olpc_bat = { + .properties = olpc_bat_props, + .num_properties = ARRAY_SIZE(olpc_bat_props), .get_property = olpc_bat_get_property, .use_for_apm = 1, }; @@ -567,13 +466,6 @@ static int __init olpc_bat_init(void) goto ac_failed; olpc_bat.name = bat_pdev->name; - if (olpc_board_at_least(olpc_board_pre(0xd0))) { /* XO-1.5 */ - olpc_bat.properties = olpc_xo15_bat_props; - olpc_bat.num_properties = ARRAY_SIZE(olpc_xo15_bat_props); - } else { /* XO-1 */ - olpc_bat.properties = olpc_xo1_bat_props; - olpc_bat.num_properties = ARRAY_SIZE(olpc_xo1_bat_props); - } ret = power_supply_register(&bat_pdev->dev, &olpc_bat); if (ret) diff --git a/trunk/drivers/power/power_supply_core.c b/trunk/drivers/power/power_supply_core.c index 970f7335d3a7..91606bb55318 100644 --- a/trunk/drivers/power/power_supply_core.c +++ b/trunk/drivers/power/power_supply_core.c @@ -190,10 +190,10 @@ int power_supply_register(struct device *parent, struct power_supply *psy) goto success; create_triggers_failed: - device_del(dev); + device_unregister(psy->dev); kobject_set_name_failed: device_add_failed: - put_device(dev); + kfree(dev); success: return rc; } @@ -201,7 +201,7 @@ EXPORT_SYMBOL_GPL(power_supply_register); void power_supply_unregister(struct power_supply *psy) { - cancel_work_sync(&psy->changed_work); + flush_scheduled_work(); power_supply_remove_triggers(psy); device_unregister(psy->dev); } diff --git a/trunk/drivers/power/s3c_adc_battery.c b/trunk/drivers/power/s3c_adc_battery.c index 4255f2358b13..4a8ae3935b3b 100644 --- a/trunk/drivers/power/s3c_adc_battery.c +++ b/trunk/drivers/power/s3c_adc_battery.c @@ -112,13 +112,6 @@ static int calc_full_volt(int volt_val, int cur_val, int impedance) return volt_val + cur_val * impedance / 1000; } -static int charge_finished(struct s3c_adc_bat *bat) -{ - return bat->pdata->gpio_inverted ? - !gpio_get_value(bat->pdata->gpio_charge_finished) : - gpio_get_value(bat->pdata->gpio_charge_finished); -} - static int s3c_adc_bat_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) @@ -147,7 +140,7 @@ static int s3c_adc_bat_get_property(struct power_supply *psy, if (bat->cable_plugged && ((bat->pdata->gpio_charge_finished < 0) || - !charge_finished(bat))) { + !gpio_get_value(bat->pdata->gpio_charge_finished))) { lut = bat->pdata->lut_acin; lut_size = bat->pdata->lut_acin_cnt; } @@ -243,7 +236,8 @@ static void s3c_adc_bat_work(struct work_struct *work) } } else { if ((bat->pdata->gpio_charge_finished >= 0) && is_plugged) { - is_charged = charge_finished(&main_bat); + is_charged = gpio_get_value( + main_bat.pdata->gpio_charge_finished); if (is_charged) { if (bat->pdata->disable_charger) bat->pdata->disable_charger(); diff --git a/trunk/drivers/power/tosa_battery.c b/trunk/drivers/power/tosa_battery.c index 53f0d3524fcd..ee04936b2db5 100644 --- a/trunk/drivers/power/tosa_battery.c +++ b/trunk/drivers/power/tosa_battery.c @@ -332,7 +332,7 @@ static struct { static int tosa_bat_suspend(struct platform_device *dev, pm_message_t state) { /* flush all pending status updates */ - flush_work_sync(&bat_work); + flush_scheduled_work(); return 0; } @@ -422,7 +422,7 @@ static int __devinit tosa_bat_probe(struct platform_device *dev) err_psy_reg_main: /* see comment in tosa_bat_remove */ - cancel_work_sync(&bat_work); + flush_scheduled_work(); i--; err_gpio: @@ -445,11 +445,12 @@ static int __devexit tosa_bat_remove(struct platform_device *dev) power_supply_unregister(&tosa_bat_main.psy); /* - * Now cancel the bat_work. We won't get any more schedules, - * since all sources (isr and external_power_changed) are - * unregistered now. + * now flush all pending work. + * we won't get any more schedules, since all + * sources (isr and external_power_changed) + * are unregistered now. */ - cancel_work_sync(&bat_work); + flush_scheduled_work(); for (i = ARRAY_SIZE(gpios) - 1; i >= 0; i--) gpio_free(gpios[i].gpio); diff --git a/trunk/drivers/power/wm97xx_battery.c b/trunk/drivers/power/wm97xx_battery.c index 156559e56fa5..5071d85ec12d 100644 --- a/trunk/drivers/power/wm97xx_battery.c +++ b/trunk/drivers/power/wm97xx_battery.c @@ -147,7 +147,7 @@ static irqreturn_t wm97xx_chrg_irq(int irq, void *data) #ifdef CONFIG_PM static int wm97xx_bat_suspend(struct device *dev) { - flush_work_sync(&bat_work); + flush_scheduled_work(); return 0; } @@ -273,7 +273,7 @@ static int __devexit wm97xx_bat_remove(struct platform_device *dev) free_irq(gpio_to_irq(pdata->charge_gpio), dev); gpio_free(pdata->charge_gpio); } - cancel_work_sync(&bat_work); + flush_scheduled_work(); power_supply_unregister(&bat_ps); kfree(prop); return 0; diff --git a/trunk/drivers/power/z2_battery.c b/trunk/drivers/power/z2_battery.c index e5ed52d71937..85064a9f649e 100644 --- a/trunk/drivers/power/z2_battery.c +++ b/trunk/drivers/power/z2_battery.c @@ -254,7 +254,7 @@ static int __devexit z2_batt_remove(struct i2c_client *client) struct z2_charger *charger = i2c_get_clientdata(client); struct z2_battery_info *info = charger->info; - cancel_work_sync(&charger->bat_work); + flush_scheduled_work(); power_supply_unregister(&charger->batt_ps); kfree(charger->batt_ps.properties); @@ -271,9 +271,7 @@ static int __devexit z2_batt_remove(struct i2c_client *client) #ifdef CONFIG_PM static int z2_batt_suspend(struct i2c_client *client, pm_message_t state) { - struct z2_charger *charger = i2c_get_clientdata(client); - - flush_work_sync(&charger->bat_work); + flush_scheduled_work(); return 0; } diff --git a/trunk/drivers/regulator/max8998.c b/trunk/drivers/regulator/max8998.c index 0ec49ca527a8..7568df6122ab 100644 --- a/trunk/drivers/regulator/max8998.c +++ b/trunk/drivers/regulator/max8998.c @@ -424,9 +424,6 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev, } } - if (pdata->buck_voltage_lock) - return -EINVAL; - /* no predefine regulator found */ max8998->buck1_idx = (buck1_last_val % 2) + 2; dev_dbg(max8998->dev, "max8998->buck1_idx:%d\n", @@ -454,26 +451,18 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev, "BUCK2, i:%d buck2_vol1:%d, buck2_vol2:%d\n" , i, max8998->buck2_vol[0], max8998->buck2_vol[1]); if (gpio_is_valid(pdata->buck2_set3)) { - - /* check if requested voltage */ - /* value is already defined */ - for (j = 0; j < ARRAY_SIZE(max8998->buck2_vol); j++) { - if (max8998->buck2_vol[j] == i) { - max8998->buck2_idx = j; - buck2_gpio_set(pdata->buck2_set3, j); - goto buck2_exit; - } + if (max8998->buck2_vol[0] == i) { + max8998->buck1_idx = 0; + buck2_gpio_set(pdata->buck2_set3, 0); + } else { + max8998->buck1_idx = 1; + ret = max8998_get_voltage_register(rdev, ®, + &shift, + &mask); + ret = max8998_write_reg(i2c, reg, i); + max8998->buck2_vol[1] = i; + buck2_gpio_set(pdata->buck2_set3, 1); } - - if (pdata->buck_voltage_lock) - return -EINVAL; - - max8998_get_voltage_register(rdev, - ®, &shift, &mask); - ret = max8998_write_reg(i2c, reg, i); - max8998->buck2_vol[max8998->buck2_idx] = i; - buck2_gpio_set(pdata->buck2_set3, max8998->buck2_idx); -buck2_exit: dev_dbg(max8998->dev, "%s: SET3:%d\n", i2c->name, gpio_get_value(pdata->buck2_set3)); } else { @@ -718,9 +707,6 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) platform_set_drvdata(pdev, max8998); i2c = max8998->iodev->i2c; - max8998->buck1_idx = pdata->buck1_default_idx; - max8998->buck2_idx = pdata->buck2_default_idx; - /* NOTE: */ /* For unused GPIO NOT marked as -1 (thereof equal to 0) WARN_ON */ /* will be displayed */ @@ -753,46 +739,23 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) i = 0; while (buck12_voltage_map_desc.min + buck12_voltage_map_desc.step*i - < (pdata->buck1_voltage1 / 1000)) + != (pdata->buck1_max_voltage1 / 1000)) i++; + printk(KERN_ERR "i:%d, buck1_idx:%d\n", i, max8998->buck1_idx); max8998->buck1_vol[0] = i; ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1, i); - if (ret) - return ret; /* Set predefined value for BUCK1 register 2 */ i = 0; while (buck12_voltage_map_desc.min + buck12_voltage_map_desc.step*i - < (pdata->buck1_voltage2 / 1000)) + != (pdata->buck1_max_voltage2 / 1000)) i++; max8998->buck1_vol[1] = i; - ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE2, i); - if (ret) - return ret; - - /* Set predefined value for BUCK1 register 3 */ - i = 0; - while (buck12_voltage_map_desc.min + - buck12_voltage_map_desc.step*i - < (pdata->buck1_voltage3 / 1000)) - i++; - - max8998->buck1_vol[2] = i; - ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE3, i); - if (ret) - return ret; - - /* Set predefined value for BUCK1 register 4 */ - i = 0; - while (buck12_voltage_map_desc.min + - buck12_voltage_map_desc.step*i - < (pdata->buck1_voltage4 / 1000)) - i++; - - max8998->buck1_vol[3] = i; - ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE4, i); + printk(KERN_ERR "i:%d, buck1_idx:%d\n", i, max8998->buck1_idx); + ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE2, i) + + ret; if (ret) return ret; @@ -809,28 +772,18 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) gpio_direction_output(pdata->buck2_set3, max8998->buck2_idx & 0x1); - /* BUCK2 register 1 */ + /* BUCK2 - set preset default voltage value to buck2_vol[0] */ i = 0; while (buck12_voltage_map_desc.min + buck12_voltage_map_desc.step*i - < (pdata->buck2_voltage1 / 1000)) + != (pdata->buck2_max_voltage / 1000)) i++; + printk(KERN_ERR "i:%d, buck2_idx:%d\n", i, max8998->buck2_idx); max8998->buck2_vol[0] = i; ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE1, i); if (ret) return ret; - /* BUCK2 register 2 */ - i = 0; - while (buck12_voltage_map_desc.min + - buck12_voltage_map_desc.step*i - < (pdata->buck2_voltage2 / 1000)) - i++; - printk(KERN_ERR "i2:%d, buck2_idx:%d\n", i, max8998->buck2_idx); - max8998->buck2_vol[1] = i; - ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE2, i); - if (ret) - return ret; } for (i = 0; i < pdata->num_regulators; i++) { @@ -882,12 +835,6 @@ static int __devexit max8998_pmic_remove(struct platform_device *pdev) return 0; } -static const struct platform_device_id max8998_pmic_id[] = { - { "max8998-pmic", TYPE_MAX8998 }, - { "lp3974-pmic", TYPE_LP3974 }, - { } -}; - static struct platform_driver max8998_pmic_driver = { .driver = { .name = "max8998-pmic", @@ -895,7 +842,6 @@ static struct platform_driver max8998_pmic_driver = { }, .probe = max8998_pmic_probe, .remove = __devexit_p(max8998_pmic_remove), - .id_table = max8998_pmic_id, }; static int __init max8998_pmic_init(void) diff --git a/trunk/drivers/rtc/rtc-max8998.c b/trunk/drivers/rtc/rtc-max8998.c index 3f7bc6b9fefa..f22dee35f330 100644 --- a/trunk/drivers/rtc/rtc-max8998.c +++ b/trunk/drivers/rtc/rtc-max8998.c @@ -20,7 +20,6 @@ #include #include #include -#include #define MAX8998_RTC_SEC 0x00 #define MAX8998_RTC_MIN 0x01 @@ -74,7 +73,6 @@ struct max8998_rtc_info { struct i2c_client *rtc; struct rtc_device *rtc_dev; int irq; - bool lp3974_bug_workaround; }; static void max8998_data_to_tm(u8 *data, struct rtc_time *tm) @@ -126,16 +124,10 @@ static int max8998_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct max8998_rtc_info *info = dev_get_drvdata(dev); u8 data[8]; - int ret; max8998_tm_to_data(tm, data); - ret = max8998_bulk_write(info->rtc, MAX8998_RTC_SEC, 8, data); - - if (info->lp3974_bug_workaround) - msleep(2000); - - return ret; + return max8998_bulk_write(info->rtc, MAX8998_RTC_SEC, 8, data); } static int max8998_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) @@ -171,29 +163,12 @@ static int max8998_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int max8998_rtc_stop_alarm(struct max8998_rtc_info *info) { - int ret = max8998_write_reg(info->rtc, MAX8998_ALARM0_CONF, 0); - - if (info->lp3974_bug_workaround) - msleep(2000); - - return ret; + return max8998_write_reg(info->rtc, MAX8998_ALARM0_CONF, 0); } static int max8998_rtc_start_alarm(struct max8998_rtc_info *info) { - int ret; - u8 alarm0_conf = 0x77; - - /* LP3974 with delay bug chips has rtc alarm bugs with "MONTH" field */ - if (info->lp3974_bug_workaround) - alarm0_conf = 0x57; - - ret = max8998_write_reg(info->rtc, MAX8998_ALARM0_CONF, alarm0_conf); - - if (info->lp3974_bug_workaround) - msleep(2000); - - return ret; + return max8998_write_reg(info->rtc, MAX8998_ALARM0_CONF, 0x77); } static int max8998_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) @@ -212,13 +187,10 @@ static int max8998_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) if (ret < 0) return ret; - if (info->lp3974_bug_workaround) - msleep(2000); - if (alrm->enabled) - ret = max8998_rtc_start_alarm(info); + return max8998_rtc_start_alarm(info); - return ret; + return 0; } static int max8998_rtc_alarm_irq_enable(struct device *dev, @@ -252,7 +224,6 @@ static const struct rtc_class_ops max8998_rtc_ops = { static int __devinit max8998_rtc_probe(struct platform_device *pdev) { struct max8998_dev *max8998 = dev_get_drvdata(pdev->dev.parent); - struct max8998_platform_data *pdata = dev_get_platdata(max8998->dev); struct max8998_rtc_info *info; int ret; @@ -278,18 +249,10 @@ static int __devinit max8998_rtc_probe(struct platform_device *pdev) ret = request_threaded_irq(info->irq, NULL, max8998_rtc_alarm_irq, 0, "rtc-alarm0", info); - if (ret < 0) dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", info->irq, ret); - dev_info(&pdev->dev, "RTC CHIP NAME: %s\n", pdev->id_entry->name); - if (pdata->rtc_delay) { - info->lp3974_bug_workaround = true; - dev_warn(&pdev->dev, "LP3974 with RTC REGERR option." - " RTC updates will be extremely slow.\n"); - } - return 0; out_rtc: @@ -310,12 +273,6 @@ static int __devexit max8998_rtc_remove(struct platform_device *pdev) return 0; } -static const struct platform_device_id max8998_rtc_id[] = { - { "max8998-rtc", TYPE_MAX8998 }, - { "lp3974-rtc", TYPE_LP3974 }, - { } -}; - static struct platform_driver max8998_rtc_driver = { .driver = { .name = "max8998-rtc", @@ -323,7 +280,6 @@ static struct platform_driver max8998_rtc_driver = { }, .probe = max8998_rtc_probe, .remove = __devexit_p(max8998_rtc_remove), - .id_table = max8998_rtc_id, }; static int __init max8998_rtc_init(void) diff --git a/trunk/drivers/s390/cio/device.c b/trunk/drivers/s390/cio/device.c index b7eaff9ca19e..e8391b89eff4 100644 --- a/trunk/drivers/s390/cio/device.c +++ b/trunk/drivers/s390/cio/device.c @@ -1835,7 +1835,6 @@ static void __ccw_device_pm_restore(struct ccw_device *cdev) * available again. Kick re-detection. */ cdev->private->flags.resuming = 1; - cdev->private->path_new_mask = LPM_ANYPATH; css_schedule_eval(sch->schid); spin_unlock_irq(sch->lock); css_complete_work(); diff --git a/trunk/drivers/scsi/ipr.c b/trunk/drivers/scsi/ipr.c index 9c5c8be72231..d3c5905b22ec 100644 --- a/trunk/drivers/scsi/ipr.c +++ b/trunk/drivers/scsi/ipr.c @@ -7515,10 +7515,16 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; volatile u32 int_reg; + int rc; ENTER; ioa_cfg->pdev->state_saved = true; - pci_restore_state(ioa_cfg->pdev); + rc = pci_restore_state(ioa_cfg->pdev); + + if (rc != PCIBIOS_SUCCESSFUL) { + ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); + return IPR_RC_JOB_CONTINUE; + } if (ipr_set_pcix_cmd_reg(ioa_cfg)) { ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); diff --git a/trunk/drivers/scsi/pmcraid.c b/trunk/drivers/scsi/pmcraid.c index 321cf3ae8630..300d59f389da 100644 --- a/trunk/drivers/scsi/pmcraid.c +++ b/trunk/drivers/scsi/pmcraid.c @@ -2228,7 +2228,12 @@ static void pmcraid_ioa_reset(struct pmcraid_cmd *cmd) /* Once either bist or pci reset is done, restore PCI config * space. If this fails, proceed with hard reset again */ - pci_restore_state(pinstance->pdev); + if (pci_restore_state(pinstance->pdev)) { + pmcraid_info("config-space error resetting again\n"); + pinstance->ioa_state = IOA_STATE_IN_RESET_ALERT; + pmcraid_reset_alert(cmd); + break; + } /* fail all pending commands */ pmcraid_fail_outstanding_cmds(pinstance); diff --git a/trunk/drivers/staging/sm7xx/smtcfb.c b/trunk/drivers/staging/sm7xx/smtcfb.c index 0bc113c44d39..f4b163f7338a 100644 --- a/trunk/drivers/staging/sm7xx/smtcfb.c +++ b/trunk/drivers/staging/sm7xx/smtcfb.c @@ -1071,7 +1071,7 @@ static int __maybe_unused smtcfb_resume(struct pci_dev *pdev) /* when resuming, restore pci data and fb cursor */ if (pdev->dev.power.power_state.event != PM_EVENT_FREEZE) { retv = pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); + retv = pci_restore_state(pdev); if (pci_enable_device(pdev)) return -1; pci_set_master(pdev); diff --git a/trunk/fs/afs/cmservice.c b/trunk/fs/afs/cmservice.c index 1c8c6cc6de30..a3bcec75c54a 100644 --- a/trunk/fs/afs/cmservice.c +++ b/trunk/fs/afs/cmservice.c @@ -289,7 +289,7 @@ static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb, call->server = server; INIT_WORK(&call->work, SRXAFSCB_CallBack); - queue_work(afs_wq, &call->work); + schedule_work(&call->work); return 0; } @@ -336,7 +336,7 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call, call->server = server; INIT_WORK(&call->work, SRXAFSCB_InitCallBackState); - queue_work(afs_wq, &call->work); + schedule_work(&call->work); return 0; } @@ -367,7 +367,7 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call, call->server = server; INIT_WORK(&call->work, SRXAFSCB_InitCallBackState); - queue_work(afs_wq, &call->work); + schedule_work(&call->work); return 0; } @@ -400,7 +400,7 @@ static int afs_deliver_cb_probe(struct afs_call *call, struct sk_buff *skb, call->state = AFS_CALL_REPLYING; INIT_WORK(&call->work, SRXAFSCB_Probe); - queue_work(afs_wq, &call->work); + schedule_work(&call->work); return 0; } @@ -496,7 +496,7 @@ static int afs_deliver_cb_probe_uuid(struct afs_call *call, struct sk_buff *skb, call->state = AFS_CALL_REPLYING; INIT_WORK(&call->work, SRXAFSCB_ProbeUuid); - queue_work(afs_wq, &call->work); + schedule_work(&call->work); return 0; } @@ -580,6 +580,6 @@ static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call, call->state = AFS_CALL_REPLYING; INIT_WORK(&call->work, SRXAFSCB_TellMeAboutYourself); - queue_work(afs_wq, &call->work); + schedule_work(&call->work); return 0; } diff --git a/trunk/fs/afs/internal.h b/trunk/fs/afs/internal.h index 58c633b80246..ab6db5abaf53 100644 --- a/trunk/fs/afs/internal.h +++ b/trunk/fs/afs/internal.h @@ -577,7 +577,6 @@ extern int afs_drop_inode(struct inode *); /* * main.c */ -extern struct workqueue_struct *afs_wq; extern struct afs_uuid afs_uuid; /* diff --git a/trunk/fs/afs/main.c b/trunk/fs/afs/main.c index 42dd2e499ed8..cfd1cbe25b22 100644 --- a/trunk/fs/afs/main.c +++ b/trunk/fs/afs/main.c @@ -30,7 +30,6 @@ module_param(rootcell, charp, 0); MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list"); struct afs_uuid afs_uuid; -struct workqueue_struct *afs_wq; /* * get a client UUID @@ -88,16 +87,10 @@ static int __init afs_init(void) if (ret < 0) return ret; - /* create workqueue */ - ret = -ENOMEM; - afs_wq = alloc_workqueue("afs", 0, 0); - if (!afs_wq) - return ret; - /* register the /proc stuff */ ret = afs_proc_init(); if (ret < 0) - goto error_proc; + return ret; #ifdef CONFIG_AFS_FSCACHE /* we want to be able to cache */ @@ -147,8 +140,6 @@ static int __init afs_init(void) error_cache: #endif afs_proc_cleanup(); -error_proc: - destroy_workqueue(afs_wq); rcu_barrier(); printk(KERN_ERR "kAFS: failed to register: %d\n", ret); return ret; @@ -172,7 +163,7 @@ static void __exit afs_exit(void) afs_purge_servers(); afs_callback_update_kill(); afs_vlocation_purge(); - destroy_workqueue(afs_wq); + flush_scheduled_work(); afs_cell_purge(); #ifdef CONFIG_AFS_FSCACHE fscache_unregister_netfs(&afs_cache_netfs); diff --git a/trunk/fs/afs/mntpt.c b/trunk/fs/afs/mntpt.c index e83c0336e7b5..6153417caf57 100644 --- a/trunk/fs/afs/mntpt.c +++ b/trunk/fs/afs/mntpt.c @@ -268,8 +268,8 @@ static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd) path_put(&nd->path); nd->path.mnt = newmnt; nd->path.dentry = dget(newmnt->mnt_root); - queue_delayed_work(afs_wq, &afs_mntpt_expiry_timer, - afs_mntpt_expiry_timeout * HZ); + schedule_delayed_work(&afs_mntpt_expiry_timer, + afs_mntpt_expiry_timeout * HZ); break; case -EBUSY: /* someone else made a mount here whilst we were busy */ @@ -295,8 +295,8 @@ static void afs_mntpt_expiry_timed_out(struct work_struct *work) if (!list_empty(&afs_vfsmounts)) { mark_mounts_for_expiry(&afs_vfsmounts); - queue_delayed_work(afs_wq, &afs_mntpt_expiry_timer, - afs_mntpt_expiry_timeout * HZ); + schedule_delayed_work(&afs_mntpt_expiry_timer, + afs_mntpt_expiry_timeout * HZ); } _leave(""); @@ -310,5 +310,6 @@ void afs_mntpt_kill_timer(void) _enter(""); ASSERT(list_empty(&afs_vfsmounts)); - cancel_delayed_work_sync(&afs_mntpt_expiry_timer); + cancel_delayed_work(&afs_mntpt_expiry_timer); + flush_scheduled_work(); } diff --git a/trunk/fs/afs/rxrpc.c b/trunk/fs/afs/rxrpc.c index e45a323aebb4..654d8fdbf01f 100644 --- a/trunk/fs/afs/rxrpc.c +++ b/trunk/fs/afs/rxrpc.c @@ -410,7 +410,7 @@ static void afs_rx_interceptor(struct sock *sk, unsigned long user_call_ID, if (!call) { /* its an incoming call for our callback service */ skb_queue_tail(&afs_incoming_calls, skb); - queue_work(afs_wq, &afs_collect_incoming_call_work); + schedule_work(&afs_collect_incoming_call_work); } else { /* route the messages directly to the appropriate call */ skb_queue_tail(&call->rx_queue, skb); diff --git a/trunk/fs/afs/server.c b/trunk/fs/afs/server.c index d59b7516e943..9fdc7fe3a7bc 100644 --- a/trunk/fs/afs/server.c +++ b/trunk/fs/afs/server.c @@ -238,8 +238,8 @@ void afs_put_server(struct afs_server *server) if (atomic_read(&server->usage) == 0) { list_move_tail(&server->grave, &afs_server_graveyard); server->time_of_death = get_seconds(); - queue_delayed_work(afs_wq, &afs_server_reaper, - afs_server_timeout * HZ); + schedule_delayed_work(&afs_server_reaper, + afs_server_timeout * HZ); } spin_unlock(&afs_server_graveyard_lock); _leave(" [dead]"); @@ -285,11 +285,10 @@ static void afs_reap_server(struct work_struct *work) expiry = server->time_of_death + afs_server_timeout; if (expiry > now) { delay = (expiry - now) * HZ; - if (!queue_delayed_work(afs_wq, &afs_server_reaper, - delay)) { + if (!schedule_delayed_work(&afs_server_reaper, delay)) { cancel_delayed_work(&afs_server_reaper); - queue_delayed_work(afs_wq, &afs_server_reaper, - delay); + schedule_delayed_work(&afs_server_reaper, + delay); } break; } @@ -324,5 +323,5 @@ void __exit afs_purge_servers(void) { afs_server_timeout = 0; cancel_delayed_work(&afs_server_reaper); - queue_delayed_work(afs_wq, &afs_server_reaper, 0); + schedule_delayed_work(&afs_server_reaper, 0); } diff --git a/trunk/fs/afs/vlocation.c b/trunk/fs/afs/vlocation.c index 431984d2e372..9ac260d1361d 100644 --- a/trunk/fs/afs/vlocation.c +++ b/trunk/fs/afs/vlocation.c @@ -507,8 +507,8 @@ void afs_put_vlocation(struct afs_vlocation *vl) _debug("buried"); list_move_tail(&vl->grave, &afs_vlocation_graveyard); vl->time_of_death = get_seconds(); - queue_delayed_work(afs_wq, &afs_vlocation_reap, - afs_vlocation_timeout * HZ); + schedule_delayed_work(&afs_vlocation_reap, + afs_vlocation_timeout * HZ); /* suspend updates on this record */ if (!list_empty(&vl->update)) { @@ -561,11 +561,11 @@ static void afs_vlocation_reaper(struct work_struct *work) if (expiry > now) { delay = (expiry - now) * HZ; _debug("delay %lu", delay); - if (!queue_delayed_work(afs_wq, &afs_vlocation_reap, - delay)) { + if (!schedule_delayed_work(&afs_vlocation_reap, + delay)) { cancel_delayed_work(&afs_vlocation_reap); - queue_delayed_work(afs_wq, &afs_vlocation_reap, - delay); + schedule_delayed_work(&afs_vlocation_reap, + delay); } break; } @@ -620,7 +620,7 @@ void afs_vlocation_purge(void) destroy_workqueue(afs_vlocation_update_worker); cancel_delayed_work(&afs_vlocation_reap); - queue_delayed_work(afs_wq, &afs_vlocation_reap, 0); + schedule_delayed_work(&afs_vlocation_reap, 0); } /* diff --git a/trunk/fs/fscache/operation.c b/trunk/fs/fscache/operation.c index 48a18f184d50..b9f34eaede09 100644 --- a/trunk/fs/fscache/operation.c +++ b/trunk/fs/fscache/operation.c @@ -101,7 +101,7 @@ int fscache_submit_exclusive_op(struct fscache_object *object, object->n_ops++; object->n_exclusive++; /* reads and writes must wait */ - if (object->n_ops > 1) { + if (object->n_ops > 0) { atomic_inc(&op->usage); list_add_tail(&op->pend_link, &object->pending_ops); fscache_stat(&fscache_n_op_pend); diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index 8df7a78ace58..86643302079e 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -779,8 +779,7 @@ static void path_put_conditional(struct path *path, struct nameidata *nd) mntput(path->mnt); } -static inline void path_to_nameidata(const struct path *path, - struct nameidata *nd) +static inline void path_to_nameidata(struct path *path, struct nameidata *nd) { if (!(nd->flags & LOOKUP_RCU)) { dput(nd->path.dentry); @@ -792,20 +791,20 @@ static inline void path_to_nameidata(const struct path *path, } static __always_inline int -__do_follow_link(const struct path *link, struct nameidata *nd, void **p) +__do_follow_link(struct path *path, struct nameidata *nd, void **p) { int error; - struct dentry *dentry = link->dentry; + struct dentry *dentry = path->dentry; - touch_atime(link->mnt, dentry); + touch_atime(path->mnt, dentry); nd_set_link(nd, NULL); - if (link->mnt != nd->path.mnt) { - path_to_nameidata(link, nd); + if (path->mnt != nd->path.mnt) { + path_to_nameidata(path, nd); nd->inode = nd->path.dentry->d_inode; dget(dentry); } - mntget(link->mnt); + mntget(path->mnt); nd->last_type = LAST_BIND; *p = dentry->d_inode->i_op->follow_link(dentry, nd); @@ -2349,12 +2348,11 @@ struct file *do_filp_open(int dfd, const char *pathname, nd.flags = flags; filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname); while (unlikely(!filp)) { /* trailing symlink */ - struct path link = path; - struct inode *linki = link.dentry->d_inode; + struct path holder; void *cookie; error = -ELOOP; /* S_ISDIR part is a temporary automount kludge */ - if (!(nd.flags & LOOKUP_FOLLOW) && !S_ISDIR(linki->i_mode)) + if (!(nd.flags & LOOKUP_FOLLOW) && !S_ISDIR(nd.inode->i_mode)) goto exit_dput; if (count++ == 32) goto exit_dput; @@ -2370,22 +2368,23 @@ struct file *do_filp_open(int dfd, const char *pathname, * just set LAST_BIND. */ nd.flags |= LOOKUP_PARENT; - error = security_inode_follow_link(link.dentry, &nd); + error = security_inode_follow_link(path.dentry, &nd); if (error) goto exit_dput; - error = __do_follow_link(&link, &nd, &cookie); + error = __do_follow_link(&path, &nd, &cookie); if (unlikely(error)) { - if (!IS_ERR(cookie) && linki->i_op->put_link) - linki->i_op->put_link(link.dentry, &nd, cookie); + if (!IS_ERR(cookie) && nd.inode->i_op->put_link) + nd.inode->i_op->put_link(path.dentry, &nd, cookie); /* nd.path had been dropped */ - nd.path = link; + nd.path = path; goto out_path; } + holder = path; nd.flags &= ~LOOKUP_PARENT; filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname); - if (linki->i_op->put_link) - linki->i_op->put_link(link.dentry, &nd, cookie); - path_put(&link); + if (nd.inode->i_op->put_link) + nd.inode->i_op->put_link(holder.dentry, &nd, cookie); + path_put(&holder); } out: if (nd.root.mnt) diff --git a/trunk/include/acpi/apei.h b/trunk/include/acpi/apei.h index c4dbb132d902..b3365025ff8d 100644 --- a/trunk/include/acpi/apei.h +++ b/trunk/include/acpi/apei.h @@ -19,12 +19,6 @@ extern int hest_disable; extern int erst_disable; -#ifdef CONFIG_ACPI_APEI -void __init acpi_hest_init(void); -#else -static inline void acpi_hest_init(void) { return; } -#endif - typedef int (*apei_hest_func_t)(struct acpi_hest_header *hest_hdr, void *data); int apei_hest_parse(apei_hest_func_t func, void *data); diff --git a/trunk/include/linux/gpio.h b/trunk/include/linux/gpio.h index 32720baf70f1..4b47ed96f131 100644 --- a/trunk/include/linux/gpio.h +++ b/trunk/include/linux/gpio.h @@ -35,13 +35,13 @@ static inline int gpio_request(unsigned gpio, const char *label) return -ENOSYS; } -static inline int gpio_request_one(unsigned gpio, +static inline int __must_check gpio_request_one(unsigned gpio, unsigned long flags, const char *label) { return -ENOSYS; } -static inline int gpio_request_array(struct gpio *array, size_t num) +static inline int __must_check gpio_request_array(struct gpio *array, size_t num) { return -ENOSYS; } diff --git a/trunk/include/linux/list_bl.h b/trunk/include/linux/list_bl.h index 5bad17d1acde..b2adbb4b2f73 100644 --- a/trunk/include/linux/list_bl.h +++ b/trunk/include/linux/list_bl.h @@ -16,7 +16,7 @@ * some fast and compact auxiliary data. */ -#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) +#if defined(CONFIG_SMP) #define LIST_BL_LOCKMASK 1UL #else #define LIST_BL_LOCKMASK 0UL diff --git a/trunk/include/linux/mfd/ab8500.h b/trunk/include/linux/mfd/ab8500.h index 37f56b7c4c15..85cf2c28fac6 100644 --- a/trunk/include/linux/mfd/ab8500.h +++ b/trunk/include/linux/mfd/ab8500.h @@ -74,37 +74,30 @@ #define AB8500_INT_ACC_DETECT_21DB_F 37 #define AB8500_INT_ACC_DETECT_21DB_R 38 #define AB8500_INT_GP_SW_ADC_CONV_END 39 -#define AB8500_INT_ADP_SOURCE_ERROR 72 -#define AB8500_INT_ADP_SINK_ERROR 73 -#define AB8500_INT_ADP_PROBE_PLUG 74 -#define AB8500_INT_ADP_PROBE_UNPLUG 75 -#define AB8500_INT_ADP_SENSE_OFF 76 -#define AB8500_INT_USB_PHY_POWER_ERR 78 -#define AB8500_INT_USB_LINK_STATUS 79 -#define AB8500_INT_BTEMP_LOW 80 -#define AB8500_INT_BTEMP_LOW_MEDIUM 81 -#define AB8500_INT_BTEMP_MEDIUM_HIGH 82 -#define AB8500_INT_BTEMP_HIGH 83 -#define AB8500_INT_USB_CHARGER_NOT_OK 89 -#define AB8500_INT_ID_WAKEUP_R 90 -#define AB8500_INT_ID_DET_R1R 92 -#define AB8500_INT_ID_DET_R2R 93 -#define AB8500_INT_ID_DET_R3R 94 -#define AB8500_INT_ID_DET_R4R 95 -#define AB8500_INT_ID_WAKEUP_F 96 -#define AB8500_INT_ID_DET_R1F 98 -#define AB8500_INT_ID_DET_R2F 99 -#define AB8500_INT_ID_DET_R3F 100 -#define AB8500_INT_ID_DET_R4F 101 -#define AB8500_INT_USB_CHG_DET_DONE 102 -#define AB8500_INT_USB_CH_TH_PROT_F 104 -#define AB8500_INT_USB_CH_TH_PROT_R 105 -#define AB8500_INT_MAIN_CH_TH_PROT_F 106 -#define AB8500_INT_MAIN_CH_TH_PROT_R 107 -#define AB8500_INT_USB_CHARGER_NOT_OKF 111 +#define AB8500_INT_BTEMP_LOW 72 +#define AB8500_INT_BTEMP_LOW_MEDIUM 73 +#define AB8500_INT_BTEMP_MEDIUM_HIGH 74 +#define AB8500_INT_BTEMP_HIGH 75 +#define AB8500_INT_USB_CHARGER_NOT_OK 81 +#define AB8500_INT_ID_WAKEUP_R 82 +#define AB8500_INT_ID_DET_R1R 84 +#define AB8500_INT_ID_DET_R2R 85 +#define AB8500_INT_ID_DET_R3R 86 +#define AB8500_INT_ID_DET_R4R 87 +#define AB8500_INT_ID_WAKEUP_F 88 +#define AB8500_INT_ID_DET_R1F 90 +#define AB8500_INT_ID_DET_R2F 91 +#define AB8500_INT_ID_DET_R3F 92 +#define AB8500_INT_ID_DET_R4F 93 +#define AB8500_INT_USB_CHG_DET_DONE 94 +#define AB8500_INT_USB_CH_TH_PROT_F 96 +#define AB8500_INT_USB_CH_TH_PROP_R 97 +#define AB8500_INT_MAIN_CH_TH_PROP_F 98 +#define AB8500_INT_MAIN_CH_TH_PROT_R 99 +#define AB8500_INT_USB_CHARGER_NOT_OKF 103 -#define AB8500_NR_IRQS 112 -#define AB8500_NUM_IRQ_REGS 14 +#define AB8500_NR_IRQS 104 +#define AB8500_NUM_IRQ_REGS 13 /** * struct ab8500 - ab8500 internal structure diff --git a/trunk/include/linux/mfd/core.h b/trunk/include/linux/mfd/core.h index 835996e167e1..5582ab3d3e48 100644 --- a/trunk/include/linux/mfd/core.h +++ b/trunk/include/linux/mfd/core.h @@ -47,12 +47,6 @@ struct mfd_cell { /* don't check for resource conflicts */ bool ignore_resource_conflicts; - - /* - * Disable runtime PM callbacks for this subdevice - see - * pm_runtime_no_callbacks(). - */ - bool pm_runtime_no_callbacks; }; extern int mfd_add_devices(struct device *parent, int id, diff --git a/trunk/include/linux/mfd/max8998-private.h b/trunk/include/linux/mfd/max8998-private.h index effa5d3b96ae..7363dea6bbcd 100644 --- a/trunk/include/linux/mfd/max8998-private.h +++ b/trunk/include/linux/mfd/max8998-private.h @@ -159,12 +159,10 @@ struct max8998_dev { u8 irq_masks_cur[MAX8998_NUM_IRQ_REGS]; u8 irq_masks_cache[MAX8998_NUM_IRQ_REGS]; int type; - bool wakeup; }; int max8998_irq_init(struct max8998_dev *max8998); void max8998_irq_exit(struct max8998_dev *max8998); -int max8998_irq_resume(struct max8998_dev *max8998); extern int max8998_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest); extern int max8998_bulk_read(struct i2c_client *i2c, u8 reg, int count, diff --git a/trunk/include/linux/mfd/max8998.h b/trunk/include/linux/mfd/max8998.h index 61daa167b576..f8c9f884aff2 100644 --- a/trunk/include/linux/mfd/max8998.h +++ b/trunk/include/linux/mfd/max8998.h @@ -70,43 +70,24 @@ struct max8998_regulator_data { * @num_regulators: number of regultors used * @irq_base: base IRQ number for max8998, required for IRQs * @ono: power onoff IRQ number for max8998 - * @buck_voltage_lock: Do NOT change the values of the following six - * registers set by buck?_voltage?. The voltage of BUCK1/2 cannot - * be other than the preset values. - * @buck1_voltage1: BUCK1 DVS mode 1 voltage register - * @buck1_voltage2: BUCK1 DVS mode 2 voltage register - * @buck1_voltage3: BUCK1 DVS mode 3 voltage register - * @buck1_voltage4: BUCK1 DVS mode 4 voltage register - * @buck2_voltage1: BUCK2 DVS mode 1 voltage register - * @buck2_voltage2: BUCK2 DVS mode 2 voltage register + * @buck1_max_voltage1: BUCK1 maximum alowed voltage register 1 + * @buck1_max_voltage2: BUCK1 maximum alowed voltage register 2 + * @buck2_max_voltage: BUCK2 maximum alowed voltage * @buck1_set1: BUCK1 gpio pin 1 to set output voltage * @buck1_set2: BUCK1 gpio pin 2 to set output voltage - * @buck1_default_idx: Default for BUCK1 gpio pin 1, 2 * @buck2_set3: BUCK2 gpio pin to set output voltage - * @buck2_default_idx: Default for BUCK2 gpio pin. - * @wakeup: Allow to wake up from suspend - * @rtc_delay: LP3974 RTC chip bug that requires delay after a register - * write before reading it. */ struct max8998_platform_data { struct max8998_regulator_data *regulators; int num_regulators; int irq_base; int ono; - bool buck_voltage_lock; - int buck1_voltage1; - int buck1_voltage2; - int buck1_voltage3; - int buck1_voltage4; - int buck2_voltage1; - int buck2_voltage2; + int buck1_max_voltage1; + int buck1_max_voltage2; + int buck2_max_voltage; int buck1_set1; int buck1_set2; - int buck1_default_idx; int buck2_set3; - int buck2_default_idx; - bool wakeup; - bool rtc_delay; }; #endif /* __LINUX_MFD_MAX8998_H */ diff --git a/trunk/include/linux/mfd/wm831x/core.h b/trunk/include/linux/mfd/wm831x/core.h index 903280d21866..a1239c48b41a 100644 --- a/trunk/include/linux/mfd/wm831x/core.h +++ b/trunk/include/linux/mfd/wm831x/core.h @@ -245,7 +245,6 @@ enum wm831x_parent { WM8320 = 0x8320, WM8321 = 0x8321, WM8325 = 0x8325, - WM8326 = 0x8326, }; struct wm831x { diff --git a/trunk/include/linux/page_cgroup.h b/trunk/include/linux/page_cgroup.h index 6d6cb7a57bb3..5b0c971d7cae 100644 --- a/trunk/include/linux/page_cgroup.h +++ b/trunk/include/linux/page_cgroup.h @@ -42,6 +42,9 @@ enum { /* flags for mem_cgroup and file and I/O status */ PCG_MOVE_LOCK, /* For race between move_account v.s. following bits */ PCG_FILE_MAPPED, /* page is accounted as "mapped" */ + PCG_FILE_DIRTY, /* page is dirty */ + PCG_FILE_WRITEBACK, /* page is under writeback */ + PCG_FILE_UNSTABLE_NFS, /* page is NFS unstable */ /* No lock in page_cgroup */ PCG_ACCT_LRU, /* page has been accounted for (under lru_lock) */ }; @@ -62,6 +65,10 @@ static inline void ClearPageCgroup##uname(struct page_cgroup *pc) \ static inline int TestClearPageCgroup##uname(struct page_cgroup *pc) \ { return test_and_clear_bit(PCG_##lname, &pc->flags); } +#define TESTSETPCGFLAG(uname, lname) \ +static inline int TestSetPageCgroup##uname(struct page_cgroup *pc) \ + { return test_and_set_bit(PCG_##lname, &pc->flags); } + /* Cache flag is set only once (at allocation) */ TESTPCGFLAG(Cache, CACHE) CLEARPCGFLAG(Cache, CACHE) @@ -81,6 +88,22 @@ SETPCGFLAG(FileMapped, FILE_MAPPED) CLEARPCGFLAG(FileMapped, FILE_MAPPED) TESTPCGFLAG(FileMapped, FILE_MAPPED) +SETPCGFLAG(FileDirty, FILE_DIRTY) +CLEARPCGFLAG(FileDirty, FILE_DIRTY) +TESTPCGFLAG(FileDirty, FILE_DIRTY) +TESTCLEARPCGFLAG(FileDirty, FILE_DIRTY) +TESTSETPCGFLAG(FileDirty, FILE_DIRTY) + +SETPCGFLAG(FileWriteback, FILE_WRITEBACK) +CLEARPCGFLAG(FileWriteback, FILE_WRITEBACK) +TESTPCGFLAG(FileWriteback, FILE_WRITEBACK) + +SETPCGFLAG(FileUnstableNFS, FILE_UNSTABLE_NFS) +CLEARPCGFLAG(FileUnstableNFS, FILE_UNSTABLE_NFS) +TESTPCGFLAG(FileUnstableNFS, FILE_UNSTABLE_NFS) +TESTCLEARPCGFLAG(FileUnstableNFS, FILE_UNSTABLE_NFS) +TESTSETPCGFLAG(FileUnstableNFS, FILE_UNSTABLE_NFS) + SETPCGFLAG(Migration, MIGRATION) CLEARPCGFLAG(Migration, MIGRATION) TESTPCGFLAG(Migration, MIGRATION) diff --git a/trunk/include/linux/pci-acpi.h b/trunk/include/linux/pci-acpi.h index 479d9bb88e11..c8b6473c5f42 100644 --- a/trunk/include/linux/pci-acpi.h +++ b/trunk/include/linux/pci-acpi.h @@ -40,10 +40,4 @@ static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev) { return NULL; } #endif -#ifdef CONFIG_ACPI_APEI -extern bool aer_acpi_firmware_first(void); -#else -static inline bool aer_acpi_firmware_first(void) { return false; } -#endif - #endif /* _PCI_ACPI_H_ */ diff --git a/trunk/include/linux/pci-aspm.h b/trunk/include/linux/pci-aspm.h index ce6810512c66..91ba0b338b47 100644 --- a/trunk/include/linux/pci-aspm.h +++ b/trunk/include/linux/pci-aspm.h @@ -27,7 +27,6 @@ extern void pcie_aspm_init_link_state(struct pci_dev *pdev); extern void pcie_aspm_exit_link_state(struct pci_dev *pdev); extern void pcie_aspm_pm_state_change(struct pci_dev *pdev); extern void pci_disable_link_state(struct pci_dev *pdev, int state); -extern void pcie_clear_aspm(void); extern void pcie_no_aspm(void); #else static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) @@ -42,9 +41,7 @@ static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev) static inline void pci_disable_link_state(struct pci_dev *pdev, int state) { } -static inline void pcie_clear_aspm(void) -{ -} + static inline void pcie_no_aspm(void) { } diff --git a/trunk/include/linux/pci.h b/trunk/include/linux/pci.h index 9e67dcd054c4..7454408c41b6 100644 --- a/trunk/include/linux/pci.h +++ b/trunk/include/linux/pci.h @@ -806,7 +806,7 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size); /* Power management related routines */ int pci_save_state(struct pci_dev *dev); -void pci_restore_state(struct pci_dev *dev); +int pci_restore_state(struct pci_dev *dev); int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state); int pci_set_power_state(struct pci_dev *dev, pci_power_t state); pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state); @@ -820,6 +820,7 @@ int pci_prepare_to_sleep(struct pci_dev *dev); int pci_back_from_sleep(struct pci_dev *dev); bool pci_dev_run_wake(struct pci_dev *dev); bool pci_check_pme_status(struct pci_dev *dev); +void pci_wakeup_event(struct pci_dev *dev); void pci_pme_wakeup_bus(struct pci_bus *bus); static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, @@ -993,9 +994,6 @@ extern void pci_restore_msi_state(struct pci_dev *dev); extern int pci_msi_enabled(void); #endif -extern bool pcie_ports_disabled; -extern bool pcie_ports_auto; - #ifndef CONFIG_PCIEASPM static inline int pcie_aspm_enabled(void) { @@ -1005,14 +1003,6 @@ static inline int pcie_aspm_enabled(void) extern int pcie_aspm_enabled(void); #endif -#ifdef CONFIG_PCIEAER -void pci_no_aer(void); -bool pci_aer_available(void); -#else -static inline void pci_no_aer(void) { } -static inline bool pci_aer_available(void) { return false; } -#endif - #ifndef CONFIG_PCIE_ECRC static inline void pcie_set_ecrc_checking(struct pci_dev *dev) { @@ -1178,8 +1168,10 @@ static inline int pci_save_state(struct pci_dev *dev) return 0; } -static inline void pci_restore_state(struct pci_dev *dev) -{ } +static inline int pci_restore_state(struct pci_dev *dev) +{ + return 0; +} static inline int pci_set_power_state(struct pci_dev *dev, pci_power_t state) { diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index 3adb06ebf841..ae0dc453e3e2 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -2478,8 +2478,7 @@ #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN 0x1c41 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX 0x1c5f #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 -#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0 0x1d40 -#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1 0x1d41 +#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC 0x1d40 #define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410 #define PCI_DEVICE_ID_INTEL_82801AA_1 0x2411 #define PCI_DEVICE_ID_INTEL_82801AA_3 0x2413 diff --git a/trunk/include/linux/pci_regs.h b/trunk/include/linux/pci_regs.h index 5b7e6b1ba54f..af83076c31a6 100644 --- a/trunk/include/linux/pci_regs.h +++ b/trunk/include/linux/pci_regs.h @@ -309,14 +309,6 @@ #define PCI_MSIX_PBA 8 #define PCI_MSIX_FLAGS_BIRMASK (7 << 0) -/* MSI-X entry's format */ -#define PCI_MSIX_ENTRY_SIZE 16 -#define PCI_MSIX_ENTRY_LOWER_ADDR 0 -#define PCI_MSIX_ENTRY_UPPER_ADDR 4 -#define PCI_MSIX_ENTRY_DATA 8 -#define PCI_MSIX_ENTRY_VECTOR_CTRL 12 -#define PCI_MSIX_ENTRY_CTRL_MASKBIT 1 - /* CompactPCI Hotswap Register */ #define PCI_CHSWP_CSR 2 /* Control and Status Register */ @@ -504,8 +496,6 @@ #define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */ #define PCI_EXP_RTCAP 30 /* Root Capabilities */ #define PCI_EXP_RTSTA 32 /* Root Status */ -#define PCI_EXP_RTSTA_PME 0x10000 /* PME status */ -#define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */ #define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */ #define PCI_EXP_DEVCAP2_ARI 0x20 /* Alternative Routing-ID */ #define PCI_EXP_DEVCTL2 40 /* Device Control 2 */ diff --git a/trunk/include/linux/power/gpio-charger.h b/trunk/include/linux/power/gpio-charger.h deleted file mode 100644 index de1dfe09a03d..000000000000 --- a/trunk/include/linux/power/gpio-charger.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2010, Lars-Peter Clausen - * - * 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. - * - * 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 __LINUX_POWER_GPIO_CHARGER_H__ -#define __LINUX_POWER_GPIO_CHARGER_H__ - -#include -#include - -/** - * struct gpio_charger_platform_data - platform_data for gpio_charger devices - * @name: Name for the chargers power_supply device - * @type: Type of the charger - * @gpio: GPIO which is used to indicate the chargers status - * @gpio_active_low: Should be set to 1 if the GPIO is active low otherwise 0 - * @supplied_to: Array of battery names to which this chargers supplies power - * @num_supplicants: Number of entries in the supplied_to array - */ -struct gpio_charger_platform_data { - const char *name; - enum power_supply_type type; - - int gpio; - int gpio_active_low; - - char **supplied_to; - size_t num_supplicants; -}; - -#endif diff --git a/trunk/include/linux/power/max17042_battery.h b/trunk/include/linux/power/max17042_battery.h deleted file mode 100644 index 7995deb8bfc1..000000000000 --- a/trunk/include/linux/power/max17042_battery.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Fuel gauge driver for Maxim 17042 / 8966 / 8997 - * Note that Maxim 8966 and 8997 are mfd and this is its subdevice. - * - * Copyright (C) 2011 Samsung Electronics - * MyungJoo Ham - * - * 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 __MAX17042_BATTERY_H_ -#define __MAX17042_BATTERY_H_ - -struct max17042_platform_data { - bool enable_current_sense; -}; - -#endif /* __MAX17042_BATTERY_H_ */ diff --git a/trunk/include/linux/s3c_adc_battery.h b/trunk/include/linux/s3c_adc_battery.h index fbe58b7e63eb..dbce22faa660 100644 --- a/trunk/include/linux/s3c_adc_battery.h +++ b/trunk/include/linux/s3c_adc_battery.h @@ -14,7 +14,6 @@ struct s3c_adc_bat_pdata { void (*disable_charger)(void); int gpio_charge_finished; - int gpio_inverted; const struct s3c_adc_bat_thresh *lut_noac; unsigned int lut_noac_cnt; diff --git a/trunk/kernel/cgroup.c b/trunk/kernel/cgroup.c index b24d7027b83c..5c5f4cc2e99a 100644 --- a/trunk/kernel/cgroup.c +++ b/trunk/kernel/cgroup.c @@ -764,7 +764,6 @@ EXPORT_SYMBOL_GPL(cgroup_unlock); */ static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, int mode); -static struct dentry *cgroup_lookup(struct inode *, struct dentry *, struct nameidata *); static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry); static int cgroup_populate_dir(struct cgroup *cgrp); static const struct inode_operations cgroup_dir_inode_operations; @@ -861,11 +860,6 @@ static void cgroup_diput(struct dentry *dentry, struct inode *inode) iput(inode); } -static int cgroup_delete(const struct dentry *d) -{ - return 1; -} - static void remove_dir(struct dentry *d) { struct dentry *parent = dget(d->d_parent); @@ -916,7 +910,7 @@ static void cgroup_d_remove_dir(struct dentry *dentry) parent = dentry->d_parent; spin_lock(&parent->d_lock); - spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); + spin_lock(&dentry->d_lock); list_del_init(&dentry->d_u.d_child); spin_unlock(&dentry->d_lock); spin_unlock(&parent->d_lock); @@ -1457,7 +1451,6 @@ static int cgroup_get_rootdir(struct super_block *sb) { static const struct dentry_operations cgroup_dops = { .d_iput = cgroup_diput, - .d_delete = cgroup_delete, }; struct inode *inode = @@ -2202,20 +2195,12 @@ static const struct file_operations cgroup_file_operations = { }; static const struct inode_operations cgroup_dir_inode_operations = { - .lookup = cgroup_lookup, + .lookup = simple_lookup, .mkdir = cgroup_mkdir, .rmdir = cgroup_rmdir, .rename = cgroup_rename, }; -static struct dentry *cgroup_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) -{ - if (dentry->d_name.len > NAME_MAX) - return ERR_PTR(-ENAMETOOLONG); - d_add(dentry, NULL); - return NULL; -} - /* * Check if a file is a control file */ diff --git a/trunk/net/rxrpc/af_rxrpc.c b/trunk/net/rxrpc/af_rxrpc.c index 74c064c0dfdd..0b9bb2085ce4 100644 --- a/trunk/net/rxrpc/af_rxrpc.c +++ b/trunk/net/rxrpc/af_rxrpc.c @@ -808,7 +808,7 @@ static int __init af_rxrpc_init(void) goto error_call_jar; } - rxrpc_workqueue = alloc_workqueue("krxrpcd", 0, 1); + rxrpc_workqueue = create_workqueue("krxrpcd"); if (!rxrpc_workqueue) { printk(KERN_NOTICE "RxRPC: Failed to allocate work queue\n"); goto error_work_queue; diff --git a/trunk/sound/pci/cs5535audio/cs5535audio_pm.c b/trunk/sound/pci/cs5535audio/cs5535audio_pm.c index 185b00088320..a3301cc4ab82 100644 --- a/trunk/sound/pci/cs5535audio/cs5535audio_pm.c +++ b/trunk/sound/pci/cs5535audio/cs5535audio_pm.c @@ -90,7 +90,12 @@ int snd_cs5535audio_resume(struct pci_dev *pci) int i; pci_set_power_state(pci, PCI_D0); - pci_restore_state(pci); + if (pci_restore_state(pci) < 0) { + printk(KERN_ERR "cs5535audio: pci_restore_state failed, " + "disabling device\n"); + snd_card_disconnect(card); + return -EIO; + } if (pci_enable_device(pci) < 0) { printk(KERN_ERR "cs5535audio: pci_enable_device failed, " "disabling device\n");