Re: [PATCH 1/5] ptp: Added a brand new class driver for ptp clocks.
On Tue, Aug 17, 2010 at 05:22:43PM -0700, john stultz wrote: Why would system time not be adjusted to the PTP time? This is my main concern, that we're presenting a fractured API to userland. Suddenly there isn't just system time, but ptp time as well, and possibly multiple different ptp times. John, it is a good thing to make thoughts about the big picture with PTP clocks and the system time, like you are doing. However, the situation is not as troubled as you think. Let me try to explain. The PTP clock is a bit of hardware (usually on the NIC) that can put timestamps on packets (both incoming or outgoing?). Not only on the NIC. There are bunch of new products doing the timestamping in the PHY or in a switch fabric attached to the host like a PHY. The synchronization that one can achieve with PHY timestamps is better that that with MAC timestamping. So while to me, it think it would be more ideal (or maybe just less different) to have a read-only interface (like the RTC), leaving PTPd to manage offset calculations and use that to steer the system time. I can acknowledge the need to have some way to correct the freq so the packet timestamps are corrected. The PTPd need not change the system time at all for PTP clock to be useful. (see below) I still feel a little concerned over the timer/alarm related interfaces. Could you explain why the alarm interface is necessary? The timer/alarm stuff is ancillary and is not at all necessary. It is just a nice to have. I will happily remove it, if it is too troubling for people. So really I think my initial negative gut reaction to this was mostly out of the fact that you introduced a char dev that provides almost 100% coverage of the posix-time interface. That is duplication we definitely don't want. The reason why I modelled the char device on the posix interface was to make the API more familiar to application programmers. After the recent discussion (and having reviewed the posix clock implementation in Linux), I now think it would be even better to simply offer a new posic clock ID for PTP. I was emulating the posix interface. Instead I should use it directly. Also I think the documentation I've read about PTP (likely just due to the engineering focus) has an odd inverted sense of priority, focusing on keeping obscure hardware clocks on NIC cards in sync, rather then the the more tangible feature of keeping the system time in sync. This could be comically interpreted as trying to create a shadow-time on the system that is the real time and yea, maybe we'll let the system know what time it is, but user-apps who want to know the score can send a magic ioctl to /dev/something and get the real deal. ;) I'm sure that's not the case, but I'd like to keep any confusion in userland about which time is the best time to a minimum (ie: use the system time). You are right. As John Eidson's excellent book points out, modern computers and operating systems provide surprisingly little support for programming based on absolute time. It is not PTP's fault. PTP is actually a step in the right direction, but it doesn't yet really fit in to the present computing world. Okay, here is the Big Picture. 1. Use Case: SW timestamping PTP with software timestamping (ie without special hardware) can acheive synchronization within a few dozen microseconds, after about twenty minutes. This is sufficient for very many people. The new API (whether char device or syscall) fully and simply supports this use case. When the PTPd adjusts the PTP clock, it is actually adjusting the system time, just like NTPd. 2. Use Case: HW timestamping for industrial control PTP with hardware timestamping can acheive synchronization within 100 nanoseconds after one minute. If you want to do something with your wonderfully synchronization PTP clock, it must have some kind of special hardware, like timestamping external signals or generating one-shot or periodic outputs. The new API (whether char device or syscall) supports this use case via the ancillary commands. In this case, the end user has an application that interfaces with the outside world via the PTP clock API. Such a specialized application (for example, motor control) uses only the PTP API, since it knows that the standard posix API cannot help. It is irrelevant that the system time is not synchronized, in this case. The PTP clock hardware may or may not provide a hardware interface (interrupt) to the main CPU. In this case, it does not matter. The PTP clock is useful all by itself. 3. Use Case: HW timestamping with PPS to host This case is the same as case 2, with the exception that the PTP clock can interrupt the main CPU. The PTP clock driver advertises the PPS capability. When enabled, the PTP layer delivers events via the existing Linux PPS subsystem. Programs like NTPd can use these events to regulate the system
cpm_i2c: write OK but read fail
Hi, My system is MPC870 based and I'm enabling the I2C driver and the ds1339 RTC driver. When the kernel tries to probe the RTC chip (slave address 0x68), the first write seems OK but the subsequent read times out. I applied the I2C/SPI microcode patch, which doesn't seem necessary though. Below is the dmesg output and all I2C debug messages are enabled. i2c-core: driver [rtc-ds1307] registered i2c /dev entries driver i2c-core: driver [dev_driver] registered fsl-i2c-cpm fa200860.i2c: cpm_i2c_setup() alloc irq_desc for 21 on node 0 alloc kstat_irqs on node 0 irq: irq 16 on host /s...@fa20/c...@9c0/interrupt-control...@930 mapped to virtual irq 21 fsl-i2c-cpm fa200860.i2c: i2c_ram 0xfddfa400, i2c_addr 0x0400, freq 6 fsl-i2c-cpm fa200860.i2c: tbase 0x0340, rbase 0x0360 i2c i2c-0: adapter [i2c-cpm] registered i2c-dev: adapter [i2c-cpm] registered as minor 0 fsl-i2c-cpm fa200860.i2c: hw routines for i2c-cpm registered. i2c 0-0068: uevent rtc-ds1307 0-0068: probe i2c i2c-0: master_xfer[0] W, addr=0x68, len=1 i2c i2c-0: master_xfer[1] R, addr=0x68, len=2 i2c i2c-0: R: 0 T: 0 i2c i2c-0: cpm_i2c_write(abyte=0xd0) i2c i2c-0: R: 0 T: 1 i2c i2c-0: cpm_i2c_read(abyte=0xd1) ^ The above shows there were two transfers being built (one write, one read). i2c i2c-0: test ready. i2c i2c-0: Interrupt: 2 i2c i2c-0: ready. i2c i2c-0: tx sc 0 0x1400 ^^^ This shows the write command went through successfully. i2c i2c-0: test ready. i2c i2c-0: I2C transfer: timeout ^ However the read timed out. :( i2c i2c-0: cpm_i2c_force_close() rtc-ds1307: probe of 0-0068 failed with error -5 i2c i2c-0: client [ds1339] registered with bus id 0-0068 The Tx/Rx BDs are dumped below. fa202340 : 1402 07b51000 ac03 07b53000 ..0. fa202350 : 9fc3f137 07b55000 9739a1d0 07b4f000 ...7..P..9.. fa202360 : 9000 07b5 b68fa19d 07b52000 .. . fa202370 : 1b85e6cc 07b54000 49df3090 07b4e000 ..@.i.0. What went wrong with read? Thanks, -Shawn. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/5] ptp: Added a brand new class driver for ptp clocks.
On Tue, Aug 17, 2010 at 01:36:29PM +0200, Arnd Bergmann wrote: On Tuesday 17 August 2010, Richard Cochran wrote: I've been looking at offering the PTP clock as a posix clock, and it is not as hard as I first thought. The PTP clock or clocks just have to be registered as one of the posix_clocks[MAX_CLOCKS] in posix-timers.c. Ok sounds good. I've been working turning the PTP stuff into syscalls, but here is a little issue I ran into. The PTP clock layer wants to call the PPS code via pps_register_source(), but the PPS can be compiled as a module. Since the PTP layer is now offering syscalls, it must always be present in the kernel. So I need to make sure that the PPS is either absent entirely or staticly linked in. How can I do this? Thanks, Richard ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: How to use mpc8xxx_gpio.c device driver
Hi, Thanks for all your replies. Now I want to enable interrupts on some GPIO pins(GPIO pins number 224, 225, 226, 227, 228 and 229 i.e gpiochip224's pins 0 to 5). I configured these pins as input(GPIOF_IN) during gpio request. I am able to request gpio pins successfully. #define GPIO_CHIP0_BASE192 #define GPIO_CHIP0_COUNT 32 #define GPIO_CHIP1_BASE224 #define GPIO_CHIP1_COUNT 32 #define GPIO(chip, pin) (GPIO_CHIP##chip##_BASE + (pin)) /* Initial GPIO pins setting. */ static struct gpio gpio_pins[] = { { GPIO(1, 0), GPIOF_IN,Chip 1, Pin 0 }, { GPIO(1, 1), GPIOF_IN,Chip 1, Pin 1 }, { GPIO(1, 2), GPIOF_IN,Chip 1, Pin 2 }, { GPIO(1, 3), GPIOF_IN,Chip 1, Pin 3 }, { GPIO(1, 4), GPIOF_IN,Chip 1, Pin 4 }, { GPIO(1, 5), GPIOF_IN,Chip 1, Pin 5 }, }; static __init int gpio_module_init(void) { int err; dev_t devno = 0; printk(KERN_INFO GPIO Driver Version 0.1\n); /* resuest the gpio pin */ err = gpio_request_array(gpio_pins, ARRAY_SIZE(gpio_pins)); if (err) { printk(KERN_WARNING gpio: unable to request gpio pins\n); return -EBUSY; } /* register interrupts handlers */ err = gpio_request_irq_array(gpio_irq_pins, ARRAY_SIZE(gpio_irq_pins)); if (err) { printk(KERN_WARNING gpio: unable to register interrupt handler.\n); goto interrupt_fail; } . . . } Now in order to enable interrupts I have to set the bits corresponding to these pins in gpiochp Interrupt Mask Register. My first question is that is there any gpio API call available for doing this? OR I have to manually memory map the gpio IMR register and set bit manually? For the time being I have manually set the IMR bit(using memory map). Second, in order to register an interrupt handler on a gpio pin, I need a IRQ number, so how am I going to get that number? From the Documentation/gpio.txt, it looks to me that gpio_to_irq() function should give me the irq number, but when I tried to use it, it gives me an error. #define GPIO_CHIP0_BASE192 #define GPIO_CHIP0_COUNT 32 #define GPIO_CHIP1_BASE224 #define GPIO_CHIP1_COUNT 32 #define GPIO(chip, pin) (GPIO_CHIP##chip##_BASE + (pin)) static struct gpio_irq gpio_irq_pins[] = { { GPIO(1, 0), IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW }, { GPIO(1, 1), IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW }, { GPIO(1, 2), IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW }, { GPIO(1, 3), IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW }, { GPIO(1, 4), IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW }, { GPIO(1, 5), IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW }, }; int gpio_request_irq_array(struct gpio_irq *array, size_t num) { int i, err, irq; for (i = 0; i num; i++, array++) { /* get the irq number corresponding to the gpio pin */ irq = gpio_to_irq(array-gpio); if (irq 0) { printk(KERN_ERR gpio: Trying to get irq number for GPIO%d\n, array-gpio); err = -EINVAL; goto err_free; } printd(gpio: irq number for GPIO%d = %d(i=%d)\n, array-gpio, irq, i); /* set the irq type for the gpio pin */ err = set_irq_type(irq, array-type); if (err) goto err_free; /* register irq handler */ err = request_irq(irq, gpio_irq_handler, IRQF_SHARED, GPIO Driver, NULL); if (err) { printk(KERN_ERR gpio: can't get assigned irq for GPIO%d\n, array-gpio); goto err_free; } } return 0; err_free: while (i--) free_irq(gpio_to_irq((--array)-gpio), NULL); return err; } Given above is my driver code, I have implemented a function named gpio_request_irq_array which works in same manner as that of gpio_request_array. I am calling in the init function, see the init code given initially. Now when I load it on my MPC837xERDB board, it gives the following errors. [ 1812.776420] GPIO Driver Version 0.1 [ 1812.779985] gpio: Trying to get irq number for GPIO224 [ 1812.785126] gpio: unable to register interrupt handler. insmod: error inserting './gpio.ko': -1 Invalid parameters Thanks in advance Ravi Gupta ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/5] ptp: Added a brand new class driver for ptp clocks.
On Wednesday 18 August 2010, Richard Cochran wrote: On Tue, Aug 17, 2010 at 01:36:29PM +0200, Arnd Bergmann wrote: On Tuesday 17 August 2010, Richard Cochran wrote: I've been looking at offering the PTP clock as a posix clock, and it is not as hard as I first thought. The PTP clock or clocks just have to be registered as one of the posix_clocks[MAX_CLOCKS] in posix-timers.c. Ok sounds good. I've been working turning the PTP stuff into syscalls, but here is a little issue I ran into. The PTP clock layer wants to call the PPS code via pps_register_source(), but the PPS can be compiled as a module. Since the PTP layer is now offering syscalls, it must always be present in the kernel. So I need to make sure that the PPS is either absent entirely or staticly linked in. How can I do this? You might want to use callbacks for these system calls that you can register to at module load time, like it is done for the existing syscalls. The simpler way (e.g. for testing) is using Kconfig dependencies, like config PTP bool IEEE 1588 Precision Time Protocol config PPS tristate Pulse per Second depends on PTP || !PTP The depends statement is a way of expressing that when PTP is enabled, PPS cannot be a module, while it may be a module if PTP is disabled. Arnd ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/4] powerpc/47x: Make sure mcsr is cleared before enabling machine check interrupts
Clear the machine check syndrom register before enabling machine check interrupts. The initial state of the tlb can lead to parity errors being flagged early after a cold boot. Signed-off-by: Dave Kleikamp sha...@linux.vnet.ibm.com --- arch/powerpc/kernel/head_44x.S |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index 5ab484e..562305b 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S @@ -113,6 +113,10 @@ _ENTRY(_start); stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */ stw r6, 0(r5) + /* Clear the Machine Check Syndrome Register */ + li r0,0 + mtspr SPRN_MCSR,r0 + /* Let's move on */ lis r4,start_ker...@h ori r4,r4,start_ker...@l -- 1.7.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 0/4] *** SUBJECT HERE ***
Josh, Here are some bug fixes for the powerpc-4xx tree. It'd be nice if they could make it into 2.6.46. Thanks, Shaggy Dave Kleikamp (4): powerpc/47x: Make sure mcsr is cleared before enabling machine check interrupts powerpc/47x: Remove redundant line from cputable.c powerpc/4xx: Index interrupt stacks by physical cpu powerpc/47x: Add an isync before the tlbivax instruction arch/powerpc/kernel/cputable.c |1 - arch/powerpc/kernel/head_44x.S |4 arch/powerpc/kernel/irq.c| 15 --- arch/powerpc/kernel/setup_32.c |9 + arch/powerpc/mm/tlb_nohash_low.S |1 + 5 files changed, 18 insertions(+), 12 deletions(-) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 4/4] powerpc/47x: Add an isync before the tlbivax instruction
Signed-off-by: Dave Kleikamp sha...@linux.vnet.ibm.com --- arch/powerpc/mm/tlb_nohash_low.S |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S index cfa7682..b9d9fed 100644 --- a/arch/powerpc/mm/tlb_nohash_low.S +++ b/arch/powerpc/mm/tlb_nohash_low.S @@ -200,6 +200,7 @@ _GLOBAL(_tlbivax_bcast) rlwimi r5,r4,0,16,31 wrteei 0 mtspr SPRN_MMUCR,r5 + isync /* tlbivax 0,r3 - use .long to avoid binutils deps */ .long 0x7c000624 | (r3 11) isync -- 1.7.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 3/4] powerpc/4xx: Index interrupt stacks by physical cpu
The interrupt stacks need to be indexed by the physical cpu since the critical, debug and machine check handlers use the contents of SPRN_PIR to index the critirq_ctx, dbgirq_ctx, and mcheckirq_ctx arrays. Signed-off-by: Dave Kleikamp sha...@linux.vnet.ibm.com --- arch/powerpc/kernel/irq.c | 15 --- arch/powerpc/kernel/setup_32.c |9 + 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index d3ce67c..52e9c95 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -446,22 +446,23 @@ struct thread_info *mcheckirq_ctx[NR_CPUS] __read_mostly; void exc_lvl_ctx_init(void) { struct thread_info *tp; - int i; + int i, hw_cpu; for_each_possible_cpu(i) { - memset((void *)critirq_ctx[i], 0, THREAD_SIZE); - tp = critirq_ctx[i]; + hw_cpu = get_hard_smp_processor_id(i); + memset((void *)critirq_ctx[hw_cpu], 0, THREAD_SIZE); + tp = critirq_ctx[hw_cpu]; tp-cpu = i; tp-preempt_count = 0; #ifdef CONFIG_BOOKE - memset((void *)dbgirq_ctx[i], 0, THREAD_SIZE); - tp = dbgirq_ctx[i]; + memset((void *)dbgirq_ctx[hw_cpu], 0, THREAD_SIZE); + tp = dbgirq_ctx[hw_cpu]; tp-cpu = i; tp-preempt_count = 0; - memset((void *)mcheckirq_ctx[i], 0, THREAD_SIZE); - tp = mcheckirq_ctx[i]; + memset((void *)mcheckirq_ctx[hw_cpu], 0, THREAD_SIZE); + tp = mcheckirq_ctx[hw_cpu]; tp-cpu = i; tp-preempt_count = HARDIRQ_OFFSET; #endif diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index a10ffc8..93666f9 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -258,17 +258,18 @@ static void __init irqstack_early_init(void) #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) static void __init exc_lvl_early_init(void) { - unsigned int i; + unsigned int i, hw_cpu; /* interrupt stacks must be in lowmem, we get that for free on ppc32 * as the memblock is limited to lowmem by MEMBLOCK_REAL_LIMIT */ for_each_possible_cpu(i) { - critirq_ctx[i] = (struct thread_info *) + hw_cpu = get_hard_smp_processor_id(i); + critirq_ctx[hw_cpu] = (struct thread_info *) __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); #ifdef CONFIG_BOOKE - dbgirq_ctx[i] = (struct thread_info *) + dbgirq_ctx[hw_cpu] = (struct thread_info *) __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); - mcheckirq_ctx[i] = (struct thread_info *) + mcheckirq_ctx[hw_cpu] = (struct thread_info *) __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); #endif } -- 1.7.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 2/4] powerpc/47x: Remove redundant line from cputable.c
There are two entries for .cpu_user_features in arch/powerpc/kernel/cputable.c. Remove the one that doesn't belong Signed-off-by: Dave Kleikamp sha...@linux.vnet.ibm.com --- arch/powerpc/kernel/cputable.c |1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 65e2b4e..1f9123f 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -1826,7 +1826,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_features = CPU_FTRS_47X, .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, - .cpu_user_features = COMMON_USER_BOOKE, .mmu_features = MMU_FTR_TYPE_47x | MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL, .icache_bsize = 32, -- 1.7.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 0/4] Some 47x patches for the powerpc-4xx tree
Sorry! Forgot to change the subject. Shaggy On Wed, 2010-08-18 at 11:44 -0500, Dave Kleikamp wrote: Josh, Here are some bug fixes for the powerpc-4xx tree. It'd be nice if they could make it into 2.6.46. Thanks, Shaggy Dave Kleikamp (4): powerpc/47x: Make sure mcsr is cleared before enabling machine check interrupts powerpc/47x: Remove redundant line from cputable.c powerpc/4xx: Index interrupt stacks by physical cpu powerpc/47x: Add an isync before the tlbivax instruction arch/powerpc/kernel/cputable.c |1 - arch/powerpc/kernel/head_44x.S |4 arch/powerpc/kernel/irq.c| 15 --- arch/powerpc/kernel/setup_32.c |9 + arch/powerpc/mm/tlb_nohash_low.S |1 + 5 files changed, 18 insertions(+), 12 deletions(-) -- Dave Kleikamp IBM Linux Technology Center ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc/pci: fix checking for child bridges in PCI code.
pci_device_to_OF_node() can return null, and list_for_each_entry will never enter the loop when dev is NULL, so it looks like this test is a typo. Reported-by: Julia Lawall ju...@diku.dk Signed-off-by: Grant Likely grant.lik...@secretlab.ca --- arch/powerpc/kernel/pci_of_scan.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index 6ddb795..e751506 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -336,7 +336,7 @@ static void __devinit __of_scan_bus(struct device_node *node, if (dev-hdr_type == PCI_HEADER_TYPE_BRIDGE || dev-hdr_type == PCI_HEADER_TYPE_CARDBUS) { struct device_node *child = pci_device_to_OF_node(dev); - if (dev) + if (child) of_scan_pci_bridge(child, dev); } } ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] Correct rtas_data_buf locking in dlpar code
The dlpar code can cause a deadlock to occur when making the RTAS configure-connector call. This occurs because we make kmalloc calls, which can block, while parsing the rtas_data_buf and holding the rtas_data_buf_lock. This an cause issues if someone else attempts to grab the rtas_data_bug_lock. This patch alleviates this issue by copying the contents of the rtas_data_buf to a local buffer before parsing. This allows us to only hold the rtas_data_buf_lock around the RTAS configure-connector calls. Signed-off-by: Nathan Fontenot nf...@austin.ibm.com --- arch/powerpc/platforms/pseries/dlpar.c | 42 ++--- 1 file changed, 29 insertions(+), 13 deletions(-) Index: powerpc/arch/powerpc/platforms/pseries/dlpar.c === --- powerpc.orig/arch/powerpc/platforms/pseries/dlpar.c 2010-08-05 10:55:46.0 -0500 +++ powerpc/arch/powerpc/platforms/pseries/dlpar.c 2010-08-18 11:42:10.0 -0500 @@ -129,20 +129,35 @@ struct device_node *dlpar_configure_conn struct property *property; struct property *last_property = NULL; struct cc_workarea *ccwa; + char *data_buf; int cc_token; - int rc; + int rc = -1; cc_token = rtas_token(ibm,configure-connector); if (cc_token == RTAS_UNKNOWN_SERVICE) return NULL; - spin_lock(rtas_data_buf_lock); - ccwa = (struct cc_workarea *)rtas_data_buf[0]; + data_buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL); + if (!data_buf) + return NULL; + + ccwa = (struct cc_workarea *)data_buf[0]; ccwa-drc_index = drc_index; ccwa-zero = 0; - rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL); - while (rc) { + do { + /* Since we release the rtas_data_buf lock between configure +* connector calls we want to re-populate the rtas_data_buffer +* with the contents of the previous call. +*/ + spin_lock(rtas_data_buf_lock); + + memcpy(rtas_data_buf, data_buf, RTAS_DATA_BUF_SIZE); + rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL); + memcpy(data_buf, rtas_data_buf, RTAS_DATA_BUF_SIZE); + + spin_unlock(rtas_data_buf_lock); + switch (rc) { case NEXT_SIBLING: dn = dlpar_parse_cc_node(ccwa); @@ -197,18 +212,19 @@ struct device_node *dlpar_configure_conn returned from configure-connector\n, rc); goto cc_error; } + } while (rc); - rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL); +cc_error: + kfree(data_buf); + + if (rc) { + if (first_dn) + dlpar_free_cc_nodes(first_dn); + + return NULL; } - spin_unlock(rtas_data_buf_lock); return first_dn; - -cc_error: - if (first_dn) - dlpar_free_cc_nodes(first_dn); - spin_unlock(rtas_data_buf_lock); - return NULL; } static struct device_node *derive_parent(const char *path) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[no subject]
Dear Rupjyoti, drivers/ata/sata_dwc_460ex.c fails to build in current mainline: ... CC drivers/ata/sata_dwc_460ex.o drivers/ata/sata_dwc_460ex.c:43:1: warning: DRV_NAME redefined In file included from drivers/ata/sata_dwc_460ex.c:38: drivers/ata/libata.h:31:1: warning: this is the location of the previous definition drivers/ata/sata_dwc_460ex.c:44:1: warning: DRV_VERSION redefined drivers/ata/libata.h:32:1: warning: this is the location of the previous definition drivers/ata/sata_dwc_460ex.c: In function 'sata_dwc_exec_command_by_tag': drivers/ata/sata_dwc_460ex.c:1356: warning: passing argument 1 of 'ata_get_cmd_descript' makes integer from pointer without a cast drivers/ata/sata_dwc_460ex.c: At top level: drivers/ata/sata_dwc_460ex.c:1592: warning: 'struct of_device' declared inside parameter list drivers/ata/sata_dwc_460ex.c:1592: warning: its scope is only this definition or declaration, which is probably not what you want drivers/ata/sata_dwc_460ex.c: In function 'sata_dwc_probe': drivers/ata/sata_dwc_460ex.c:1607: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1614: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1616: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1622: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1628: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1630: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1646: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1650: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1652: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1658: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1660: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1667: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1676: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1678: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1691: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1693: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c: At top level: drivers/ata/sata_dwc_460ex.c:1705: warning: 'struct of_device' declared inside parameter list drivers/ata/sata_dwc_460ex.c: In function 'sata_dwc_remove': drivers/ata/sata_dwc_460ex.c:1707: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1720: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c: At top level: drivers/ata/sata_dwc_460ex.c:1736: warning: initialization from incompatible pointer type drivers/ata/sata_dwc_460ex.c:1737: warning: initialization from incompatible pointer type make[2]: *** [drivers/ata/sata_dwc_460ex.o] Error 1 Do you have any hints how to fix that? Best regards, Wolfgang Denk -- DENX Software Engineering GmbH, MD: Wolfgang Denk Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: w...@denx.de Few people do business well who do nothing else. -- Philip Earl of Chesterfield ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/5] ptp: Added a brand new class driver for ptp clocks.
On Wed, 2010-08-18 at 09:19 +0200, Richard Cochran wrote: On Tue, Aug 17, 2010 at 05:22:43PM -0700, john stultz wrote: So while to me, it think it would be more ideal (or maybe just less different) to have a read-only interface (like the RTC), leaving PTPd to manage offset calculations and use that to steer the system time. I can acknowledge the need to have some way to correct the freq so the packet timestamps are corrected. The PTPd need not change the system time at all for PTP clock to be useful. (see below) Right, obviously an ok-solution is often more useful then no-solution. But that doesn't mean we shouldn't shoot for a good or even great-solution. :) I still feel a little concerned over the timer/alarm related interfaces. Could you explain why the alarm interface is necessary? The timer/alarm stuff is ancillary and is not at all necessary. It is just a nice to have. I will happily remove it, if it is too troubling for people. If there's a compelling argument for it, I'm interested to hear. But again, it seems like just yet-another-way-to-get-alarm/timer-functionality, so before we add an extra API (or widen an existing API) I'd like to understand the need. But maybe it might simplify the discussion to pull it for now, but keeping it in mind to possibly include later as an extension? So really I think my initial negative gut reaction to this was mostly out of the fact that you introduced a char dev that provides almost 100% coverage of the posix-time interface. That is duplication we definitely don't want. The reason why I modelled the char device on the posix interface was to make the API more familiar to application programmers. After the recent discussion (and having reviewed the posix clock implementation in Linux), I now think it would be even better to simply offer a new posic clock ID for PTP. I was emulating the posix interface. Instead I should use it directly. I'm definitely interested to see what you come up with here. I'm still hesitant with adding a PTP clock_id, but extending the posix-clocks interface in this way isn't unprecedented (see: CLOCK_SGI_CYCLE) I just would like to make sure we don't end up with a clock_id namespace littered with oddball clocks that were not well abstracted (see: CLOCK_SGI_CYCLE :). For instance: imagine if instead of keeping the clocksource abstraction internal to the timekeeping core, we exposed each clocksource to userland via a clock_id. Every arch would have different ids, and each arch might have multiple ids. Programming against that would be a huge pain. So in thinking about this, try to focus on what the new clock_id provides that the other existing clockids do not? Are they at comparable levels of abstraction? 15 years from now, are folks likely to still be using it? Will it be maintainable? etc... Also I think the documentation I've read about PTP (likely just due to the engineering focus) has an odd inverted sense of priority, focusing on keeping obscure hardware clocks on NIC cards in sync, rather then the the more tangible feature of keeping the system time in sync. This could be comically interpreted as trying to create a shadow-time on the system that is the real time and yea, maybe we'll let the system know what time it is, but user-apps who want to know the score can send a magic ioctl to /dev/something and get the real deal. ;) I'm sure that's not the case, but I'd like to keep any confusion in userland about which time is the best time to a minimum (ie: use the system time). You are right. As John Eidson's excellent book points out, modern computers and operating systems provide surprisingly little support for programming based on absolute time. It is not PTP's fault. PTP is actually a step in the right direction, but it doesn't yet really fit in to the present computing world. You'll have to forgive me, as I haven't had the time to check out that book. What exactly do you mean by operating systems provide little support for programming based on absolute time? Okay, here is the Big Picture. 1. Use Case: SW timestamping PTP with software timestamping (ie without special hardware) can acheive synchronization within a few dozen microseconds, after about twenty minutes. This is sufficient for very many people. The new API (whether char device or syscall) fully and simply supports this use case. When the PTPd adjusts the PTP clock, it is actually adjusting the system time, just like NTPd. Again this illustrates the inversion of focus: system time is merely one of many possible PTP clocks in the larger PTP framework. The way I tend to see it: PTP is just one of the many ways to sync system time. 2. Use Case: HW timestamping for industrial control PTP with hardware timestamping can acheive synchronization within 100 nanoseconds after one minute. If you want to do something with your wonderfully
Re:
Hi Wolfgang, On Wed, 18 Aug 2010 22:56:46 +0200 Wolfgang Denk w...@denx.de wrote: drivers/ata/sata_dwc_460ex.c: At top level: drivers/ata/sata_dwc_460ex.c:1592: warning: 'struct of_device' declared inside parameter list drivers/ata/sata_dwc_460ex.c:1592: warning: its scope is only this definition or declaration, which is probably not what you want drivers/ata/sata_dwc_460ex.c: In function 'sata_dwc_probe': drivers/ata/sata_dwc_460ex.c:1607: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1614: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1616: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1622: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1628: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1630: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1646: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1650: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1652: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1658: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1660: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1667: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1676: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1678: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1691: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1693: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c: At top level: drivers/ata/sata_dwc_460ex.c:1705: warning: 'struct of_device' declared inside parameter list drivers/ata/sata_dwc_460ex.c: In function 'sata_dwc_remove': drivers/ata/sata_dwc_460ex.c:1707: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c:1720: error: dereferencing pointer to incomplete type drivers/ata/sata_dwc_460ex.c: At top level: drivers/ata/sata_dwc_460ex.c:1736: warning: initialization from incompatible pointer type drivers/ata/sata_dwc_460ex.c:1737: warning: initialization from incompatible pointer type I think most of these (if not all) are fixed in Linus' tree today. -- Cheers, Stephen Rothwells...@canb.auug.org.au http://www.canb.auug.org.au/~sfr/ pgp1Od5VUUAHQ.pgp Description: PGP signature ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 0/4] Some 47x patches for the powerpc-4xx tree
On Wed, 2010-08-18 at 11:45 -0500, Dave Kleikamp wrote: Sorry! Forgot to change the subject. Shaggy On Wed, 2010-08-18 at 11:44 -0500, Dave Kleikamp wrote: Josh, Here are some bug fixes for the powerpc-4xx tree. It'd be nice if they could make it into 2.6.46. Yeah and I'm sure they can make it into 2.6.46... if you want to wait that long ! In the meantime, 2.6.36 will do :-) Cheers, Ben. Thanks, Shaggy Dave Kleikamp (4): powerpc/47x: Make sure mcsr is cleared before enabling machine check interrupts powerpc/47x: Remove redundant line from cputable.c powerpc/4xx: Index interrupt stacks by physical cpu powerpc/47x: Add an isync before the tlbivax instruction arch/powerpc/kernel/cputable.c |1 - arch/powerpc/kernel/head_44x.S |4 arch/powerpc/kernel/irq.c| 15 --- arch/powerpc/kernel/setup_32.c |9 + arch/powerpc/mm/tlb_nohash_low.S |1 + 5 files changed, 18 insertions(+), 12 deletions(-) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 1/3] Ramdisk address was not copied correctly on kexec'ed kernel
Signed-off-by: Matthew McClintock m...@freescale.com --- kexec/arch/ppc/fixup_dtb.c |2 +- kexec/arch/ppc/kexec-ppc.c |2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kexec/arch/ppc/fixup_dtb.c b/kexec/arch/ppc/fixup_dtb.c index 26c23a3..09f9ac1 100644 --- a/kexec/arch/ppc/fixup_dtb.c +++ b/kexec/arch/ppc/fixup_dtb.c @@ -311,7 +311,7 @@ static void fixup_initrd(char *blob_buf) return; } - tmp = ramdisk_base + ramdisk_size + 1; + tmp = ramdisk_base + ramdisk_size; err = fdt_setprop(blob_buf, nodeoffset, linux,initrd-end, tmp, sizeof(tmp)); if (err 0) { diff --git a/kexec/arch/ppc/kexec-ppc.c b/kexec/arch/ppc/kexec-ppc.c index c36c7b3..ab76d6f 100644 --- a/kexec/arch/ppc/kexec-ppc.c +++ b/kexec/arch/ppc/kexec-ppc.c @@ -481,7 +481,7 @@ static int get_devtree_details(unsigned long kexec_flags) if ((initrd_end - initrd_start) != 0 ) { initrd_base = initrd_start; - initrd_size = initrd_end - initrd_start + 1; + initrd_size = initrd_end - initrd_start; } if (reuse_initrd) { -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 0/3] Misc. bug fixes for ppc32
This patch series fixes a few issues I have discovered with my previous patch series. Nothing new has been added. v2: Missed signoff, removed initializing variable twice Matthew McClintock (3): Ramdisk address was not copied correctly on kexec'ed kernel Prevent multiple reservations for cpu-release-addr Prevent initrd-start and initrd-end from appearing multiple times kexec/arch/ppc/fixup_dtb.c | 50 --- kexec/arch/ppc/kexec-ppc.c |2 +- 2 files changed, 29 insertions(+), 23 deletions(-) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 3/3] Prevent initrd-start and initrd-end from appearing multiple times
We always remove the old entry, and add it back if it is needed on for the kexec'ed kernel Signed-off-by: Matthew McClintock m...@freescale.com --- kexec/arch/ppc/fixup_dtb.c | 20 ++-- 1 files changed, 10 insertions(+), 10 deletions(-) diff --git a/kexec/arch/ppc/fixup_dtb.c b/kexec/arch/ppc/fixup_dtb.c index 910a3f0..205fd77 100644 --- a/kexec/arch/ppc/fixup_dtb.c +++ b/kexec/arch/ppc/fixup_dtb.c @@ -160,7 +160,7 @@ static void fixup_reserve_regions(struct kexec_info *info, char *blob_buf, off_t goto out; } } - } else { + } else if (ramdisk || reuse_initrd) { /* Otherwise we just add back the ramdisk and the device tree * is already in the list */ ret = fdt_add_mem_rsv(blob_buf, ramdisk_base, ramdisk_size); @@ -300,13 +300,16 @@ static void fixup_initrd(char *blob_buf) nodeoffset = fdt_path_offset(blob_buf, /chosen); - if ((reuse_initrd || ramdisk) - ((ramdisk_base != 0) (ramdisk_size != 0))) { - if (nodeoffset 0) { - printf(fdt_initrd: %s\n, fdt_strerror(nodeoffset)); - return; - } + if (nodeoffset 0) { + printf(fdt_initrd: %s\n, fdt_strerror(nodeoffset)); + return; + } + + fdt_delprop(blob_buf, nodeoffset, linux,initrd-start); + fdt_delprop(blob_buf, nodeoffset, linux,initrd-end); + if ((reuse_initrd || ramdisk) + ((ramdisk_base != 0) (ramdisk_size != 0))) { tmp = ramdisk_base; err = fdt_setprop(blob_buf, nodeoffset, linux,initrd-start, tmp, sizeof(tmp)); @@ -325,9 +328,6 @@ static void fixup_initrd(char *blob_buf) fdt_strerror(err)); return; } - } else { - fdt_delprop(blob_buf, nodeoffset, linux,initrd-start); - fdt_delprop(blob_buf, nodeoffset, linux,initrd-end); } } -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 2/3] Prevent multiple reservations for cpu-release-addr
Currently, we can add a lot of reservations over a small range, this does a simple check to verify the previous entry is not the same as the current one and skips it if so Signed-off-by: Matthew McClintock m...@freescale.com --- kexec/arch/ppc/fixup_dtb.c | 28 +--- 1 files changed, 17 insertions(+), 11 deletions(-) diff --git a/kexec/arch/ppc/fixup_dtb.c b/kexec/arch/ppc/fixup_dtb.c index 09f9ac1..910a3f0 100644 --- a/kexec/arch/ppc/fixup_dtb.c +++ b/kexec/arch/ppc/fixup_dtb.c @@ -139,6 +139,7 @@ static void fixup_reserve_regions(struct kexec_info *info, char *blob_buf, off_t { int ret, i; int nodeoffset; + u64 val = 0; /* If this is a KEXEC kernel we add all regions since they will * all need to be saved */ @@ -175,20 +176,25 @@ static void fixup_reserve_regions(struct kexec_info *info, char *blob_buf, off_t while (nodeoffset != -FDT_ERR_NOTFOUND) { const void *buf; int sz, ret; - u64 val = 0; + u64 tmp; buf = fdt_getprop(blob_buf, nodeoffset, cpu-release-addr, sz); - if (sz == 4) { - val = *(u32 *)buf; - } else if (sz == 8) { - val = *(u64 *)buf; - } - if (val) { - ret = fdt_add_mem_rsv(blob_buf, PAGE_ALIGN(val-PAGE_SIZE), PAGE_SIZE); - if (ret) - printf(%s: Unable to add reserve for cpu-release-addr!\n, - fdt_strerror(ret)); + if (buf) { + if (sz == 4) { + tmp = *(u32 *)buf; + } else if (sz == 8) { + tmp = *(u64 *)buf; + } + + /* crude check to see if last value is repeated */ + if (_ALIGN_DOWN(tmp, PAGE_SIZE) != _ALIGN_DOWN(val, PAGE_SIZE)) { + val = tmp; + ret = fdt_add_mem_rsv(blob_buf, _ALIGN_DOWN(val, PAGE_SIZE), PAGE_SIZE); + if (ret) + printf(%s: Unable to add reserve for cpu-release-addr!\n, + fdt_strerror(ret)); + } } nodeoffset = fdt_node_offset_by_prop_value(blob_buf, nodeoffset, -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: 64-bit ppc rwsem
On Tue, 2010-08-17 at 22:28 -0700, David Miller wrote: From: Benjamin Herrenschmidt b...@kernel.crashing.org Date: Wed, 18 Aug 2010 15:03:23 +1000 I tried various tricks but so far they didn't work. I'll have another look tomorrow, but I may end up having to keep all the crap typecasts. The casts are pretty much unavoidable. Here's what I'm going to end up using on sparc64: Similar here, but using atomic_long_t instead so it works for 32-bit too for me. I suppose we could make that part common indeed. What about asm-generic/rwsem-atomic.h or rwsem-cmpxchg.h ? Below is my current patch, seems to boot fine here so far. Cheers, Ben Subject: [PATCH] powerpc: Make rwsem use long type This makes the 64-bit kernel use 64-bit signed integers for the counter (effectively supporting 32-bit of active count in the semaphore), thus avoiding things like overflow of the mmap_sem if you use a really crazy number of threads Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- arch/powerpc/include/asm/rwsem.h | 64 ++ 1 files changed, 37 insertions(+), 27 deletions(-) diff --git a/arch/powerpc/include/asm/rwsem.h b/arch/powerpc/include/asm/rwsem.h index 24cd928..8447d89 100644 --- a/arch/powerpc/include/asm/rwsem.h +++ b/arch/powerpc/include/asm/rwsem.h @@ -21,15 +21,20 @@ /* * the semaphore definition */ -struct rw_semaphore { - /* XXX this should be able to be an atomic_t -- paulus */ - signed int count; -#define RWSEM_UNLOCKED_VALUE 0x -#define RWSEM_ACTIVE_BIAS 0x0001 -#define RWSEM_ACTIVE_MASK 0x -#define RWSEM_WAITING_BIAS (-0x0001) +#ifdef CONFIG_PPC64 +# define RWSEM_ACTIVE_MASK 0xL +#else +# define RWSEM_ACTIVE_MASK 0xL +#endif + +#define RWSEM_UNLOCKED_VALUE 0xL +#define RWSEM_ACTIVE_BIAS 0x0001L +#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) + +struct rw_semaphore { + longcount; spinlock_t wait_lock; struct list_headwait_list; #ifdef CONFIG_DEBUG_LOCK_ALLOC @@ -43,9 +48,13 @@ struct rw_semaphore { # define __RWSEM_DEP_MAP_INIT(lockname) #endif -#define __RWSEM_INITIALIZER(name) \ - { RWSEM_UNLOCKED_VALUE, __SPIN_LOCK_UNLOCKED((name).wait_lock), \ - LIST_HEAD_INIT((name).wait_list) __RWSEM_DEP_MAP_INIT(name) } +#define __RWSEM_INITIALIZER(name) \ +{ \ + RWSEM_UNLOCKED_VALUE, \ + __SPIN_LOCK_UNLOCKED((name).wait_lock), \ + LIST_HEAD_INIT((name).wait_list)\ + __RWSEM_DEP_MAP_INIT(name) \ +} #define DECLARE_RWSEM(name)\ struct rw_semaphore name = __RWSEM_INITIALIZER(name) @@ -70,13 +79,13 @@ extern void __init_rwsem(struct rw_semaphore *sem, const char *name, */ static inline void __down_read(struct rw_semaphore *sem) { - if (unlikely(atomic_inc_return((atomic_t *)(sem-count)) = 0)) + if (unlikely(atomic_long_inc_return((atomic_long_t *)sem-count) = 0)) rwsem_down_read_failed(sem); } static inline int __down_read_trylock(struct rw_semaphore *sem) { - int tmp; + long tmp; while ((tmp = sem-count) = 0) { if (tmp == cmpxchg(sem-count, tmp, @@ -92,10 +101,10 @@ static inline int __down_read_trylock(struct rw_semaphore *sem) */ static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) { - int tmp; + long tmp; - tmp = atomic_add_return(RWSEM_ACTIVE_WRITE_BIAS, - (atomic_t *)(sem-count)); + tmp = atomic_long_add_return(RWSEM_ACTIVE_WRITE_BIAS, +(atomic_long_t *)sem-count); if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS)) rwsem_down_write_failed(sem); } @@ -107,7 +116,7 @@ static inline void __down_write(struct rw_semaphore *sem) static inline int __down_write_trylock(struct rw_semaphore *sem) { - int tmp; + long tmp; tmp = cmpxchg(sem-count, RWSEM_UNLOCKED_VALUE, RWSEM_ACTIVE_WRITE_BIAS); @@ -119,9 +128,9 @@ static inline int __down_write_trylock(struct rw_semaphore *sem) */ static inline void __up_read(struct rw_semaphore *sem) { - int tmp; + long tmp; - tmp = atomic_dec_return((atomic_t *)(sem-count)); + tmp = atomic_long_dec_return((atomic_long_t *)sem-count); if (unlikely(tmp -1 (tmp RWSEM_ACTIVE_MASK) == 0)) rwsem_wake(sem); } @@ -131,17 +140,17 @@ static inline void
Re: 64-bit ppc rwsem
From: Benjamin Herrenschmidt b...@kernel.crashing.org Date: Thu, 19 Aug 2010 15:23:23 +1000 Similar here, but using atomic_long_t instead so it works for 32-bit too for me. I suppose we could make that part common indeed. What about asm-generic/rwsem-atomic.h or rwsem-cmpxchg.h ? Using rwsem-cmpxchg.h sounds best I guess. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/5] ptp: Added a brand new class driver for ptp clocks.
On Wed, Aug 18, 2010 at 05:12:56PM -0700, john stultz wrote: On Wed, 2010-08-18 at 09:19 +0200, Richard Cochran wrote: The timer/alarm stuff is ancillary and is not at all necessary. It is just a nice to have. I will happily remove it, if it is too troubling for people. If there's a compelling argument for it, I'm interested to hear. But again, it seems like just yet-another-way-to-get-alarm/timer-functionality, so before we add an extra API (or widen an existing API) I'd like to understand the need. We don't really need it, IMHO. But if we offer clockid_t CLOCK_PTP, then we get timer_settime() without any extra effort. I was emulating the posix interface. Instead I should use it directly. I'm definitely interested to see what you come up with here. I'm still hesitant with adding a PTP clock_id, but extending the posix-clocks interface in this way isn't unprecedented (see: CLOCK_SGI_CYCLE) I just would like to make sure we don't end up with a clock_id namespace littered with oddball clocks that were not well abstracted (see: CLOCK_SGI_CYCLE :). For instance: imagine if instead of keeping the clocksource abstraction internal to the timekeeping core, we exposed each clocksource to userland via a clock_id. Every arch would have different ids, and each arch might have multiple ids. Programming against that would be a huge pain. The clockid_t CLOCK_PTP will be arch-neutral. So in thinking about this, try to focus on what the new clock_id provides that the other existing clockids do not? Are they at comparable levels of abstraction? 15 years from now, are folks likely to still be using it? Will it be maintainable? etc... Arnd convinced me that clockid_t=CLOCK_PTP is a good fit. My plan would be to introduce just one additional syscall: SYSCALL_DEFINE3(clock_adjtime, const clockid_t, clkid, int, ppb, struct timespec __user *, ts) ppb - desired frequency adjustment in parts per billion ts - desired time step (or jump) in sec,nsec to correct a measured offset Arguably, this syscall might be useful for other clocks, too. I think the ancillary features from PTP hardware clocks should be made available throught the sysfs. A syscall for these would end up very ugly, looking like an ioctl. Also, it is hard to see how these features relate to the more general idea of the clockid. In contrast, sysfs attributes will fit the need nicely: 1. enable or disable pps 2. enable or disable external timestamps 3. read out external timestamp 4. configure period for periodic output 1. Use Case: SW timestamping The way I tend to see it: PTP is just one of the many ways to sync system time. 2. Use Case: HW timestamping for industrial control These specialized applications are part of what concerns me the most. PTP was not invented to just to get a computer's system time in the ball park. For that, NTP is good enough. Rather, some people want to use their computers for tasks that require close synchronization, like industrial control, audio/video streaming, and many others. Are you saying that we should not support such applications? For example, I can see some parallels between things like audio processing, where you have a buffer consumed by the card at a certain rate. Now, the card has its own crystal it uses to time its consumption, so it has its own time domain, and could drift from system time. Thus you want to trigger buffer-refill interrupts off of the audio card's clock, not the system time which might run the risk of being late. But again, we don't expose the audio hardware clock to userland in the same way we expose system time. This is a good example of the poverty (in regards to time synchronization) of our current systems. Lets say I want to build a surround sound audio system, using a set of distributed computers, each host connected to one speaker. How I can be sure that the samples in one channel (ie one host) pass through the DA converter at exactly the same time? Again, my knowledge in the networking stack is pretty limited. But it would seem that having an interface that does something to the effect of adjust the timestamp clock on the hardware that generated it from this packet by Xppb would feel like the right level of abstraction. Its closely related to SO_TIMESTAMP, option right? Would something like using the setsockopt/getsockopt interface with SO_TIMESTAMP_ADJUST/OFFSET/SET/etc be reasonable? The clock and its adjustment have nothing to do with a network socket. The current PTP hacks floating around all add private ioctls to the MAC driver. That is the *wrong* way to do it. 3. Use Case: HW timestamping with PPS to host ... And yes, this seems perfectly reasonable feature to add. Its not controversial to me, because its likely to work within the existing interfaces and won't expose anything new to userland. Okay, then will you support an elegant solution for case 3, that also supports cases 1 and 2