From 1813a68457bb45b378d5bbec615b167deff3bcfc Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 20 Jul 2010 15:22:54 -0700 Subject: x86: Move alloc_desk_mask variables inside ifdef They are only useful with CONFIG_CPUMASK_OFFSTACK Avoids hundreds of warnings with a gcc 4.6 -Wall build. Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Thomas Gleixner --- include/linux/irq.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/irq.h b/include/linux/irq.h index c03243ad84b4..fff1d77c3753 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -439,12 +439,12 @@ extern int set_irq_msi(unsigned int irq, struct msi_desc *entry); static inline bool alloc_desc_masks(struct irq_desc *desc, int node, bool boot) { +#ifdef CONFIG_CPUMASK_OFFSTACK gfp_t gfp = GFP_ATOMIC; if (boot) gfp = GFP_NOWAIT; -#ifdef CONFIG_CPUMASK_OFFSTACK if (!alloc_cpumask_var_node(&desc->affinity, gfp, node)) return false; -- cgit v1.2.3 From e3239ff92a17976ac5d26fa0fe40ef3a9daf2523 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 4 Aug 2010 14:06:41 +1000 Subject: memblock: Rename memblock_region to memblock_type and memblock_property to memblock_region Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index a59faf2b5edd..86e7daf742f2 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -18,22 +18,22 @@ #define MAX_MEMBLOCK_REGIONS 128 -struct memblock_property { +struct memblock_region { u64 base; u64 size; }; -struct memblock_region { +struct memblock_type { unsigned long cnt; u64 size; - struct memblock_property region[MAX_MEMBLOCK_REGIONS+1]; + struct memblock_region regions[MAX_MEMBLOCK_REGIONS+1]; }; struct memblock { unsigned long debug; u64 rmo_size; - struct memblock_region memory; - struct memblock_region reserved; + struct memblock_type memory; + struct memblock_type reserved; }; extern struct memblock memblock; @@ -56,27 +56,27 @@ extern u64 memblock_end_of_DRAM(void); extern void __init memblock_enforce_memory_limit(u64 memory_limit); extern int __init memblock_is_reserved(u64 addr); extern int memblock_is_region_reserved(u64 base, u64 size); -extern int memblock_find(struct memblock_property *res); +extern int memblock_find(struct memblock_region *res); extern void memblock_dump_all(void); static inline u64 -memblock_size_bytes(struct memblock_region *type, unsigned long region_nr) +memblock_size_bytes(struct memblock_type *type, unsigned long region_nr) { - return type->region[region_nr].size; + return type->regions[region_nr].size; } static inline u64 -memblock_size_pages(struct memblock_region *type, unsigned long region_nr) +memblock_size_pages(struct memblock_type *type, unsigned long region_nr) { return memblock_size_bytes(type, region_nr) >> PAGE_SHIFT; } static inline u64 -memblock_start_pfn(struct memblock_region *type, unsigned long region_nr) +memblock_start_pfn(struct memblock_type *type, unsigned long region_nr) { - return type->region[region_nr].base >> PAGE_SHIFT; + return type->regions[region_nr].base >> PAGE_SHIFT; } static inline u64 -memblock_end_pfn(struct memblock_region *type, unsigned long region_nr) +memblock_end_pfn(struct memblock_type *type, unsigned long region_nr) { return memblock_start_pfn(type, region_nr) + memblock_size_pages(type, region_nr); -- cgit v1.2.3 From 411a25a80da328f5ae6b6c037872ffe867fcc130 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 6 Jul 2010 15:38:56 -0700 Subject: memblock: No reason to include asm/memblock.h late Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 86e7daf742f2..4b6931327b22 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -16,6 +16,8 @@ #include #include +#include + #define MAX_MEMBLOCK_REGIONS 128 struct memblock_region { @@ -82,8 +84,6 @@ memblock_end_pfn(struct memblock_type *type, unsigned long region_nr) memblock_size_pages(type, region_nr); } -#include - #endif /* __KERNEL__ */ #endif /* _LINUX_MEMBLOCK_H */ -- cgit v1.2.3 From 72d4b0b4e0e7fa858767e03972771a9f7c02b689 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 4 Aug 2010 14:38:47 +1000 Subject: memblock: Implement memblock_is_memory and memblock_is_region_memory To make it fast, we steal ARM's binary search for memblock_is_memory() and we use that to also the replace existing implementation of memblock_is_reserved(). Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 4b6931327b22..47bceb187058 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -56,6 +56,8 @@ extern u64 __init __memblock_alloc_base(u64 size, extern u64 __init memblock_phys_mem_size(void); extern u64 memblock_end_of_DRAM(void); extern void __init memblock_enforce_memory_limit(u64 memory_limit); +extern int memblock_is_memory(u64 addr); +extern int memblock_is_region_memory(u64 base, u64 size); extern int __init memblock_is_reserved(u64 addr); extern int memblock_is_region_reserved(u64 base, u64 size); extern int memblock_find(struct memblock_region *res); -- cgit v1.2.3 From 5b385f259fa4d356452e3b4729cbaf5213f4f55b Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 4 Aug 2010 13:40:38 +1000 Subject: memblock: Introduce for_each_memblock() and new accessors Walk memblock's using for_each_memblock() and use memblock_region_base/end_pfn() for getting to PFNs. Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 47bceb187058..c914112cd24f 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -64,6 +64,7 @@ extern int memblock_find(struct memblock_region *res); extern void memblock_dump_all(void); +/* Obsolete accessors */ static inline u64 memblock_size_bytes(struct memblock_type *type, unsigned long region_nr) { @@ -86,6 +87,57 @@ memblock_end_pfn(struct memblock_type *type, unsigned long region_nr) memblock_size_pages(type, region_nr); } +/* + * pfn conversion functions + * + * While the memory MEMBLOCKs should always be page aligned, the reserved + * MEMBLOCKs may not be. This accessor attempt to provide a very clear + * idea of what they return for such non aligned MEMBLOCKs. + */ + +/** + * memblock_region_base_pfn - Return the lowest pfn intersecting with the region + * @reg: memblock_region structure + */ +static inline unsigned long memblock_region_base_pfn(const struct memblock_region *reg) +{ + return reg->base >> PAGE_SHIFT; +} + +/** + * memblock_region_last_pfn - Return the highest pfn intersecting with the region + * @reg: memblock_region structure + */ +static inline unsigned long memblock_region_last_pfn(const struct memblock_region *reg) +{ + return (reg->base + reg->size - 1) >> PAGE_SHIFT; +} + +/** + * memblock_region_end_pfn - Return the pfn of the first page following the region + * but not intersecting it + * @reg: memblock_region structure + */ +static inline unsigned long memblock_region_end_pfn(const struct memblock_region *reg) +{ + return memblock_region_last_pfn(reg) + 1; +} + +/** + * memblock_region_pages - Return the number of pages covering a region + * @reg: memblock_region structure + */ +static inline unsigned long memblock_region_pages(const struct memblock_region *reg) +{ + return memblock_region_end_pfn(reg) - memblock_region_end_pfn(reg); +} + +#define for_each_memblock(memblock_type, region) \ + for (region = memblock.memblock_type.regions; \ + region < (memblock.memblock_type.regions + memblock.memblock_type.cnt); \ + region++) + + #endif /* __KERNEL__ */ #endif /* _LINUX_MEMBLOCK_H */ -- cgit v1.2.3 From 1e2b904026e9debf95f500b8980a00c43ac0f31c Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 4 Aug 2010 13:52:25 +1000 Subject: memblock: Remove obsolete accessors Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 23 ----------------------- 1 file changed, 23 deletions(-) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index c914112cd24f..7d70fdd43db4 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -64,29 +64,6 @@ extern int memblock_find(struct memblock_region *res); extern void memblock_dump_all(void); -/* Obsolete accessors */ -static inline u64 -memblock_size_bytes(struct memblock_type *type, unsigned long region_nr) -{ - return type->regions[region_nr].size; -} -static inline u64 -memblock_size_pages(struct memblock_type *type, unsigned long region_nr) -{ - return memblock_size_bytes(type, region_nr) >> PAGE_SHIFT; -} -static inline u64 -memblock_start_pfn(struct memblock_type *type, unsigned long region_nr) -{ - return type->regions[region_nr].base >> PAGE_SHIFT; -} -static inline u64 -memblock_end_pfn(struct memblock_type *type, unsigned long region_nr) -{ - return memblock_start_pfn(type, region_nr) + - memblock_size_pages(type, region_nr); -} - /* * pfn conversion functions * -- cgit v1.2.3 From b693fffb189fbfe7e1e8317ce5838808be8666a0 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 4 Aug 2010 13:52:55 +1000 Subject: memblock: Remove memblock_find() Nobody uses it anymore. It's semantics were ... weird Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 7d70fdd43db4..776c7d945dcc 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -60,7 +60,6 @@ extern int memblock_is_memory(u64 addr); extern int memblock_is_region_memory(u64 base, u64 size); extern int __init memblock_is_reserved(u64 addr); extern int memblock_is_region_reserved(u64 base, u64 size); -extern int memblock_find(struct memblock_region *res); extern void memblock_dump_all(void); -- cgit v1.2.3 From 35a1f0bd07015dde66501b47cfb6ddc72ebe7346 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 6 Jul 2010 15:38:58 -0700 Subject: memblock: Remove nid_range argument, arch provides memblock_nid_range() instead Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 776c7d945dcc..367dea6e95a0 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -46,8 +46,7 @@ extern long memblock_add(u64 base, u64 size); extern long memblock_remove(u64 base, u64 size); extern long __init memblock_free(u64 base, u64 size); extern long __init memblock_reserve(u64 base, u64 size); -extern u64 __init memblock_alloc_nid(u64 size, u64 align, int nid, - u64 (*nid_range)(u64, u64, int *)); +extern u64 __init memblock_alloc_nid(u64 size, u64 align, int nid); extern u64 __init memblock_alloc(u64 size, u64 align); extern u64 __init memblock_alloc_base(u64 size, u64, u64 max_addr); @@ -63,6 +62,10 @@ extern int memblock_is_region_reserved(u64 base, u64 size); extern void memblock_dump_all(void); +/* Provided by the architecture */ +extern u64 memblock_nid_range(u64 start, u64 end, int *nid); + + /* * pfn conversion functions * -- cgit v1.2.3 From 27f574c223d2c09610058b3ec7a29582d63a3e06 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 6 Jul 2010 15:39:00 -0700 Subject: memblock: Expose MEMBLOCK_ALLOC_ANYWHERE Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 367dea6e95a0..3cf3304e901d 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -50,6 +50,7 @@ extern u64 __init memblock_alloc_nid(u64 size, u64 align, int nid); extern u64 __init memblock_alloc(u64 size, u64 align); extern u64 __init memblock_alloc_base(u64 size, u64, u64 max_addr); +#define MEMBLOCK_ALLOC_ANYWHERE 0 extern u64 __init __memblock_alloc_base(u64 size, u64 align, u64 max_addr); extern u64 __init memblock_phys_mem_size(void); -- cgit v1.2.3 From e63075a3c9377536d085bc013cd3fe6323162449 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 6 Jul 2010 15:39:01 -0700 Subject: memblock: Introduce default allocation limit and use it to replace explicit ones This introduce memblock.current_limit which is used to limit allocations from memblock_alloc() or memblock_alloc_base(..., MEMBLOCK_ALLOC_ACCESSIBLE). The old MEMBLOCK_ALLOC_ANYWHERE changes value from 0 to ~(u64)0 and can still be used with memblock_alloc_base() to allocate really anywhere. It is -no-longer- cropped to MEMBLOCK_REAL_LIMIT which disappears. Note to archs: I'm leaving the default limit to MEMBLOCK_ALLOC_ANYWHERE. I strongly recommend that you ensure that you set an appropriate limit during boot in order to guarantee that an memblock_alloc() at any time results in something that is accessible with a simple __va(). The reason is that a subsequent patch will introduce the ability for the array to resize itself by reallocating itself. The MEMBLOCK core will honor the current limit when performing those allocations. Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 3cf3304e901d..c4f6e53264ed 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -34,6 +34,7 @@ struct memblock_type { struct memblock { unsigned long debug; u64 rmo_size; + u64 current_limit; struct memblock_type memory; struct memblock_type reserved; }; @@ -46,11 +47,16 @@ extern long memblock_add(u64 base, u64 size); extern long memblock_remove(u64 base, u64 size); extern long __init memblock_free(u64 base, u64 size); extern long __init memblock_reserve(u64 base, u64 size); + extern u64 __init memblock_alloc_nid(u64 size, u64 align, int nid); extern u64 __init memblock_alloc(u64 size, u64 align); + +/* Flags for memblock_alloc_base() amd __memblock_alloc_base() */ +#define MEMBLOCK_ALLOC_ANYWHERE (~(u64)0) +#define MEMBLOCK_ALLOC_ACCESSIBLE 0 + extern u64 __init memblock_alloc_base(u64 size, u64, u64 max_addr); -#define MEMBLOCK_ALLOC_ANYWHERE 0 extern u64 __init __memblock_alloc_base(u64 size, u64 align, u64 max_addr); extern u64 __init memblock_phys_mem_size(void); @@ -66,6 +72,14 @@ extern void memblock_dump_all(void); /* Provided by the architecture */ extern u64 memblock_nid_range(u64 start, u64 end, int *nid); +/** + * memblock_set_current_limit - Set the current allocation limit to allow + * limiting allocations to what is currently + * accessible during boot + * @limit: New limit value (physical address) + */ +extern void memblock_set_current_limit(u64 limit); + /* * pfn conversion functions -- cgit v1.2.3 From cd3db0c4ca3d237e7ad20f7107216e575705d2b0 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 6 Jul 2010 15:39:02 -0700 Subject: memblock: Remove rmo_size, burry it in arch/powerpc where it belongs The RMA (RMO is a misnomer) is a concept specific to ppc64 (in fact server ppc64 though I hijack it on embedded ppc64 for similar purposes) and represents the area of memory that can be accessed in real mode (aka with MMU off), or on embedded, from the exception vectors (which is bolted in the TLB) which pretty much boils down to the same thing. We take that out of the generic MEMBLOCK data structure and move it into arch/powerpc where it belongs, renaming it to "RMA" while at it. Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index c4f6e53264ed..71b8edc6ede8 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -33,7 +33,6 @@ struct memblock_type { struct memblock { unsigned long debug; - u64 rmo_size; u64 current_limit; struct memblock_type memory; struct memblock_type reserved; -- cgit v1.2.3 From 2898cc4cdf208f15246b7a1c6951d2b126a70fd6 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 4 Aug 2010 13:34:42 +1000 Subject: memblock: Change u64 to phys_addr_t Let's not waste space and cycles on archs that don't support >32-bit physical address space. Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 71b8edc6ede8..b65045a4ed08 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -21,19 +21,19 @@ #define MAX_MEMBLOCK_REGIONS 128 struct memblock_region { - u64 base; - u64 size; + phys_addr_t base; + phys_addr_t size; }; struct memblock_type { unsigned long cnt; - u64 size; + phys_addr_t size; struct memblock_region regions[MAX_MEMBLOCK_REGIONS+1]; }; struct memblock { unsigned long debug; - u64 current_limit; + phys_addr_t current_limit; struct memblock_type memory; struct memblock_type reserved; }; @@ -42,34 +42,34 @@ extern struct memblock memblock; extern void __init memblock_init(void); extern void __init memblock_analyze(void); -extern long memblock_add(u64 base, u64 size); -extern long memblock_remove(u64 base, u64 size); -extern long __init memblock_free(u64 base, u64 size); -extern long __init memblock_reserve(u64 base, u64 size); +extern long memblock_add(phys_addr_t base, phys_addr_t size); +extern long memblock_remove(phys_addr_t base, phys_addr_t size); +extern long __init memblock_free(phys_addr_t base, phys_addr_t size); +extern long __init memblock_reserve(phys_addr_t base, phys_addr_t size); -extern u64 __init memblock_alloc_nid(u64 size, u64 align, int nid); -extern u64 __init memblock_alloc(u64 size, u64 align); +extern phys_addr_t __init memblock_alloc_nid(phys_addr_t size, phys_addr_t align, int nid); +extern phys_addr_t __init memblock_alloc(phys_addr_t size, phys_addr_t align); /* Flags for memblock_alloc_base() amd __memblock_alloc_base() */ -#define MEMBLOCK_ALLOC_ANYWHERE (~(u64)0) +#define MEMBLOCK_ALLOC_ANYWHERE (~(phys_addr_t)0) #define MEMBLOCK_ALLOC_ACCESSIBLE 0 -extern u64 __init memblock_alloc_base(u64 size, - u64, u64 max_addr); -extern u64 __init __memblock_alloc_base(u64 size, - u64 align, u64 max_addr); -extern u64 __init memblock_phys_mem_size(void); -extern u64 memblock_end_of_DRAM(void); -extern void __init memblock_enforce_memory_limit(u64 memory_limit); -extern int memblock_is_memory(u64 addr); -extern int memblock_is_region_memory(u64 base, u64 size); -extern int __init memblock_is_reserved(u64 addr); -extern int memblock_is_region_reserved(u64 base, u64 size); +extern phys_addr_t __init memblock_alloc_base(phys_addr_t size, + phys_addr_t, phys_addr_t max_addr); +extern phys_addr_t __init __memblock_alloc_base(phys_addr_t size, + phys_addr_t align, phys_addr_t max_addr); +extern phys_addr_t __init memblock_phys_mem_size(void); +extern phys_addr_t memblock_end_of_DRAM(void); +extern void __init memblock_enforce_memory_limit(phys_addr_t memory_limit); +extern int memblock_is_memory(phys_addr_t addr); +extern int memblock_is_region_memory(phys_addr_t base, phys_addr_t size); +extern int __init memblock_is_reserved(phys_addr_t addr); +extern int memblock_is_region_reserved(phys_addr_t base, phys_addr_t size); extern void memblock_dump_all(void); /* Provided by the architecture */ -extern u64 memblock_nid_range(u64 start, u64 end, int *nid); +extern phys_addr_t memblock_nid_range(phys_addr_t start, phys_addr_t end, int *nid); /** * memblock_set_current_limit - Set the current allocation limit to allow @@ -77,7 +77,7 @@ extern u64 memblock_nid_range(u64 start, u64 end, int *nid); * accessible during boot * @limit: New limit value (physical address) */ -extern void memblock_set_current_limit(u64 limit); +extern void memblock_set_current_limit(phys_addr_t limit); /* -- cgit v1.2.3 From 9d3c30f5a17ec35894eadb7171f724643dce19c3 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 6 Jul 2010 15:39:04 -0700 Subject: memblock: Remove unused memblock.debug struct member Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index b65045a4ed08..0fe6dd56a4b4 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -32,7 +32,6 @@ struct memblock_type { }; struct memblock { - unsigned long debug; phys_addr_t current_limit; struct memblock_type memory; struct memblock_type reserved; @@ -55,9 +54,11 @@ extern phys_addr_t __init memblock_alloc(phys_addr_t size, phys_addr_t align); #define MEMBLOCK_ALLOC_ACCESSIBLE 0 extern phys_addr_t __init memblock_alloc_base(phys_addr_t size, - phys_addr_t, phys_addr_t max_addr); + phys_addr_t align, + phys_addr_t max_addr); extern phys_addr_t __init __memblock_alloc_base(phys_addr_t size, - phys_addr_t align, phys_addr_t max_addr); + phys_addr_t align, + phys_addr_t max_addr); extern phys_addr_t __init memblock_phys_mem_size(void); extern phys_addr_t memblock_end_of_DRAM(void); extern void __init memblock_enforce_memory_limit(phys_addr_t memory_limit); -- cgit v1.2.3 From 4734b594c6ca1be796d30c82d93fdf5160f45124 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 28 Jul 2010 14:31:29 +1000 Subject: memblock: Remove memblock_type.size and add memblock.memory_size instead Right now, both the "memory" and "reserved" memblock_type structures have a "size" member. It represents the calculated memory size in the former case and is unused in the latter. This moves it out to the main memblock structure instead Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 0fe6dd56a4b4..c9c7b0f344a5 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -27,12 +27,12 @@ struct memblock_region { struct memblock_type { unsigned long cnt; - phys_addr_t size; struct memblock_region regions[MAX_MEMBLOCK_REGIONS+1]; }; struct memblock { phys_addr_t current_limit; + phys_addr_t memory_size; /* Updated by memblock_analyze() */ struct memblock_type memory; struct memblock_type reserved; }; -- cgit v1.2.3 From bf23c51f1f49d3960f3cd8e3d2e7f943d9c41042 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 6 Jul 2010 15:39:06 -0700 Subject: memblock: Move memblock arrays to static storage in memblock.c and make their size a variable This is in preparation for having resizable arrays. Note that we still allocate one more than needed, this is unchanged from the previous implementation. Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index c9c7b0f344a5..150be938b910 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -18,7 +18,7 @@ #include -#define MAX_MEMBLOCK_REGIONS 128 +#define INIT_MEMBLOCK_REGIONS 128 struct memblock_region { phys_addr_t base; @@ -26,8 +26,9 @@ struct memblock_region { }; struct memblock_type { - unsigned long cnt; - struct memblock_region regions[MAX_MEMBLOCK_REGIONS+1]; + unsigned long cnt; /* number of regions */ + unsigned long max; /* size of the allocated array */ + struct memblock_region *regions; }; struct memblock { -- cgit v1.2.3 From d2cd563ba82c424083b78e0ce97d68bfb04d1242 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 6 Jul 2010 15:39:14 -0700 Subject: memblock: Add arch function to control coalescing of memblock memory regions Some archs such as ARM want to avoid coalescing accross things such as the lowmem/highmem boundary or similar. This provides the option to control it via an arch callback for which a weak default is provided which always allows coalescing. Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 150be938b910..e5e8f9db3a84 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -72,6 +72,8 @@ extern void memblock_dump_all(void); /* Provided by the architecture */ extern phys_addr_t memblock_nid_range(phys_addr_t start, phys_addr_t end, int *nid); +extern int memblock_memory_can_coalesce(phys_addr_t addr1, phys_addr_t size1, + phys_addr_t addr2, phys_addr_t size2); /** * memblock_set_current_limit - Set the current allocation limit to allow -- cgit v1.2.3 From c196f76fd5ece716ee3b7fa5dda3576961c0cecc Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 6 Jul 2010 15:39:16 -0700 Subject: memblock: NUMA allocate can now use early_pfn_map We now provide a default (weak) implementation of memblock_nid_range() which uses the early_pfn_map[] if CONFIG_ARCH_POPULATES_NODE_MAP is set. Sparc still needs to use its own method due to the way the pages can be scattered between nodes. This implementation is inefficient due to our main algorithm and callback construct wanting to work on an ascending addresses bases while early_pfn_map[] would rather work with nid's (it's unsorted at that stage). But it should work and we can look into improving it subsequently, possibly using arch compile options to chose a different algorithm alltogether. Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index e5e8f9db3a84..82b030244aa7 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -47,6 +47,9 @@ extern long memblock_remove(phys_addr_t base, phys_addr_t size); extern long __init memblock_free(phys_addr_t base, phys_addr_t size); extern long __init memblock_reserve(phys_addr_t base, phys_addr_t size); +/* The numa aware allocator is only available if + * CONFIG_ARCH_POPULATES_NODE_MAP is set + */ extern phys_addr_t __init memblock_alloc_nid(phys_addr_t size, phys_addr_t align, int nid); extern phys_addr_t __init memblock_alloc(phys_addr_t size, phys_addr_t align); -- cgit v1.2.3 From 9d1e24928e6a0728d1c7c76818ccbd11b93e7ac9 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 6 Jul 2010 15:39:17 -0700 Subject: memblock: Separate memblock_alloc_nid() and memblock_alloc_try_nid() The former is now strict, it will fail if it cannot honor the allocation within the node, while the later implements the previous semantic which falls back to allocating anywhere. Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 82b030244aa7..c8da03eb7ba3 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -50,7 +50,11 @@ extern long __init memblock_reserve(phys_addr_t base, phys_addr_t size); /* The numa aware allocator is only available if * CONFIG_ARCH_POPULATES_NODE_MAP is set */ -extern phys_addr_t __init memblock_alloc_nid(phys_addr_t size, phys_addr_t align, int nid); +extern phys_addr_t __init memblock_alloc_nid(phys_addr_t size, phys_addr_t align, + int nid); +extern phys_addr_t __init memblock_alloc_try_nid(phys_addr_t size, phys_addr_t align, + int nid); + extern phys_addr_t __init memblock_alloc(phys_addr_t size, phys_addr_t align); /* Flags for memblock_alloc_base() amd __memblock_alloc_base() */ -- cgit v1.2.3 From 5e63cf43af844ed30acc278b38b8c9bc51eba493 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 28 Jul 2010 15:07:21 +1000 Subject: memblock: Expose some memblock bits for use by x86 This exposes memblock_debug and associated memblock_dbg() macro, along with memblock_can_resize so that x86 can use these when ported to use memblock Signed-off-by: Yinghai Lu Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index c8da03eb7ba3..eed0f9b8e526 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -39,6 +39,11 @@ struct memblock { }; extern struct memblock memblock; +extern int memblock_debug; +extern int memblock_can_resize; + +#define memblock_dbg(fmt, ...) \ + if (memblock_debug) printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) extern void __init memblock_init(void); extern void __init memblock_analyze(void); -- cgit v1.2.3 From 37d8d4bf489e39eedc9537f8616fe87879b13cb0 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 28 Jul 2010 15:20:58 +1000 Subject: memblock: Export MEMBLOCK_ERROR will used by x86 memblock_x86_find_in_range_node and nobootmem replacement Signed-off-by: Yinghai Lu Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index eed0f9b8e526..1a9c29cc92fa 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -18,7 +18,8 @@ #include -#define INIT_MEMBLOCK_REGIONS 128 +#define INIT_MEMBLOCK_REGIONS 128 +#define MEMBLOCK_ERROR (~(phys_addr_t)0) struct memblock_region { phys_addr_t base; -- cgit v1.2.3 From 25818f0f288cd5333ba5a90ad6dde3def4c4ff58 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 28 Jul 2010 15:25:10 +1000 Subject: memblock: Make MEMBLOCK_ERROR be 0 And ensure we don't hand out 0 as a valid allocation. We put the low limit at PAGE_SIZE arbitrarily. Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 1a9c29cc92fa..dfa64494ced1 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -19,7 +19,7 @@ #include #define INIT_MEMBLOCK_REGIONS 128 -#define MEMBLOCK_ERROR (~(phys_addr_t)0) +#define MEMBLOCK_ERROR 0 struct memblock_region { phys_addr_t base; -- cgit v1.2.3 From f0b37fad9a63217c39997b2d2b31f44e3d8be727 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 28 Jul 2010 15:28:21 +1000 Subject: memblock: Protect memblock.h with CONFIG_HAVE_MEMBLOCK This should make it easier to catch/debug incorrect use when the CONFIG_ option isn't set. Signed-off-by: Yinghai Lu Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index dfa64494ced1..c24b27849096 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -2,6 +2,7 @@ #define _LINUX_MEMBLOCK_H #ifdef __KERNEL__ +#ifdef CONFIG_HAVE_MEMBLOCK /* * Logical memory blocks. * @@ -148,6 +149,8 @@ static inline unsigned long memblock_region_pages(const struct memblock_region * region++) +#endif /* CONFIG_HAVE_MEMBLOCK */ + #endif /* __KERNEL__ */ #endif /* _LINUX_MEMBLOCK_H */ -- cgit v1.2.3 From 10d0643988e976360eb3497dcafb55b393b8e480 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 28 Jul 2010 15:43:02 +1000 Subject: memblock: Option for the architecture to put memblock into the .init section Arch code can define ARCH_DISCARD_MEMBLOCK in asm/memblock.h, which in turns causes memblock code and data to go respectively into the .init and .initdata sections. This will be used by the x86 architecture. If ARCH_DISCARD_MEMBLOCK is defined, the debugfs files to inspect the memblock arrays after boot are not created. Signed-off-by: Yinghai Lu Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index c24b27849096..3978e6a8e824 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -149,6 +149,14 @@ static inline unsigned long memblock_region_pages(const struct memblock_region * region++) +#ifdef ARCH_DISCARD_MEMBLOCK +#define __init_memblock __init +#define __initdata_memblock __initdata +#else +#define __init_memblock +#define __initdata_memblock +#endif + #endif /* CONFIG_HAVE_MEMBLOCK */ #endif /* __KERNEL__ */ -- cgit v1.2.3 From 5303b68f57c227c27193a14e57dd12be27cd670f Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 28 Jul 2010 15:38:40 +1000 Subject: memblock: Add memblock_find_in_range() This is a wrapper for memblock_find_base() using slightly different arguments (start,end instead of start,size for example) in order to make it easier to convert existing arch/x86 code. Signed-off-by: Yinghai Lu Signed-off-by: Benjamin Herrenschmidt --- include/linux/memblock.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 3978e6a8e824..4df09bdcae42 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -47,6 +47,8 @@ extern int memblock_can_resize; #define memblock_dbg(fmt, ...) \ if (memblock_debug) printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) +u64 memblock_find_in_range(u64 start, u64 end, u64 size, u64 align); + extern void __init memblock_init(void); extern void __init memblock_analyze(void); extern long memblock_add(phys_addr_t base, phys_addr_t size); -- cgit v1.2.3 From 9a76f1ff6e299fbb04149fe15aff061351fd0dab Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 5 Aug 2010 13:20:59 +0100 Subject: ASoC: Add initial WM8962 CODEC driver The WM8962 is a low power, high performance stereo CODEC designed for portable digital audio applications. This initial driver release supports the key audio paths of the WM8962. Extended functionality, such as microphone detection, digital microphones and the advanced DSP signal enhancements provided by the device are not yet supported. Signed-off-by: Mark Brown --- include/sound/wm8962.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 include/sound/wm8962.h (limited to 'include') diff --git a/include/sound/wm8962.h b/include/sound/wm8962.h new file mode 100644 index 000000000000..f70258e3471c --- /dev/null +++ b/include/sound/wm8962.h @@ -0,0 +1,23 @@ +/* + * wm8962.h -- WM8962 Soc Audio driver platform data + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _WM8962_PDATA_H +#define _WM8962_PDATA_H + +#define WM8962_MAX_GPIO 6 + +/* Use to set GPIO default values to zero */ +#define WM8962_GPIO_SET 0x10000 + +struct wm8962_pdata { + u32 gpio_init[WM8962_MAX_GPIO]; + + bool spk_mono; /* Speaker outputs tied together as mono */ +}; + +#endif -- cgit v1.2.3 From 73e4008ddddc84d5f2499c17012b340a0dae153e Mon Sep 17 00:00:00 2001 From: Nikolai Kondrashov Date: Fri, 6 Aug 2010 23:03:06 +0400 Subject: HID: allow resizing and replacing report descriptors Update hid_driver's report_fixup prototype to allow changing report descriptor size and/or returning completely different report descriptor. Update existing usage accordingly. This is to give more freedom in descriptor fixup and to allow having a whole fixed descriptor in the code for the sake of readability. Signed-off-by: Nikolai Kondrashov Signed-off-by: Jiri Kosina --- include/linux/hid.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/hid.h b/include/linux/hid.h index 42a0f1d11365..0a34fb071379 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -626,8 +626,8 @@ struct hid_driver { int (*event)(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage, __s32 value); - void (*report_fixup)(struct hid_device *hdev, __u8 *buf, - unsigned int size); + __u8 *(*report_fixup)(struct hid_device *hdev, __u8 *buf, + unsigned int *size); int (*input_mapping)(struct hid_device *hdev, struct hid_input *hidinput, struct hid_field *field, -- cgit v1.2.3 From f0fba2ad1b6b53d5360125c41953b7afcd6deff0 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Wed, 17 Mar 2010 20:15:21 +0000 Subject: ASoC: multi-component - ASoC Multi-Component Support This patch extends the ASoC API to allow sound cards to have more than one CODEC and more than one platform DMA controller. This is achieved by dividing some current ASoC structures that contain both driver data and device data into structures that only either contain device data or driver data. i.e. struct snd_soc_codec ---> struct snd_soc_codec (device data) +-> struct snd_soc_codec_driver (driver data) struct snd_soc_platform ---> struct snd_soc_platform (device data) +-> struct snd_soc_platform_driver (driver data) struct snd_soc_dai ---> struct snd_soc_dai (device data) +-> struct snd_soc_dai_driver (driver data) struct snd_soc_device ---> deleted This now allows ASoC to be more tightly aligned with the Linux driver model and also means that every ASoC codec, platform and (platform) DAI is a kernel device. ASoC component private data is now stored as device private data. The ASoC sound card struct snd_soc_card has also been updated to store lists of it's components rather than a pointer to a codec and platform. The PCM runtime struct soc_pcm_runtime now has pointers to all its components. This patch adds DAPM support for ASoC multi-component and removes struct snd_soc_socdev from DAPM core. All DAPM calls are now made on a card, codec or runtime PCM level basis rather than using snd_soc_socdev. Other notable multi-component changes:- * Stream operations now de-reference less structures. * close_delayed work() now runs on a DAI basis rather than looping all DAIs in a card. * PM suspend()/resume() operations can now handle N CODECs and Platforms per sound card. * Added soc_bind_dai_link() to bind the component devices to the sound card. * Added soc_dai_link_probe() and soc_dai_link_remove() to probe and remove DAI link components. * sysfs entries can now be registered per component per card. * snd_soc_new_pcms() functionailty rolled into dai_link_probe(). * snd_soc_register_codec() now does all the codec list and mutex init. This patch changes the probe() and remove() of the CODEC drivers as follows:- o Make CODEC driver a platform driver o Moved all struct snd_soc_codec list, mutex, etc initialiasation to core. o Removed all static codec pointers (drivers now support > 1 codec dev) o snd_soc_register_pcms() now done by core. o snd_soc_register_dai() folded into snd_soc_register_codec(). CS4270 portions: Acked-by: Timur Tabi Some TLV320aic23 and Cirrus platform fixes. Signed-off-by: Ryan Mallon TI CODEC and OMAP fixes Signed-off-by: Peter Ujfalusi Signed-off-by: Janusz Krzysztofik Signed-off-by: Jarkko Nikula Samsung platform and misc fixes :- Signed-off-by: Chanwoo Choi Signed-off-by: Joonyoung Shim Signed-off-by: Kyungmin Park Reviewed-by: Jassi Brar Signed-off-by: Seungwhan Youn MPC8610 and PPC fixes. Signed-off-by: Timur Tabi i.MX fixes and some core fixes. Signed-off-by: Sascha Hauer J4740 platform fixes:- Signed-off-by: Lars-Peter Clausen CC: Tony Lindgren CC: Nicolas Ferre CC: Kevin Hilman CC: Sascha Hauer CC: Atsushi Nemoto CC: Kuninori Morimoto CC: Daniel Gloeckner CC: Manuel Lauss CC: Mike Frysinger CC: Arnaud Patard CC: Wan ZongShun Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- include/linux/i2c/twl.h | 6 +- include/sound/sh_fsi.h | 4 +- include/sound/soc-dai.h | 98 +++++++++++------- include/sound/soc-dapm.h | 8 +- include/sound/soc-of-simple.h | 25 ----- include/sound/soc.h | 236 +++++++++++++++++++++++++----------------- include/sound/tlv320aic3x.h | 43 +++++++- 7 files changed, 259 insertions(+), 161 deletions(-) delete mode 100644 include/sound/soc-of-simple.h (limited to 'include') diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index 6de90bfc6acd..4793d8a7f480 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h @@ -553,8 +553,12 @@ extern void twl4030_power_init(struct twl4030_power_data *triton2_scripts); extern int twl4030_remove_script(u8 flags); struct twl4030_codec_audio_data { - unsigned int audio_mclk; + unsigned int audio_mclk; /* not used, will be removed */ + unsigned int digimic_delay; /* in ms */ unsigned int ramp_delay_value; + unsigned int offset_cncl_path; + unsigned int check_defaults:1; + unsigned int reset_registers:1; unsigned int hs_extmute:1; void (*set_hs_extmute)(int mute); }; diff --git a/include/sound/sh_fsi.h b/include/sound/sh_fsi.h index 9d51d6f35893..3fd6456d07d7 100644 --- a/include/sound/sh_fsi.h +++ b/include/sound/sh_fsi.h @@ -114,7 +114,7 @@ struct sh_fsi_platform_info { int (*set_rate)(int is_porta, int rate); /* for master mode */ }; -extern struct snd_soc_dai fsi_soc_dai[2]; -extern struct snd_soc_platform fsi_soc_platform; +extern struct snd_soc_dai_driver fsi_soc_dai[2]; +extern struct snd_soc_platform_driver fsi_soc_platform; #endif /* __SOUND_FSI_H */ diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 377693a14385..e7b680248006 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -91,15 +91,17 @@ struct snd_pcm_substream; SNDRV_PCM_FMTBIT_S32_LE |\ SNDRV_PCM_FMTBIT_S32_BE) -struct snd_soc_dai_ops; +struct snd_soc_dai_driver; struct snd_soc_dai; struct snd_ac97_bus_ops; /* Digital Audio Interface registration */ -int snd_soc_register_dai(struct snd_soc_dai *dai); -void snd_soc_unregister_dai(struct snd_soc_dai *dai); -int snd_soc_register_dais(struct snd_soc_dai *dai, size_t count); -void snd_soc_unregister_dais(struct snd_soc_dai *dai, size_t count); +int snd_soc_register_dai(struct device *dev, + struct snd_soc_dai_driver *dai_drv); +void snd_soc_unregister_dai(struct device *dev); +int snd_soc_register_dais(struct device *dev, + struct snd_soc_dai_driver *dai_drv, size_t count); +void snd_soc_unregister_dais(struct device *dev, size_t count); /* Digital Audio Interface clocking API.*/ int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, @@ -126,16 +128,6 @@ int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate); /* Digital Audio Interface mute */ int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute); -/* - * Digital Audio Interface. - * - * Describes the Digital Audio Interface in terms of its ALSA, DAI and AC97 - * operations and capabilities. Codec and platform drivers will register this - * structure for every DAI they have. - * - * This structure covers the clocking, formating and ALSA operations for each - * interface. - */ struct snd_soc_dai_ops { /* * DAI clocking configuration, all optional. @@ -191,24 +183,24 @@ struct snd_soc_dai_ops { }; /* - * Digital Audio Interface runtime data. + * Digital Audio Interface Driver. * - * Holds runtime data for a DAI. + * Describes the Digital Audio Interface in terms of its ALSA, DAI and AC97 + * operations and capabilities. Codec and platform drivers will register this + * structure for every DAI they have. + * + * This structure covers the clocking, formating and ALSA operations for each + * interface. */ -struct snd_soc_dai { +struct snd_soc_dai_driver { /* DAI description */ - char *name; + const char *name; unsigned int id; int ac97_control; - struct device *dev; - void *ac97_pdata; /* platform_data for the ac97 codec */ - - /* DAI callbacks */ - int (*probe)(struct platform_device *pdev, - struct snd_soc_dai *dai); - void (*remove)(struct platform_device *pdev, - struct snd_soc_dai *dai); + /* DAI driver callbacks */ + int (*probe)(struct snd_soc_dai *dai); + int (*remove)(struct snd_soc_dai *dai); int (*suspend)(struct snd_soc_dai *dai); int (*resume)(struct snd_soc_dai *dai); @@ -219,26 +211,51 @@ struct snd_soc_dai { struct snd_soc_pcm_stream capture; struct snd_soc_pcm_stream playback; unsigned int symmetric_rates:1; +}; + +/* + * Digital Audio Interface runtime data. + * + * Holds runtime data for a DAI. + */ +struct snd_soc_dai { + const char *name; + int id; + struct device *dev; + void *ac97_pdata; /* platform_data for the ac97 codec */ + + /* driver ops */ + struct snd_soc_dai_driver *driver; /* DAI runtime info */ - struct snd_soc_codec *codec; + unsigned int capture_active:1; /* stream is in use */ + unsigned int playback_active:1; /* stream is in use */ + unsigned int symmetric_rates:1; + struct snd_pcm_runtime *runtime; unsigned int active; unsigned char pop_wait:1; + unsigned char probed:1; - /* DAI private data */ - void *private_data; + /* DAI DMA data */ + void *playback_dma_data; + void *capture_dma_data; - /* parent platform */ - struct snd_soc_platform *platform; + /* parent platform/codec */ + union { + struct snd_soc_platform *platform; + struct snd_soc_codec *codec; + }; + struct snd_soc_card *card; struct list_head list; + struct list_head card_list; }; static inline void *snd_soc_dai_get_dma_data(const struct snd_soc_dai *dai, const struct snd_pcm_substream *ss) { return (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) ? - dai->playback.dma_data : dai->capture.dma_data; + dai->playback_dma_data : dai->capture_dma_data; } static inline void snd_soc_dai_set_dma_data(struct snd_soc_dai *dai, @@ -246,9 +263,20 @@ static inline void snd_soc_dai_set_dma_data(struct snd_soc_dai *dai, void *data) { if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) - dai->playback.dma_data = data; + dai->playback_dma_data = data; else - dai->capture.dma_data = data; + dai->capture_dma_data = data; +} + +static inline void snd_soc_dai_set_drvdata(struct snd_soc_dai *dai, + void *data) +{ + dev_set_drvdata(dai->dev, data); +} + +static inline void *snd_soc_dai_get_drvdata(struct snd_soc_dai *dai) +{ + return dev_get_drvdata(dai->dev); } #endif diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index c5d9987bc897..c4a445651ca0 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -322,14 +322,14 @@ int snd_soc_dapm_new_controls(struct snd_soc_codec *codec, /* dapm path setup */ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec); -void snd_soc_dapm_free(struct snd_soc_device *socdev); +void snd_soc_dapm_free(struct snd_soc_codec *codec); int snd_soc_dapm_add_routes(struct snd_soc_codec *codec, const struct snd_soc_dapm_route *route, int num); /* dapm events */ -int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, char *stream, - int event); -void snd_soc_dapm_shutdown(struct snd_soc_device *socdev); +int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, + const char *stream, int event); +void snd_soc_dapm_shutdown(struct snd_soc_card *card); /* dapm sys fs - used by the core */ int snd_soc_dapm_sys_add(struct device *dev); diff --git a/include/sound/soc-of-simple.h b/include/sound/soc-of-simple.h deleted file mode 100644 index a064e1934a56..000000000000 --- a/include/sound/soc-of-simple.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * OF helpers for ALSA SoC - * - * Copyright (C) 2008, Secret Lab Technologies Ltd. - */ - -#ifndef _INCLUDE_SOC_OF_H_ -#define _INCLUDE_SOC_OF_H_ - -#if defined(CONFIG_SND_SOC_OF_SIMPLE) || defined(CONFIG_SND_SOC_OF_SIMPLE_MODULE) - -#include -#include - -int of_snd_soc_register_codec(struct snd_soc_codec_device *codec_dev, - void *codec_data, struct snd_soc_dai *dai, - struct device_node *node); - -int of_snd_soc_register_platform(struct snd_soc_platform *platform, - struct device_node *node, - struct snd_soc_dai *cpu_dai); - -#endif - -#endif /* _INCLUDE_SOC_OF_H_ */ diff --git a/include/sound/soc.h b/include/sound/soc.h index 65e9d03ed4f5..d31e8b7b2d5e 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -228,13 +228,17 @@ struct snd_soc_ops; struct snd_soc_dai_mode; struct snd_soc_pcm_runtime; struct snd_soc_dai; +struct snd_soc_dai_driver; struct snd_soc_platform; struct snd_soc_dai_link; +struct snd_soc_platform_driver; struct snd_soc_codec; +struct snd_soc_codec_driver; struct soc_enum; struct snd_soc_ac97_ops; struct snd_soc_jack; struct snd_soc_jack_pin; + #ifdef CONFIG_GPIOLIB struct snd_soc_jack_gpio; #endif @@ -249,19 +253,18 @@ enum snd_soc_control_type { SND_SOC_SPI, }; -int snd_soc_register_platform(struct snd_soc_platform *platform); -void snd_soc_unregister_platform(struct snd_soc_platform *platform); -int snd_soc_register_codec(struct snd_soc_codec *codec); -void snd_soc_unregister_codec(struct snd_soc_codec *codec); +int snd_soc_register_platform(struct device *dev, + struct snd_soc_platform_driver *platform_drv); +void snd_soc_unregister_platform(struct device *dev); +int snd_soc_register_codec(struct device *dev, + struct snd_soc_codec_driver *codec_drv, + struct snd_soc_dai_driver *dai_drv, int num_dai); +void snd_soc_unregister_codec(struct device *dev); int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg); int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, int addr_bits, int data_bits, enum snd_soc_control_type control); -/* pcm <-> DAI connect */ -void snd_soc_free_pcms(struct snd_soc_device *socdev); -int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid); - /* Utility functions to get clock rates from various things */ int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots); int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params); @@ -273,7 +276,7 @@ int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream, const struct snd_pcm_hardware *hw); /* Jack reporting */ -int snd_soc_jack_new(struct snd_soc_card *card, const char *id, int type, +int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type, struct snd_soc_jack *jack); void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask); int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count, @@ -390,7 +393,7 @@ struct snd_soc_jack_gpio { struct snd_soc_jack { struct snd_jack *jack; - struct snd_soc_card *card; + struct snd_soc_codec *codec; struct list_head pins; int status; struct blocking_notifier_head notifier; @@ -398,15 +401,13 @@ struct snd_soc_jack { /* SoC PCM stream information */ struct snd_soc_pcm_stream { - char *stream_name; + const char *stream_name; u64 formats; /* SNDRV_PCM_FMTBIT_* */ unsigned int rates; /* SNDRV_PCM_RATE_* */ unsigned int rate_min; /* min rate */ unsigned int rate_max; /* max rate */ unsigned int channels_min; /* min channels */ unsigned int channels_max; /* max channels */ - unsigned int active; /* stream is in use */ - void *dma_data; /* used by platform code */ }; /* SoC audio ops */ @@ -419,44 +420,35 @@ struct snd_soc_ops { int (*trigger)(struct snd_pcm_substream *, int); }; -/* SoC Audio Codec */ +/* SoC Audio Codec device */ struct snd_soc_codec { - char *name; - struct module *owner; - struct mutex mutex; + const char *name; + int id; struct device *dev; - struct snd_soc_device *socdev; + struct snd_soc_codec_driver *driver; + struct mutex mutex; + struct snd_soc_card *card; struct list_head list; - - /* callbacks */ - int (*set_bias_level)(struct snd_soc_codec *, - enum snd_soc_bias_level level); + struct list_head card_list; + int num_dai; /* runtime */ - struct snd_card *card; struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ unsigned int active; - unsigned int pcm_devs; - void *drvdata; + unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */ + unsigned int cache_only:1; /* Suppress writes to hardware */ + unsigned int cache_sync:1; /* Cache needs to be synced to hardware */ + unsigned int suspended:1; /* Codec is in suspend PM state */ + unsigned int probed:1; /* Codec has been probed */ + unsigned int ac97_registered:1; /* Codec has been AC97 registered */ + unsigned int sysfs_registered:1; /* codec has been sysfs registered */ /* codec IO */ void *control_data; /* codec control (i2c/3wire) data */ - unsigned int (*read)(struct snd_soc_codec *, unsigned int); - int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); - int (*display_register)(struct snd_soc_codec *, char *, - size_t, unsigned int); - int (*volatile_register)(unsigned int); - int (*readable_register)(unsigned int); hw_write_t hw_write; unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int); void *reg_cache; - short reg_cache_size; - short reg_cache_step; - - unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */ - unsigned int cache_only:1; /* Suppress writes to hardware */ - unsigned int cache_sync:1; /* Cache needs to be synced to hardware */ /* dapm */ u32 pop_time; @@ -466,10 +458,6 @@ struct snd_soc_codec { enum snd_soc_bias_level suspend_bias_level; struct delayed_work delayed_work; - /* codec DAI's */ - struct snd_soc_dai *dai; - unsigned int num_dai; - #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_codec_root; struct dentry *debugfs_reg; @@ -478,23 +466,40 @@ struct snd_soc_codec { #endif }; -/* codec device */ -struct snd_soc_codec_device { - int (*probe)(struct platform_device *pdev); - int (*remove)(struct platform_device *pdev); - int (*suspend)(struct platform_device *pdev, pm_message_t state); - int (*resume)(struct platform_device *pdev); +/* codec driver */ +struct snd_soc_codec_driver { + + /* driver ops */ + int (*probe)(struct snd_soc_codec *); + int (*remove)(struct snd_soc_codec *); + int (*suspend)(struct snd_soc_codec *, + pm_message_t state); + int (*resume)(struct snd_soc_codec *); + + /* codec IO */ + unsigned int (*read)(struct snd_soc_codec *, unsigned int); + int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); + int (*display_register)(struct snd_soc_codec *, char *, + size_t, unsigned int); + int (*volatile_register)(unsigned int); + int (*readable_register)(unsigned int); + short reg_cache_size; + short reg_cache_step; + short reg_word_size; + const void *reg_cache_default; + + /* codec bias level */ + int (*set_bias_level)(struct snd_soc_codec *, + enum snd_soc_bias_level level); }; /* SoC platform interface */ -struct snd_soc_platform { - char *name; - struct list_head list; +struct snd_soc_platform_driver { - int (*probe)(struct platform_device *pdev); - int (*remove)(struct platform_device *pdev); - int (*suspend)(struct snd_soc_dai_link *dai_link); - int (*resume)(struct snd_soc_dai_link *dai_link); + int (*probe)(struct snd_soc_platform *); + int (*remove)(struct snd_soc_platform *); + int (*suspend)(struct snd_soc_dai *dai); + int (*resume)(struct snd_soc_dai *dai); /* pcm creation and destruction */ int (*pcm_new)(struct snd_card *, struct snd_soc_dai *, @@ -509,23 +514,31 @@ struct snd_soc_platform { struct snd_soc_dai *); /* platform stream ops */ - struct snd_pcm_ops *pcm_ops; + struct snd_pcm_ops *ops; }; -/* SoC machine DAI configuration, glues a codec and cpu DAI together */ -struct snd_soc_dai_link { - char *name; /* Codec name */ - char *stream_name; /* Stream name */ +struct snd_soc_platform { + const char *name; + int id; + struct device *dev; + struct snd_soc_platform_driver *driver; - /* DAI */ - struct snd_soc_dai *codec_dai; - struct snd_soc_dai *cpu_dai; + unsigned int suspended:1; /* platform is suspended */ + unsigned int probed:1; - /* machine stream operations */ - struct snd_soc_ops *ops; + struct snd_soc_card *card; + struct list_head list; + struct list_head card_list; +}; - /* codec/machine specific init - e.g. add machine controls */ - int (*init)(struct snd_soc_codec *codec); +struct snd_soc_dai_link { + /* config - must be set by machine driver */ + const char *name; /* Codec name */ + const char *stream_name; /* Stream name */ + const char *codec_name; /* for multi-codec */ + const char *platform_name; /* for multi-platform */ + const char *cpu_dai_name; + const char *codec_dai_name; /* Keep DAI active over suspend */ unsigned int ignore_suspend:1; @@ -533,21 +546,24 @@ struct snd_soc_dai_link { /* Symmetry requirements */ unsigned int symmetric_rates:1; - /* Symmetry data - only valid if symmetry is being enforced */ - unsigned int rate; + /* codec/machine specific init - e.g. add machine controls */ + int (*init)(struct snd_soc_pcm_runtime *rtd); - /* DAI pcm */ - struct snd_pcm *pcm; + /* machine stream operations */ + struct snd_soc_ops *ops; }; /* SoC card */ struct snd_soc_card { - char *name; + const char *name; struct device *dev; + struct snd_card *snd_card; + struct module *owner; struct list_head list; + struct mutex mutex; - int instantiated; + bool instantiated; int (*probe)(struct platform_device *pdev); int (*remove)(struct platform_device *pdev); @@ -568,28 +584,38 @@ struct snd_soc_card { /* CPU <--> Codec DAI links */ struct snd_soc_dai_link *dai_link; int num_links; + struct snd_soc_pcm_runtime *rtd; + int num_rtd; - struct snd_soc_device *socdev; - - struct snd_soc_codec *codec; - - struct snd_soc_platform *platform; - struct delayed_work delayed_work; struct work_struct deferred_resume_work; + + /* lists of probed devices belonging to this card */ + struct list_head codec_dev_list; + struct list_head platform_dev_list; + struct list_head dai_dev_list; }; -/* SoC Device - the audio subsystem */ -struct snd_soc_device { - struct device *dev; +/* SoC machine DAI configuration, glues a codec and cpu DAI together */ +struct snd_soc_pcm_runtime { + struct device dev; struct snd_soc_card *card; - struct snd_soc_codec_device *codec_dev; - void *codec_data; -}; + struct snd_soc_dai_link *dai_link; + + unsigned int complete:1; + unsigned int dev_registered:1; -/* runtime channel data */ -struct snd_soc_pcm_runtime { - struct snd_soc_dai_link *dai; - struct snd_soc_device *socdev; + /* Symmetry data - only valid if symmetry is being enforced */ + unsigned int rate; + long pmdown_time; + + /* runtime devices */ + struct snd_pcm *pcm; + struct snd_soc_codec *codec; + struct snd_soc_platform *platform; + struct snd_soc_dai *codec_dai; + struct snd_soc_dai *cpu_dai; + + struct delayed_work delayed_work; }; /* mixer control */ @@ -615,24 +641,48 @@ struct soc_enum { static inline unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg) { - return codec->read(codec, reg); + return codec->driver->read(codec, reg); } static inline unsigned int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int val) { - return codec->write(codec, reg, val); + return codec->driver->write(codec, reg, val); } +/* device driver data */ + static inline void snd_soc_codec_set_drvdata(struct snd_soc_codec *codec, - void *data) + void *data) { - codec->drvdata = data; + dev_set_drvdata(codec->dev, data); } static inline void *snd_soc_codec_get_drvdata(struct snd_soc_codec *codec) { - return codec->drvdata; + return dev_get_drvdata(codec->dev); +} + +static inline void snd_soc_platform_set_drvdata(struct snd_soc_platform *platform, + void *data) +{ + dev_set_drvdata(platform->dev, data); +} + +static inline void *snd_soc_platform_get_drvdata(struct snd_soc_platform *platform) +{ + return dev_get_drvdata(platform->dev); +} + +static inline void snd_soc_pcm_set_drvdata(struct snd_soc_pcm_runtime *rtd, + void *data) +{ + dev_set_drvdata(&rtd->dev, data); +} + +static inline void *snd_soc_pcm_get_drvdata(struct snd_soc_pcm_runtime *rtd) +{ + return dev_get_drvdata(&rtd->dev); } #include diff --git a/include/sound/tlv320aic3x.h b/include/sound/tlv320aic3x.h index b1a5f34e5cfa..99e0308bf2c2 100644 --- a/include/sound/tlv320aic3x.h +++ b/include/sound/tlv320aic3x.h @@ -10,8 +10,49 @@ #ifndef __TLV320AIC3x_H__ #define __TLV320AIC3x_H__ +/* GPIO API */ +enum { + AIC3X_GPIO1_FUNC_DISABLED = 0, + AIC3X_GPIO1_FUNC_AUDIO_WORDCLK_ADC = 1, + AIC3X_GPIO1_FUNC_CLOCK_MUX = 2, + AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV2 = 3, + AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV4 = 4, + AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV8 = 5, + AIC3X_GPIO1_FUNC_SHORT_CIRCUIT_IRQ = 6, + AIC3X_GPIO1_FUNC_AGC_NOISE_IRQ = 7, + AIC3X_GPIO1_FUNC_INPUT = 8, + AIC3X_GPIO1_FUNC_OUTPUT = 9, + AIC3X_GPIO1_FUNC_DIGITAL_MIC_MODCLK = 10, + AIC3X_GPIO1_FUNC_AUDIO_WORDCLK = 11, + AIC3X_GPIO1_FUNC_BUTTON_IRQ = 12, + AIC3X_GPIO1_FUNC_HEADSET_DETECT_IRQ = 13, + AIC3X_GPIO1_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 14, + AIC3X_GPIO1_FUNC_ALL_IRQ = 16 +}; + +enum { + AIC3X_GPIO2_FUNC_DISABLED = 0, + AIC3X_GPIO2_FUNC_HEADSET_DETECT_IRQ = 2, + AIC3X_GPIO2_FUNC_INPUT = 3, + AIC3X_GPIO2_FUNC_OUTPUT = 4, + AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT = 5, + AIC3X_GPIO2_FUNC_AUDIO_BITCLK = 8, + AIC3X_GPIO2_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 9, + AIC3X_GPIO2_FUNC_ALL_IRQ = 10, + AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_OR_AGC_IRQ = 11, + AIC3X_GPIO2_FUNC_HEADSET_OR_BUTTON_PRESS_OR_SHORT_CIRCUIT_IRQ = 12, + AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_IRQ = 13, + AIC3X_GPIO2_FUNC_AGC_NOISE_IRQ = 14, + AIC3X_GPIO2_FUNC_BUTTON_PRESS_IRQ = 15 +}; + +struct aic3x_setup_data { + unsigned int gpio_func[2]; +}; + struct aic3x_pdata { int gpio_reset; /* < 0 if not used */ + struct aic3x_setup_data *setup; }; -#endif \ No newli