From b0f82b81fe6bbcf78d478071f33e44554726bc81 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Thu, 20 May 2010 07:47:21 +0200 Subject: perf: Drop the skip argument from perf_arch_fetch_regs_caller Drop this argument now that we always want to rewind only to the state of the first caller. It means frame pointers are not necessary anymore to reliably get the source of an event. But this also means we need this helper to be a macro now, as an inline function is not an option since we need to know when to provide a default implentation. Signed-off-by: Frederic Weisbecker Signed-off-by: Paul Mackerras Cc: David Miller Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo --- arch/sparc/include/asm/perf_event.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/perf_event.h b/arch/sparc/include/asm/perf_event.h index 7e2669894ce8..74c4e0cd889c 100644 --- a/arch/sparc/include/asm/perf_event.h +++ b/arch/sparc/include/asm/perf_event.h @@ -6,7 +6,15 @@ extern void set_perf_event_pending(void); #define PERF_EVENT_INDEX_OFFSET 0 #ifdef CONFIG_PERF_EVENTS +#include + extern void init_hw_perf_events(void); + +extern void +__perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip); + +#define perf_arch_fetch_caller_regs(pt_regs, ip) \ + __perf_arch_fetch_caller_regs(pt_regs, ip, 1); #else static inline void init_hw_perf_events(void) { } #endif -- cgit v1.2.3 From 1996bda2a42480c275656233e631ee0966574be4 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 21 May 2010 14:05:13 +0200 Subject: arch: Implement local64_t On 64bit, local_t is of size long, and thus we make local64_t an alias. On 32bit, we fall back to atomic64_t. (architecture can provide optimized 32-bit version) (This new facility is to be used by perf events optimizations.) Signed-off-by: Peter Zijlstra Cc: linux-arch@vger.kernel.org Cc: Andrew Morton Cc: Linus Torvalds LKML-Reference: Signed-off-by: Ingo Molnar --- arch/sparc/include/asm/local64.h | 1 + 1 file changed, 1 insertion(+) create mode 100644 arch/sparc/include/asm/local64.h (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/local64.h b/arch/sparc/include/asm/local64.h new file mode 100644 index 000000000000..36c93b5cc239 --- /dev/null +++ b/arch/sparc/include/asm/local64.h @@ -0,0 +1 @@ +#include -- cgit v1.2.3 From 1636f8ac2b08410df4766449f7c86b912443cd99 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 18 Jun 2010 11:09:58 -0600 Subject: sparc/of: Move of_device fields into struct pdev_archdata This patch moves SPARC architecture specific data members out of struct of_device and into the pdev_archdata structure. The reason for this change is to unify the struct of_device definition amongst all the architectures. It also remvoes the .sysdata, .slot, .portid and .clock_freq properties because they aren't actually used by anything. A subsequent patch will replace struct of_device entirely with struct platform_device and the of_platform support code will share common routines with the platform bus (but the bus instances themselves can remain separate). This patch also adds 'struct resources *resource' and num_resources to match the fields defined in struct platform_device. After this change, 'struct platform_device' can be used as a drop-in replacement for 'struct of_platform'. This change is in preparation for merging the of_platform_bus_type with the platform_bus_type. Signed-off-by: Grant Likely Acked-by: David S. Miller Cc: Stephen Rothwell --- arch/sparc/include/asm/device.h | 5 +++++ arch/sparc/include/asm/floppy_64.h | 4 ++-- arch/sparc/include/asm/of_device.h | 11 +++-------- arch/sparc/include/asm/parport.h | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/device.h b/arch/sparc/include/asm/device.h index d4c452147412..f9740d065fe7 100644 --- a/arch/sparc/include/asm/device.h +++ b/arch/sparc/include/asm/device.h @@ -6,6 +6,8 @@ #ifndef _ASM_SPARC_DEVICE_H #define _ASM_SPARC_DEVICE_H +#include + struct device_node; struct of_device; @@ -18,6 +20,9 @@ struct dev_archdata { }; struct pdev_archdata { + struct resource resource[PROMREG_MAX]; + unsigned int irqs[PROMINTR_MAX]; + int num_irqs; }; #endif /* _ASM_SPARC_DEVICE_H */ diff --git a/arch/sparc/include/asm/floppy_64.h b/arch/sparc/include/asm/floppy_64.h index 8fac3ab22f36..4f5bde638f72 100644 --- a/arch/sparc/include/asm/floppy_64.h +++ b/arch/sparc/include/asm/floppy_64.h @@ -567,7 +567,7 @@ static unsigned long __init sun_floppy_init(void) } if (op) { floppy_op = op; - FLOPPY_IRQ = op->irqs[0]; + FLOPPY_IRQ = op->archdata.irqs[0]; } else { struct device_node *ebus_dp; void __iomem *auxio_reg; @@ -593,7 +593,7 @@ static unsigned long __init sun_floppy_init(void) if (state_prop && !strncmp(state_prop, "disabled", 8)) return 0; - FLOPPY_IRQ = op->irqs[0]; + FLOPPY_IRQ = op->archdata.irqs[0]; /* Make sure the high density bit is set, some systems * (most notably Ultra5/Ultra10) come up with it clear. diff --git a/arch/sparc/include/asm/of_device.h b/arch/sparc/include/asm/of_device.h index f320246a0586..6d1844a547b4 100644 --- a/arch/sparc/include/asm/of_device.h +++ b/arch/sparc/include/asm/of_device.h @@ -15,15 +15,10 @@ struct of_device { struct device dev; - struct resource resource[PROMREG_MAX]; - unsigned int irqs[PROMINTR_MAX]; - int num_irqs; + u32 num_resources; + struct resource *resource; - void *sysdata; - - int slot; - int portid; - int clock_freq; + struct pdev_archdata archdata; }; extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name); diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h index c333b8d0949b..0c34a8792fc7 100644 --- a/arch/sparc/include/asm/parport.h +++ b/arch/sparc/include/asm/parport.h @@ -116,7 +116,7 @@ static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id parent = op->dev.of_node->parent; if (!strcmp(parent->name, "dma")) { p = parport_pc_probe_port(base, base + 0x400, - op->irqs[0], PARPORT_DMA_NOFIFO, + op->archdata.irqs[0], PARPORT_DMA_NOFIFO, op->dev.parent->parent, 0); if (!p) return -ENOMEM; @@ -166,7 +166,7 @@ static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id 0, PTR_LPT_REG_DIR); p = parport_pc_probe_port(base, base + 0x400, - op->irqs[0], + op->archdata.irqs[0], slot, op->dev.parent, 0); -- cgit v1.2.3 From b505ff5e7291cca6379549297e3852ce3622d550 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 18 Jun 2010 11:09:59 -0600 Subject: of: kill struct of_device Now that the device tree node pointer has been moved out of struct of_device and into the common struct device, there isn't anything unique about of_device anymore. In fact, there isn't much need for a separate of_bus when all busses have access to OF style probing. arch/powerpc and arch/microblaze are moving away from using the of_bus and using the regular platform bus instead for mmio devices. This patch makes of_device the same as platform_device as a stepping stone in migrating of_platform_drivers over to the platform bus. Signed-off-by: Grant Likely Acked-by: David S. Miller Cc: Michal Simek Cc: Benjamin Herrenschmidt Cc: Stephen Rothwell --- arch/sparc/include/asm/device.h | 4 ++-- arch/sparc/include/asm/of_device.h | 14 -------------- 2 files changed, 2 insertions(+), 16 deletions(-) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/device.h b/arch/sparc/include/asm/device.h index f9740d065fe7..fb220e482039 100644 --- a/arch/sparc/include/asm/device.h +++ b/arch/sparc/include/asm/device.h @@ -9,13 +9,13 @@ #include struct device_node; -struct of_device; +struct platform_device; struct dev_archdata { void *iommu; void *stc; void *host_controller; - struct of_device *op; + struct platform_device *op; int numa_node; }; diff --git a/arch/sparc/include/asm/of_device.h b/arch/sparc/include/asm/of_device.h index 6d1844a547b4..22b9828fe693 100644 --- a/arch/sparc/include/asm/of_device.h +++ b/arch/sparc/include/asm/of_device.h @@ -7,20 +7,6 @@ #include #include -/* - * The of_device is a kind of "base class" that is a superset of - * struct device for use by devices attached to an OF node and - * probed using OF properties. - */ -struct of_device -{ - struct device dev; - u32 num_resources; - struct resource *resource; - - struct pdev_archdata archdata; -}; - extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name); extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size); -- cgit v1.2.3 From e3873444990dd6f8a095d1f72b5ad45192f8c506 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 18 Jun 2010 11:09:59 -0600 Subject: of/irq: Move irq_of_parse_and_map() to common code Merge common code between PowerPC and Microblaze. SPARC implements irq_of_parse_and_map(), but the implementation is different, so it does not use this code. Signed-off-by: Grant Likely Acked-by: Benjamin Herrenschmidt Cc: Michal Simek Cc: "David S. Miller" Cc: Stephen Rothwell Cc: Jeremy Kerr --- arch/sparc/include/asm/prom.h | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index f845828ca4c6..ac695742df85 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h @@ -56,7 +56,6 @@ extern void of_fill_in_cpu_data(void); * register them in the of_device objects, whereas powerpc computes them * on request. */ -extern unsigned int irq_of_parse_and_map(struct device_node *node, int index); static inline void irq_dispose_mapping(unsigned int virq) { } -- cgit v1.2.3 From 1ab1d63a85cee2545272f63a7644e9f855cb65d0 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 24 Jun 2010 15:14:37 -0600 Subject: of/platform: remove all of_bus_type and of_platform_bus_type references Both of_bus_type and of_platform_bus_type are just #define aliases for the platform bus. This patch removes all references to them and switches to the of_register_platform_driver()/of_unregister_platform_driver() API for registering. Subsequent patches will convert each user of of_register_platform_driver() into plain platform_drivers without the of_platform_driver shim. At which point the of_register_platform_driver()/of_unregister_platform_driver() functions can be removed. Signed-off-by: Grant Likely Acked-by: David S. Miller --- arch/sparc/include/asm/of_platform.h | 2 -- arch/sparc/include/asm/parport.h | 4 +--- 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/of_platform.h b/arch/sparc/include/asm/of_platform.h index 90da99059f83..26540ddfc511 100644 --- a/arch/sparc/include/asm/of_platform.h +++ b/arch/sparc/include/asm/of_platform.h @@ -13,6 +13,4 @@ * */ -#define of_bus_type of_platform_bus_type /* for compatibility */ - #endif diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h index 0c34a8792fc7..4891fbce1114 100644 --- a/arch/sparc/include/asm/parport.h +++ b/arch/sparc/include/asm/parport.h @@ -243,9 +243,7 @@ static struct of_platform_driver ecpp_driver = { static int parport_pc_find_nonpci_ports(int autoirq, int autodma) { - of_register_driver(&ecpp_driver, &of_bus_type); - - return 0; + return of_register_platform_driver(&ecpp_driver); } #endif /* !(_ASM_SPARC64_PARPORT_H */ -- cgit v1.2.3 From 129ac799ad627b1e08382739f9e8cd75d7477fa3 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 29 Jun 2010 09:26:53 -0700 Subject: of: remove asm/of_platform.h Only thing left in it is of_instantiate_rtc() which can be moved to asm/prom.h on PowerPC and is unused in microblaze. Signed-off-by: Grant Likely Acked-by: David S. Miller --- arch/sparc/include/asm/of_platform.h | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 arch/sparc/include/asm/of_platform.h (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/of_platform.h b/arch/sparc/include/asm/of_platform.h deleted file mode 100644 index 26540ddfc511..000000000000 --- a/arch/sparc/include/asm/of_platform.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef ___ASM_SPARC_OF_PLATFORM_H -#define ___ASM_SPARC_OF_PLATFORM_H -/* - * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. - * - * Modified for Sparc by merging parts of asm/of_device.h - * by Stephen Rothwell - * - * 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. - * - */ - -#endif -- cgit v1.2.3 From 295960429675e17ec658320ebb24385727032bed Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 29 Jun 2010 11:15:54 -0600 Subject: of: remove asm/of_device.h It is mostly unused now. Sparc has a few defines left in it, but they can be moved to other headers. Removing this header means that new architectures adding CONFIG_OF support don't need to also add this header file. Signed-off-by: Grant Likely Acked-by: David S. Miller --- arch/sparc/include/asm/device.h | 2 ++ arch/sparc/include/asm/of_device.h | 19 ------------------- arch/sparc/include/asm/prom.h | 4 ++++ 3 files changed, 6 insertions(+), 19 deletions(-) delete mode 100644 arch/sparc/include/asm/of_device.h (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/device.h b/arch/sparc/include/asm/device.h index fb220e482039..daa6a8a5e9cd 100644 --- a/arch/sparc/include/asm/device.h +++ b/arch/sparc/include/asm/device.h @@ -19,6 +19,8 @@ struct dev_archdata { int numa_node; }; +extern void of_propagate_archdata(struct platform_device *bus); + struct pdev_archdata { struct resource resource[PROMREG_MAX]; unsigned int irqs[PROMINTR_MAX]; diff --git a/arch/sparc/include/asm/of_device.h b/arch/sparc/include/asm/of_device.h deleted file mode 100644 index 22b9828fe693..000000000000 --- a/arch/sparc/include/asm/of_device.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _ASM_SPARC_OF_DEVICE_H -#define _ASM_SPARC_OF_DEVICE_H -#ifdef __KERNEL__ - -#include -#include -#include -#include - -extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name); -extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size); - -extern void of_propagate_archdata(struct of_device *bus); - -/* This is just here during the transition */ -#include - -#endif /* __KERNEL__ */ -#endif /* _ASM_SPARC_OF_DEVICE_H */ diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index ac695742df85..d35df5ace18a 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h @@ -51,6 +51,10 @@ extern void prom_build_devicetree(void); extern void of_populate_present_mask(void); extern void of_fill_in_cpu_data(void); +struct resource; +extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name); +extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size); + /* These routines are here to provide compatibility with how powerpc * handles IRQ mapping for OF device nodes. We precompute and permanently * register them in the of_device objects, whereas powerpc computes them -- cgit v1.2.3 From 94a0cb1fc61ab7a0d47d268a7764374efeb2160b Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 22 Jul 2010 13:59:23 -0600 Subject: of/device: Replace of_device with platform_device in includes and core code of_device is currently just an #define alias to platform_device until it gets removed entirely. This patch removes references to it from the include directories and the core drivers/of code. Signed-off-by: Grant Likely Acked-by: David S. Miller --- arch/sparc/include/asm/floppy_64.h | 6 +++--- arch/sparc/include/asm/parport.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/floppy_64.h b/arch/sparc/include/asm/floppy_64.h index 4f5bde638f72..6597ce874d78 100644 --- a/arch/sparc/include/asm/floppy_64.h +++ b/arch/sparc/include/asm/floppy_64.h @@ -43,7 +43,7 @@ struct sun_flpy_controller { /* You'll only ever find one controller on an Ultra anyways. */ static struct sun_flpy_controller *sun_fdc = (struct sun_flpy_controller *)-1; unsigned long fdc_status; -static struct of_device *floppy_op = NULL; +static struct platform_device *floppy_op = NULL; struct sun_floppy_ops { unsigned char (*fd_inb) (unsigned long port); @@ -548,7 +548,7 @@ static unsigned long __init sun_floppy_init(void) { static int initialized = 0; struct device_node *dp; - struct of_device *op; + struct platform_device *op; const char *prop; char state[128]; @@ -661,7 +661,7 @@ static unsigned long __init sun_floppy_init(void) config = 0; for (dp = ebus_dp->child; dp; dp = dp->sibling) { if (!strcmp(dp->name, "ecpp")) { - struct of_device *ecpp_op; + struct platform_device *ecpp_op; ecpp_op = of_find_device_by_node(dp); if (ecpp_op) diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h index 4891fbce1114..4f7afa01b2ae 100644 --- a/arch/sparc/include/asm/parport.h +++ b/arch/sparc/include/asm/parport.h @@ -103,7 +103,7 @@ static inline unsigned int get_dma_residue(unsigned int dmanr) return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info); } -static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id *match) +static int __devinit ecpp_probe(struct platform_device *op, const struct of_device_id *match) { unsigned long base = op->resource[0].start; unsigned long config = op->resource[1].start; @@ -192,7 +192,7 @@ out_err: return err; } -static int __devexit ecpp_remove(struct of_device *op) +static int __devexit ecpp_remove(struct platform_device *op) { struct parport *p = dev_get_drvdata(&op->dev); int slot = p->dma; -- cgit v1.2.3 From cd4cd7306a403f62ef3ca783b9d1cf2a03e595ed Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 22 Jul 2010 16:04:30 -0600 Subject: sparc: remove references to of_device and to_of_device of_device is just a #define alias to platform_device. This patch replaces all references to it with platform_device. Signed-off-by: Grant Likely Acked-by: David S. Miller --- arch/sparc/include/asm/prom.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index d35df5ace18a..c82a7da25f9f 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h @@ -57,7 +57,7 @@ extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long s /* These routines are here to provide compatibility with how powerpc * handles IRQ mapping for OF device nodes. We precompute and permanently - * register them in the of_device objects, whereas powerpc computes them + * register them in the platform_device objects, whereas powerpc computes them * on request. */ static inline void irq_dispose_mapping(unsigned int virq) -- cgit v1.2.3 From 559e2b7ee7a1c7753d534abcb2742a4775339293 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 23 Jul 2010 20:11:18 -0600 Subject: of: Provide default of_node_to_nid() implementation. of_node_to_nid() is only relevant in a few architectures. Don't force everyone to implement it anyway. Signed-off-by: Grant Likely --- arch/sparc/include/asm/prom.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index c82a7da25f9f..291f12575edd 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h @@ -43,8 +43,7 @@ extern int of_getintprop_default(struct device_node *np, extern int of_find_in_proplist(const char *list, const char *match, int len); #ifdef CONFIG_NUMA extern int of_node_to_nid(struct device_node *dp); -#else -#define of_node_to_nid(dp) (-1) +#define of_node_to_nid of_node_to_nid #endif extern void prom_build_devicetree(void); -- cgit v1.2.3 From 7e005f79791dcd58436c88ded4a7f5aed1b82147 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Mon, 31 May 2010 15:59:04 +0900 Subject: remove needless ISA_DMA_THRESHOLD Architectures don't need to define ISA_DMA_THRESHOLD anymore. Signed-off-by: FUJITA Tomonori Acked-by: James Bottomley Acked-by: David Howells Signed-off-by: Jens Axboe --- arch/sparc/include/asm/scatterlist.h | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/scatterlist.h b/arch/sparc/include/asm/scatterlist.h index 433e45f05fd4..92bb638313f8 100644 --- a/arch/sparc/include/asm/scatterlist.h +++ b/arch/sparc/include/asm/scatterlist.h @@ -3,7 +3,6 @@ #include -#define ISA_DMA_THRESHOLD (~0UL) #define ARCH_HAS_SG_CHAIN #endif /* !(_SPARC_SCATTERLIST_H) */ -- cgit v1.2.3 From c8837434e8bfd08abf3b596dbaeffe4a8b59a284 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 4 Aug 2010 17:30:21 -0700 Subject: sparc64: Add missing ID to parport probing code. SunBlade-2500 has 'parallel' device node with compatible property "pnpALI,1533,3" so add that to the ID table. Reported-by: Mikael Pettersson Tested-by: Mikael Pettersson Signed-off-by: David S. Miller --- arch/sparc/include/asm/parport.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h index 4f7afa01b2ae..aa4c82648d88 100644 --- a/arch/sparc/include/asm/parport.h +++ b/arch/sparc/include/asm/parport.h @@ -228,6 +228,10 @@ static const struct of_device_id ecpp_match[] = { .name = "parallel", .compatible = "ns87317-ecpp", }, + { + .name = "parallel", + .compatible = "pnpALI,1533,3", + }, {}, }; -- cgit v1.2.3 From b11287e8c5b2797b86351f6db0fcd9ff99b20bab Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 8 Aug 2010 22:03:59 -0700 Subject: sparc64: Fix perf_arch_get_caller_regs(). After b0f82b81fe6bbcf78d478071f33e44554726bc81 ("perf: Drop the skip argument from perf_arch_fetch_regs_caller") the build broke on sparc64 due to the lack of a module symbol export of __perf_arch_fetch_caller_regs. But that assembler helper can actually be complete eliminated now that the semantics of this interface have been greatly simplified. Signed-off-by: David S. Miller --- arch/sparc/include/asm/perf_event.h | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/perf_event.h b/arch/sparc/include/asm/perf_event.h index 74c4e0cd889c..727af70646cb 100644 --- a/arch/sparc/include/asm/perf_event.h +++ b/arch/sparc/include/asm/perf_event.h @@ -10,11 +10,26 @@ extern void set_perf_event_pending(void); extern void init_hw_perf_events(void); -extern void -__perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip); - -#define perf_arch_fetch_caller_regs(pt_regs, ip) \ - __perf_arch_fetch_caller_regs(pt_regs, ip, 1); +#define perf_arch_fetch_caller_regs(regs, ip) \ +do { \ + unsigned long _pstate, _asi, _pil, _i7, _fp; \ + __asm__ __volatile__("rdpr %%pstate, %0\n\t" \ + "rd %%asi, %1\n\t" \ + "rdpr %%pil, %2\n\t" \ + "mov %%i7, %3\n\t" \ + "mov %%i6, %4\n\t" \ + : "=r" (_pstate), \ + "=r" (_asi), \ + "=r" (_pil), \ + "=r" (_i7), \ + "=r" (_fp)); \ + (regs)->tstate = (_pstate << 8) | \ + (_asi << 24) | (_pil << 20); \ + (regs)->tpc = (ip); \ + (regs)->tnpc = (regs)->tpc + 4; \ + (regs)->u_regs[UREG_I6] = _fp; \ + (regs)->u_regs[UREG_I7] = _i7; \ +} while (0) #else static inline void init_hw_perf_events(void) { } #endif -- cgit v1.2.3 From 4cb6066af9ee58ddba58a63cc77b324ac21add75 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 9 Aug 2010 00:45:46 -0700 Subject: sparc: Kill user copy check code. For whatever reason GCC isn't able to figure things out in the control flow (in particular when min() and max() expressions are involved) on sparc as well as it can on x86. So lots of useless incorrect user copy warnings get spewed and the full-on compile failure mode of the user copy checks were never usable on sparc at all. People can debug these kinds of problems on x86. Signed-off-by: David S. Miller --- arch/sparc/include/asm/uaccess_32.h | 15 --------------- arch/sparc/include/asm/uaccess_64.h | 23 +++++------------------ 2 files changed, 5 insertions(+), 33 deletions(-) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h index 25f1d10155e8..8303ac481034 100644 --- a/arch/sparc/include/asm/uaccess_32.h +++ b/arch/sparc/include/asm/uaccess_32.h @@ -260,23 +260,8 @@ static inline unsigned long __copy_to_user(void __user *to, const void *from, un return __copy_user(to, (__force void __user *) from, n); } -extern void copy_from_user_overflow(void) -#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS - __compiletime_error("copy_from_user() buffer size is not provably correct") -#else - __compiletime_warning("copy_from_user() buffer size is not provably correct") -#endif -; - static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) { - int sz = __compiletime_object_size(to); - - if (unlikely(sz != -1 && sz < n)) { - copy_from_user_overflow(); - return n; - } - if (n && __access_ok((unsigned long) from, n)) return __copy_user((__force void __user *) to, from, n); else diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h index 2406788bfe5f..3e1449f07798 100644 --- a/arch/sparc/include/asm/uaccess_64.h +++ b/arch/sparc/include/asm/uaccess_64.h @@ -205,14 +205,6 @@ __asm__ __volatile__( \ extern int __get_user_bad(void); -extern void copy_from_user_overflow(void) -#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS - __compiletime_error("copy_from_user() buffer size is not provably correct") -#else - __compiletime_warning("copy_from_user() buffer size is not provably correct") -#endif -; - extern unsigned long __must_check ___copy_from_user(void *to, const void __user *from, unsigned long size); @@ -221,16 +213,11 @@ extern unsigned long copy_from_user_fixup(void *to, const void __user *from, static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long size) { - int sz = __compiletime_object_size(to); - unsigned long ret = size; - - if (likely(sz == -1 || sz >= size)) { - ret = ___copy_from_user(to, from, size); - if (unlikely(ret)) - ret = copy_from_user_fixup(to, from, size); - } else { - copy_from_user_overflow(); - } + unsigned long ret = ___copy_from_user(to, from, size); + + if (unlikely(ret)) + ret = copy_from_user_fixup(to, from, size); + return ret; } #define __copy_from_user copy_from_user -- cgit v1.2.3 From 597781f3e51f48ef8e67be772196d9e9673752c4 Mon Sep 17 00:00:00 2001 From: Cesar Eduardo Barros Date: Mon, 9 Aug 2010 17:18:32 -0700 Subject: kmap_atomic: make kunmap_atomic() harder to misuse kunmap_atomic() is currently at level -4 on Rusty's "Hard To Misuse" list[1] ("Follow common convention and you'll get it wrong"), except in some architectures when CONFIG_DEBUG_HIGHMEM is set[2][3]. kunmap() takes a pointer to a struct page; kunmap_atomic(), however, takes takes a pointer to within the page itself. This seems to once in a while trip people up (the convention they are following is the one from kunmap()). Make it much harder to misuse, by moving it to level 9 on Rusty's list[4] ("The compiler/linker won't let you get it wrong"). This is done by refusing to build if the type of its first argument is a pointer to a struct page. The real kunmap_atomic() is renamed to kunmap_atomic_notypecheck() (which is what you would call in case for some strange reason calling it with a pointer to a struct page is not incorrect in your code). The previous version of this patch was compile tested on x86-64. [1] http://ozlabs.org/~rusty/index.cgi/tech/2008-04-01.html [2] In these cases, it is at level 5, "Do it right or it will always break at runtime." [3] At least mips and powerpc look very similar, and sparc also seems to share a common ancestor with both; there seems to be quite some degree of copy-and-paste coding here. The include/asm/highmem.h file for these three archs mention x86 CPUs at its top. [4] http://ozlabs.org/~rusty/index.cgi/tech/2008-03-30.html [5] As an aside, could someone tell me why mn10300 uses unsigned long as the first parameter of kunmap_atomic() instead of void *? Signed-off-by: Cesar Eduardo Barros Cc: Russell King (arch/arm) Cc: Ralf Baechle (arch/mips) Cc: David Howells (arch/frv, arch/mn10300) Cc: Koichi Yasutake (arch/mn10300) Cc: Kyle McMartin (arch/parisc) Cc: Helge Deller (arch/parisc) Cc: "James E.J. Bottomley" (arch/parisc) Cc: Benjamin Herrenschmidt (arch/powerpc) Cc: Paul Mackerras (arch/powerpc) Cc: "David S. Miller" (arch/sparc) Cc: Thomas Gleixner (arch/x86) Cc: Ingo Molnar (arch/x86) Cc: "H. Peter Anvin" (arch/x86) Cc: Arnd Bergmann (include/asm-generic) Cc: Rusty Russell ("Hard To Misuse" list) Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sparc/include/asm/highmem.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/highmem.h b/arch/sparc/include/asm/highmem.h index 3de42e776274..ec23b0a87b98 100644 --- a/arch/sparc/include/asm/highmem.h +++ b/arch/sparc/include/asm/highmem.h @@ -71,7 +71,7 @@ static inline void kunmap(struct page *page) } extern void *kmap_atomic(struct page *page, enum km_type type); -extern void kunmap_atomic(void *kvaddr, enum km_type type); +extern void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type); extern struct page *kmap_atomic_to_page(void *vaddr); #define flush_cache_kmaps() flush_cache_all() -- cgit v1.2.3 From 26df6d13406d1a53b0bda08bd712f1924affd7cd Mon Sep 17 00:00:00 2001 From: "hyc@symas.com" Date: Tue, 22 Jun 2010 10:14:49 -0700 Subject: tty: Add EXTPROC support for LINEMODE This patch is against the 2.6.34 source. Paraphrased from the 1989 BSD patch by David Borman @ cray.com: These are the changes needed for the kernel to support LINEMODE in the server. There is a new bit in the termios local flag word, EXTPROC. When this bit is set, several aspects of the terminal driver are disabled. Input line editing, character echo, and mapping of signals are all disabled. This allows the telnetd to turn off these functions when in linemode, but still keep track of what state the user wants the terminal to be in. New ioctl: TIOCSIG Generate a signal to processes in the current process group of the pty. There is a new mode for packet driver, the TIOCPKT_IOCTL bit. When packet mode is turned on in the pty, and the EXTPROC bit is set, then whenever the state of the pty is changed, the next read on the master side of the pty will have the TIOCPKT_IOCTL bit set. This allows the process on the server side of the pty to know when the state of the terminal has changed; it can then issue the appropriate ioctl to retrieve the new state. Since the original BSD patches accompanied the source code for telnet I've left that reference here, but obviously the feature is useful for any remote terminal protocol, including ssh. The corresponding feature has existed in the BSD tty driver since 1989. For historical reference, a good copy of the relevant files can be found here: http://anonsvn.mit.edu/viewvc/krb5/trunk/src/appl/telnet/?pathrev=17741 Signed-off-by: Howard Chu Cc: Alan Cox Signed-off-by: Greg Kroah-Hartman --- arch/sparc/include/asm/ioctls.h | 2 ++ arch/sparc/include/asm/termbits.h | 1 + 2 files changed, 3 insertions(+) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/ioctls.h b/arch/sparc/include/asm/ioctls.h index 1fe6855c5c18..53f4ee009bdd 100644 --- a/arch/sparc/include/asm/ioctls.h +++ b/arch/sparc/include/asm/ioctls.h @@ -80,6 +80,7 @@ /* Get minor device of a pty master's FD -- Solaris equiv is ISPTM */ #define TIOCGPTN _IOR('t', 134, unsigned int) /* Get Pty Number */ #define TIOCSPTLCK _IOW('t', 135, int) /* Lock/unlock PTY */ +#define TIOCSIG _IOW('t', 136, int) /* Generate signal on Pty slave */ /* Little f */ #define FIOCLEX _IO('f', 1) @@ -132,5 +133,6 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 +#define TIOCPKT_IOCTL 64 #endif /* !(_ASM_SPARC_IOCTLS_H) */ diff --git a/arch/sparc/include/asm/termbits.h b/arch/sparc/include/asm/termbits.h index d72dfed1f9d7..23b10ff08df2 100644 --- a/arch/sparc/include/asm/termbits.h +++ b/arch/sparc/include/asm/termbits.h @@ -225,6 +225,7 @@ struct ktermios { #define FLUSHO 0x00002000 #define PENDIN 0x00004000 #define IEXTEN 0x00008000 +#define EXTPROC 0x00010000 /* modem lines */ #define TIOCM_LE 0x001 -- cgit v1.2.3 From 4565f0170dfc849b3629c27d769db800467baa62 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 10 Aug 2010 18:03:22 -0700 Subject: dma-mapping: unify dma_get_cache_alignment implementations dma_get_cache_alignment returns the minimum DMA alignment. Architectures defines it as ARCH_DMA_MINALIGN (formally ARCH_KMALLOC_MINALIGN). So we can unify dma_get_cache_alignment implementations. Note that some architectures implement dma_get_cache_alignment wrongly. dma_get_cache_alignment() should return the minimum DMA alignment. So fully-coherent architectures should return 1. This patch also fixes this issue. Signed-off-by: FUJITA Tomonori Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sparc/include/asm/dma-mapping.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h index 4b4a0c0b0ccd..74db853ec2cf 100644 --- a/arch/sparc/include/asm/dma-mapping.h +++ b/arch/sparc/include/asm/dma-mapping.h @@ -52,15 +52,6 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) return (dma_addr == DMA_ERROR_CODE); } -static inline int dma_get_cache_alignment(void) -{ - /* - * no easy way to get cache size on all processors, so return - * the maximum possible, to be safe - */ - return (1 << INTERNODE_CACHE_SHIFT); -} - static inline int dma_set_mask(struct device *dev, u64 mask) { #ifdef CONFIG_PCI -- cgit v1.2.3 From 3b9c6c11f519718d618f5d7c9508daf78b207f6f Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 10 Aug 2010 18:03:25 -0700 Subject: dma-mapping: remove dma_is_consistent API Architectures implement dma_is_consistent() in different ways (some misinterpret the definition of API in DMA-API.txt). So it hasn't been so useful for drivers. We have only one user of the API in tree. Unlikely out-of-tree drivers use the API. Even if we fix dma_is_consistent() in some architectures, it doesn't look useful at all. It was invented long ago for some old systems that can't allocate coherent memory at all. It's better to export only APIs that are definitely necessary for drivers. Let's remove this API. Signed-off-by: FUJITA Tomonori Cc: James Bottomley Reviewed-by: Konrad Rzeszutek Wilk Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sparc/include/asm/dma-mapping.h | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h index 74db853ec2cf..8c0e4f7bb204 100644 --- a/arch/sparc/include/asm/dma-mapping.h +++ b/arch/sparc/include/asm/dma-mapping.h @@ -11,7 +11,6 @@ extern int dma_supported(struct device *dev, u64 mask); #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -#define dma_is_consistent(d, h) (1) extern struct dma_map_ops *dma_ops, pci32_dma_ops; extern struct bus_type pci_bus_type; -- cgit v1.2.3 From 0a492896ac07336c98f37ad7fab4a6387b6ada78 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 15 Aug 2010 00:26:14 -0700 Subject: sparc: Really fix "console=" for serial consoles. If a video head and keyboard are hooked up, specifying "console=ttyS0" or similar to use a serial console will not work properly. The key issue is that we must register all serial console capable devices with register_console(), otherwise the command line specified device won't be found. The sun serial drivers would only register themselves as console devices if the OpenFirmware specified console device node matched. To fix this part we now unconditionally get the serial console register by setting serial_drv->cons always. Secondarily we must not add_preferred_console() using the firmware provided console setting if the user gaven an override on the kernel command line using "console=" The "primary framebuffer" matching logic was always triggering o n openfirmware device node match, make it not when a command line override was given. Reported-by: Frans Pop Tested-by: Frans Pop Signed-off-by: David S. Miller --- arch/sparc/include/asm/fb.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/fb.h b/arch/sparc/include/asm/fb.h index e834880be204..2173432ad7f7 100644 --- a/arch/sparc/include/asm/fb.h +++ b/arch/sparc/include/asm/fb.h @@ -1,5 +1,6 @@ #ifndef _SPARC_FB_H_ #define _SPARC_FB_H_ +#include #include #include #include @@ -18,6 +19,9 @@ static inline int fb_is_primary_device(struct fb_info *info) struct device *dev = info->device; struct device_node *node; + if (console_set_on_cmdline) + return 0; + node = dev->of_node; if (node && node == of_console_device) -- cgit v1.2.3 From 8e8073a449b2e00641c095ad55bd56f43468daf9 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 16 Aug 2010 15:04:29 -0700 Subject: sparc: Hook up new fanotify and prlimit64 syscalls. The only tricky bit is the compat version of fanotify_mark, which which on 32-bit the 64-bit mark argument is passed in as "high32", "low32". Signed-off-by: David S. Miller --- arch/sparc/include/asm/unistd.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h index d0b3b01ac9d4..03eb5a8f6f93 100644 --- a/arch/sparc/include/asm/unistd.h +++ b/arch/sparc/include/asm/unistd.h @@ -397,8 +397,11 @@ #define __NR_rt_tgsigqueueinfo 326 #define __NR_perf_event_open 327 #define __NR_recvmmsg 328 +#define __NR_fanotify_init 329 +#define __NR_fanotify_mark 330 +#define __NR_prlimit64 331 -#define NR_syscalls 329 +#define NR_syscalls 332 #ifdef __32bit_syscall_numbers__ /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, -- cgit v1.2.3 From ef201bebe5afc91a2b99b45dacc8c6dd88ca9e58 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 17 Aug 2010 17:09:53 -0700 Subject: sparc64: Fix rwsem constant bug leading to hangs. As noticed by Linus, it is critical that some of the rwsem constants be signed. Yet, hex constants are unsigned unless explicitly casted or negated. The most critical one is RWSEM_WAITING_BIAS. This bug was exacerbated by commit 424acaaeb3a3932d64a9b4bd59df6cf72c22d8f3 ("rwsem: wake queued readers when writer blocks on active read lock") Signed-off-by: David S. Miller --- arch/sparc/include/asm/rwsem-const.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/rwsem-const.h b/arch/sparc/include/asm/rwsem-const.h index a303c9d64d84..e4c61a18bb28 100644 --- a/arch/sparc/include/asm/rwsem-const.h +++ b/arch/sparc/include/asm/rwsem-const.h @@ -5,7 +5,7 @@ #define RWSEM_UNLOCKED_VALUE 0x00000000 #define RWSEM_ACTIVE_BIAS 0x00000001 #define RWSEM_ACTIVE_MASK 0x0000ffff -#define RWSEM_WAITING_BIAS 0xffff0000 +#define RWSEM_WAITING_BIAS (-0x00010000) #define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) -- cgit v1.2.3 From 86fa04b8742ac681d470786f55e2403ada0075b2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 17 Aug 2010 17:12:04 -0700 Subject: sparc64: Fix atomic64_t routine return values. Should return 'long' instead of 'int'. Thanks to Dimitris Michailidis and Tony Luck. Signed-off-by: David S. Miller --- arch/sparc/include/asm/atomic_64.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h index 2050ca02c423..f0c74227c737 100644 --- a/arch/sparc/include/asm/atomic_64.h +++ b/arch/sparc/include/asm/atomic_64.h @@ -25,9 +25,9 @@ extern void atomic_sub(int, atomic_t *); extern void atomic64_sub(int, atomic64_t *); extern int atomic_add_ret(int, atomic_t *); -extern int atomic64_add_ret(int, atomic64_t *); +extern long atomic64_add_ret(int, atomic64_t *); extern int atomic_sub_ret(int, atomic_t *); -extern int atomic64_sub_ret(int, atomic64_t *); +extern long atomic64_sub_ret(int, atomic64_t *); #define atomic_dec_return(v) atomic_sub_ret(1, v) #define atomic64_dec_return(v) atomic64_sub_ret(1, v) @@ -91,7 +91,7 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n))) #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) -static inline int atomic64_add_unless(atomic64_t *v, long a, long u) +static inline long atomic64_add_unless(atomic64_t *v, long a, long u) { long c, old; c = atomic64_read(v); -- cgit v1.2.3 From b10f997bb0f4e5b34d447f498fb85834a40d3acb Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 17 Aug 2010 21:44:13 -0700 Subject: sparc64: Really fix atomic64_t interface types. Linus noticed that some of the interface arguments didn't get "int" --> "long" conversion, as needed. Signed-off-by: David S. Miller --- arch/sparc/include/asm/atomic_64.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h index f0c74227c737..bdb2ff880bdd 100644 --- a/arch/sparc/include/asm/atomic_64.h +++ b/arch/sparc/include/asm/atomic_64.h @@ -20,14 +20,14 @@ #define atomic64_set(v, i) (((v)->counter) = i) extern void atomic_add(int, atomic_t *); -extern void atomic64_add(int, atomic64_t *); +extern void atomic64_add(long, atomic64_t *); extern void atomic_sub(int, atomic_t *); -extern void atomic64_sub(int, atomic64_t *); +extern void atomic64_sub(long, atomic64_t *); extern int atomic_add_ret(int, atomic_t *); -extern long atomic64_add_ret(int, atomic64_t *); +extern long atomic64_add_ret(long, atomic64_t *); extern int atomic_sub_ret(int, atomic_t *); -extern long atomic64_sub_ret(int, atomic64_t *); +extern long atomic64_sub_ret(long, atomic64_t *); #define atomic_dec_return(v) atomic_sub_ret(1, v) #define atomic64_dec_return(v) atomic64_sub_ret(1, v) -- cgit v1.2.3 From 9b3bb86acabe0c05923cea1ed3b0bee9439fef4b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 17 Aug 2010 22:49:26 -0700 Subject: sparc64: Make rwsems 64-bit. Basically tip-off the powerpc code, use a 64-bit type and atomic64_t interfaces for the implementation. This gets us off of the by-hand asm code I wrote, which frankly I think probably ruins I-cache hit rates. The idea was the keep the call chains less deep, but anything taking the rw-semaphores probably is also calling other stuff and therefore already has allocated a stack-frame. So no real stack frame savings ever. Ben H. has posted patches to make powerpc use 64-bit too and with some abstractions we can probably use a shared header file somewhere. With suggestions from Sam Ravnborg. Signed-off-by: David S. Miller --- arch/sparc/include/asm/rwsem-const.h | 12 ---- arch/sparc/include/asm/rwsem.h | 120 ++++++++++++++++++++++++++++++----- 2 files changed, 103 insertions(+), 29 deletions(-) delete mode 100644 arch/sparc/include/asm/rwsem-const.h (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/rwsem-const.h b/arch/sparc/include/asm/rwsem-const.h deleted file mode 100644 index e4c61a18bb28..000000000000 --- a/arch/sparc/include/asm/rwsem-const.h +++ /dev/null @@ -1,12 +0,0 @@ -/* rwsem-const.h: RW semaphore counter constants. */ -#ifndef _SPARC64_RWSEM_CONST_H -#define _SPARC64_RWSEM_CONST_H - -#define RWSEM_UNLOCKED_VALUE 0x00000000 -#define RWSEM_ACTIVE_BIAS 0x00000001 -#define RWSEM_ACTIVE_MASK 0x0000ffff -#define RWSEM_WAITING_BIAS (-0x00010000) -#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS -#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) - -#endif /* _SPARC64_RWSEM_CONST_H */ diff --git a/arch/sparc/include/asm/rwsem.h b/arch/sparc/include/asm/rwsem.h index 6e5621006f85..a2b4302869bc 100644 --- a/arch/sparc/include/asm/rwsem.h +++ b/arch/sparc/include/asm/rwsem.h @@ -15,16 +15,21 @@ #include #include -#include struct rwsem_waiter; struct rw_semaphore { - signed int count; - spinlock_t wait_lock; - struct list_head wait_list; + signed long count; +#define RWSEM_UNLOCKED_VALUE 0x00000000L +#define RWSEM_ACTIVE_BIAS 0x00000001L +#define RWSEM_ACTIVE_MASK 0xffffffffL +#define RWSEM_WAITING_BIAS (-RWSEM_ACTIVE_MASK-1) +#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS +#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) + spinlock_t wait_lock; + struct list_head wait_list; #ifdef CONFIG_DEBUG_LOCK_ALLOC - struct lockdep_map dep_map; + struct lockdep_map dep_map; #endif }; @@ -41,6 +46,11 @@ struct rw_semaphore { #define DECLARE_RWSEM(name) \ struct rw_semaphore name = __RWSEM_INITIALIZER(name) +extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem); +extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem); +extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem); +extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem); + extern void __init_rwsem(struct rw_semaphore *sem, const char *name, struct lock_class_key *key); @@ -51,27 +61,103 @@ do { \ __init_rwsem((sem), #sem, &__key); \ } while (0) -extern void __down_read(struct rw_semaphore *sem); -extern int __down_read_trylock(struct rw_semaphore *sem); -extern void __down_write(struct rw_semaphore *sem); -extern int __down_write_trylock(struct rw_semaphore *sem); -extern void __up_read(struct rw_semaphore *sem); -extern void __up_write(struct rw_semaphore *sem); -extern void __downgrade_write(struct rw_semaphore *sem); +/* + * lock for reading + */ +static inline void __down_read(struct rw_semaphore *sem) +{ + if (unlikely(atomic64_inc_return((atomic64_t *)(&sem->count)) <= 0L)) + rwsem_down_read_failed(sem); +} + +static inline int __down_read_trylock(struct rw_semaphore *sem) +{ + long tmp; + + while ((tmp = sem->count) >= 0L) { + if (tmp == cmpxchg(&sem->count, tmp, + tmp + RWSEM_ACTIVE_READ_BIAS)) { + return 1; + } + } + return 0; +} +/* + * lock for writing + */ static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) { - __down_write(sem); + long tmp; + + tmp = atomic64_add_return(RWSEM_ACTIVE_WRITE_BIAS, + (atomic64_t *)(&sem->count)); + if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS)) + rwsem_down_write_failed(sem); } -static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem) +static inline void __down_write(struct rw_semaphore *sem) { - return atomic_add_return(delta, (atomic_t *)(&sem->count)); + __down_write_nested(sem, 0); +} + +static inline int __down_write_trylock(struct rw_semaphore *sem) +{ + long tmp; + + tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE, + RWSEM_ACTIVE_WRITE_BIAS); + return tmp == RWSEM_UNLOCKED_VALUE; } -static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) +/* + * unlock after reading + */ +static inline void __up_read(struct rw_semaphore *sem) +{ + long tmp; + + tmp = atomic64_dec_return((atomic64_t *)(&sem->count)); + if (unlikely(tmp < -1L && (tmp & RWSEM_ACTIVE_MASK) == 0L)) + rwsem_wake(sem); +} + +/* + * unlock after writing + */ +static inline void __up_write(struct rw_semaphore *sem) +{ + if (unlikely(atomic64_sub_return(RWSEM_ACTIVE_WRITE_BIAS, + (atomic64_t *)(&sem->count)) < 0L)) + rwsem_wake(sem); +} + +/* + * implement atomic add functionality + */ +static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem) +{ + atomic64_add(delta, (atomic64_t *)(&sem->count)); +} + +/* + * downgrade write lock to read lock + */ +static inline void __downgrade_write(struct rw_semaphore *sem) +{ + long tmp; + + tmp = atomic64_add_return(-RWSEM_WAITING_BIAS, (atomic64_t *)(&sem->count)); + if (tmp < 0L) + rwsem_downgrade_wake(sem); +} + +/* + * implement exchange and add functionality + */ +static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem) { - atomic_add(delta, (atomic_t *)(&sem->count)); + return atomic64_add_return(delta, (atomic64_t *)(&sem->count)); } static inline int rwsem_is_locked(struct rw_semaphore *sem) -- cgit v1.2.3 From 0f58189d4a3ca96d7959501ecb203177efdbc5bd Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 18 Aug 2010 22:53:26 -0700 Subject: sparc64: Make lock backoff really a NOP on UP builds. As noticed by Mikulas Patocka, the backoff macros don't completely nop out for UP builds, we still get a branch always and a delay slot nop. Fix this by making the branch to the backoff spin loop selective, then we can nop out the spin loop completely. Signed-off-by: David S. Miller --- arch/sparc/include/asm/backoff.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/backoff.h b/arch/sparc/include/asm/backoff.h index fa1fdf67e350..db3af0d30fb1 100644 --- a/arch/sparc/include/asm/backoff.h +++ b/arch/sparc/include/asm/backoff.h @@ -8,6 +8,9 @@ #define BACKOFF_SETUP(reg) \ mov 1, reg +#define BACKOFF_LABEL(spin_label, continue_label) \ + spin_label + #define BACKOFF_SPIN(reg, tmp, label) \ mov reg, tmp; \ 88: brnz,pt tmp, 88b; \ @@ -22,9 +25,11 @@ #else #define BACKOFF_SETUP(reg) -#define BACKOFF_SPIN(reg, tmp, label) \ - ba,pt %xcc, label; \ - nop; + +#define BACKOFF_LABEL(spin_label, continue_label) \ + continue_label + +#define BACKOFF_SPIN(reg, tmp, label) #endif -- cgit v1.2.3 From 019408f9b89c68cd7b8ddb904960dc17ccf7e531 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 19 Aug 2010 14:15:32 -0700 Subject: sparc64: Fill a missing delay slot. If the code were already aligned to 64 bytes, wr instruction would be executed twice --- once in delay slot and once in the jump target. Signed-off-by: Mikulas Patocka Signed-off-by: David S. Miller --- arch/sparc/include/asm/system_64.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/system_64.h b/arch/sparc/include/asm/system_64.h index d24cfe16afc1..e3b65d8cf41b 100644 --- a/arch/sparc/include/asm/system_64.h +++ b/arch/sparc/include/asm/system_64.h @@ -106,6 +106,7 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \ */ #define write_pic(__p) \ __asm__ __volatile__("ba,pt %%xcc, 99f\n\t" \ + " nop\n\t" \ ".align 64\n" \ "99:wr %0, 0x0, %%pic\n\t" \ "rd %%pic, %%g0" : : "r" (__p)) -- cgit v1.2.3 From 25edd6946a1d74e5e77813c2324a0908c68bcf9e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 23 Aug 2010 23:10:57 -0700 Subject: sparc64: Get rid of indirect p1275 PROM call buffer. This is based upon a report by Meelis Roos showing that it's possible that we'll try to fetch a property that is 32K in size with some devices. With the current fixed 3K buffer we use for moving data in and out of the firmware during PROM calls, that simply won't work. In fact, it will scramble random kernel data during bootup. The reasoning behind the temporary buffer is entirely historical. It used to be the case that we had problems referencing dynamic kernel memory (including the stack) early in the boot process before we explicitly told the firwmare to switch us over to the kernel trap table. So what we did was always give the firmware buffers that were locked into the main kernel image. But we no longer have problems like that, so get rid of all of this indirect bounce buffering. Besides fixing Meelis's bug, this also makes the kernel data about 3K smaller. It was also discovered during these conversions that the implementation of prom_retain() was completely wrong, so that was fixed here as well. Currently that interface is not in use. Reported-by: Meelis Roos Tested-by: Meelis Roos Signed-off-by: David S. Miller --- arch/sparc/include/asm/oplib_64.h | 27 +++------------------------ 1 file changed, 3 insertions(+), 24 deletions(-) (limited to 'arch/sparc/include') diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h index a5db0317b5fb..3e0b2d62303d 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h @@ -185,9 +185,8 @@ extern int prom_getunumber(int syndrome_code, char *buf, int buflen); /* Retain physical memory to the caller across soft resets. */ -extern unsigned long prom_retain(const char *name, - unsigned long pa_low, unsigned long pa_high, - long size, long align); +extern int prom_retain(const char *name, unsigned long size, + unsigned long align, unsigned long *paddr); /* Load explicit I/D TLB entries into the calling processor. */ extern long prom_itlb_load(unsigned long index, @@ -287,26 +286,6 @@ extern void prom_sun4v_guest_soft_state(void); extern int prom_ihandle2path(int handle, char *buffer, int bufsize); /* Client interface level routines. */ -extern long p1275_cmd(const char *, long, ...); - -#if 0 -#define P1275_SIZE(x) ((((long)((x) / 32)) << 32) | (x)) -#else -#define P1275_SIZE(x) x -#endif - -/* We support at most 16 input and 1 output argument */ -#define P1275_ARG_NUMBER 0 -#define P1275_ARG_IN_STRING 1 -#define P1275_ARG_OUT_BUF 2 -#define P1275_ARG_OUT_32B 3 -#define P1275_ARG_IN_FUNCTION 4 -#define P1275_ARG_IN_BUF 5 -#define P1275_ARG_IN_64B 6 - -#define P1275_IN(x) ((x) & 0xf) -#define P1275_OUT(x) (((x) << 4) & 0xf0) -#define P1275_INOUT(i,o) (P1275_IN(i)|P1275_OUT(o)) -#define P1275_ARG(n,x) ((x) << ((n)*3 + 8)) +extern void p1275_cmd_direct(unsigned long *); #endif /* !(__SPARC64_OPLIB_H) */ -- cgit v1.2.3