* Re: [PATCH] of_mmc_spi: add card detect irq support
From: Grant Likely @ 2011-03-08 3:52 UTC (permalink / raw)
To: Anton Vorontsov
Cc: David Brownell, Esben Haabendal, linux-mmc, David Brownell,
Andrew Morton, linuxppc-dev
In-Reply-To: <20101228160526.GA20087@oksana.dev.rtsoft.ru>
On Tue, Dec 28, 2010 at 07:05:26PM +0300, Anton Vorontsov wrote:
> On Mon, Aug 30, 2010 at 11:49:08AM -0600, Grant Likely wrote:
> > On Mon, Aug 30, 2010 at 10:38 AM, David Brownell <david-b@pacbell.net> wrote:
> > > Since I don't do OpenFirmware, let's hear from
> > > Grant on this one.
> >
> > Looks good to me.
> >
> > Acked-by: Grant Likely <grant.likely@secretlab.ca>
>
> I wonder what happened with this patch?
Merged, thanks. :-)
g.
^ permalink raw reply
* Re: [PATCH 01/28] powerpc: mpic irq_data conversion.
From: Grant Likely @ 2011-03-08 4:13 UTC (permalink / raw)
To: Lennert Buytenhek; +Cc: Thomas Gleixner, linuxppc-dev, Stephen Rothwell
In-Reply-To: <20110307235902.GF16649@mail.wantstofly.org>
On Tue, Mar 08, 2011 at 12:59:02AM +0100, Lennert Buytenhek wrote:
> Signed-off-by: Lennert Buytenhek <buytenh@secretlab.ca>
Hi Lennert,
I'm taking a look over now and running some build testing.
However, this needs a wider audience for review before it gets merged.
Can you please repost and cc: benh, sfr, tglx, and linux-kernel?
Thanks,
g.
> ---
> arch/powerpc/include/asm/mpic.h | 6 +-
> arch/powerpc/platforms/pasemi/setup.c | 4 +-
> arch/powerpc/sysdev/mpic.c | 131 +++++++++++++++++----------------
> arch/powerpc/sysdev/mpic.h | 5 +-
> arch/powerpc/sysdev/mpic_pasemi_msi.c | 18 ++--
> arch/powerpc/sysdev/mpic_u3msi.c | 18 ++--
> 6 files changed, 92 insertions(+), 90 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
> index e000cce..946ec49 100644
> --- a/arch/powerpc/include/asm/mpic.h
> +++ b/arch/powerpc/include/asm/mpic.h
> @@ -467,11 +467,11 @@ extern void mpic_request_ipis(void);
> void smp_mpic_message_pass(int target, int msg);
>
> /* Unmask a specific virq */
> -extern void mpic_unmask_irq(unsigned int irq);
> +extern void mpic_unmask_irq(struct irq_data *d);
> /* Mask a specific virq */
> -extern void mpic_mask_irq(unsigned int irq);
> +extern void mpic_mask_irq(struct irq_data *d);
> /* EOI a specific virq */
> -extern void mpic_end_irq(unsigned int irq);
> +extern void mpic_end_irq(struct irq_data *d);
>
> /* Fetch interrupt from a given mpic */
> extern unsigned int mpic_get_one_irq(struct mpic *mpic);
> diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
> index f372ec1..a6067b3 100644
> --- a/arch/powerpc/platforms/pasemi/setup.c
> +++ b/arch/powerpc/platforms/pasemi/setup.c
> @@ -240,7 +240,7 @@ static __init void pas_init_IRQ(void)
> nmi_virq = irq_create_mapping(NULL, *nmiprop);
> mpic_irq_set_priority(nmi_virq, 15);
> set_irq_type(nmi_virq, IRQ_TYPE_EDGE_RISING);
> - mpic_unmask_irq(nmi_virq);
> + mpic_unmask_irq(irq_get_irq_data(nmi_virq));
> }
>
> of_node_put(mpic_node);
> @@ -266,7 +266,7 @@ static int pas_machine_check_handler(struct pt_regs *regs)
> if (nmi_virq != NO_IRQ && mpic_get_mcirq() == nmi_virq) {
> printk(KERN_ERR "NMI delivered\n");
> debugger(regs);
> - mpic_end_irq(nmi_virq);
> + mpic_end_irq(irq_get_irq_data(nmi_virq));
> goto out;
> }
>
> diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
> index b0c8469..95712f6 100644
> --- a/arch/powerpc/sysdev/mpic.c
> +++ b/arch/powerpc/sysdev/mpic.c
> @@ -611,7 +611,7 @@ static struct mpic *mpic_find(unsigned int irq)
> if (irq < NUM_ISA_INTERRUPTS)
> return NULL;
>
> - return irq_to_desc(irq)->chip_data;
> + return get_irq_chip_data(irq);
> }
>
> /* Determine if the linux irq is an IPI */
> @@ -636,16 +636,16 @@ static inline u32 mpic_physmask(u32 cpumask)
>
> #ifdef CONFIG_SMP
> /* Get the mpic structure from the IPI number */
> -static inline struct mpic * mpic_from_ipi(unsigned int ipi)
> +static inline struct mpic * mpic_from_ipi(struct irq_data *d)
> {
> - return irq_to_desc(ipi)->chip_data;
> + return irq_data_get_irq_chip_data(d);
> }
> #endif
>
> /* Get the mpic structure from the irq number */
> static inline struct mpic * mpic_from_irq(unsigned int irq)
> {
> - return irq_to_desc(irq)->chip_data;
> + return get_irq_chip_data(irq);
> }
>
> /* Send an EOI */
> @@ -660,13 +660,13 @@ static inline void mpic_eoi(struct mpic *mpic)
> */
>
>
> -void mpic_unmask_irq(unsigned int irq)
> +void mpic_unmask_irq(struct irq_data *d)
> {
> unsigned int loops = 100000;
> - struct mpic *mpic = mpic_from_irq(irq);
> - unsigned int src = mpic_irq_to_hw(irq);
> + struct mpic *mpic = mpic_from_irq(d->irq);
> + unsigned int src = mpic_irq_to_hw(d->irq);
>
> - DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
> + DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, d->irq, src);
>
> mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
> mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) &
> @@ -681,13 +681,13 @@ void mpic_unmask_irq(unsigned int irq)
> } while(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK);
> }
>
> -void mpic_mask_irq(unsigned int irq)
> +void mpic_mask_irq(struct irq_data *d)
> {
> unsigned int loops = 100000;
> - struct mpic *mpic = mpic_from_irq(irq);
> - unsigned int src = mpic_irq_to_hw(irq);
> + struct mpic *mpic = mpic_from_irq(d->irq);
> + unsigned int src = mpic_irq_to_hw(d->irq);
>
> - DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
> + DBG("%s: disable_irq: %d (src %d)\n", mpic->name, d->irq, src);
>
> mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
> mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) |
> @@ -703,12 +703,12 @@ void mpic_mask_irq(unsigned int irq)
> } while(!(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK));
> }
>
> -void mpic_end_irq(unsigned int irq)
> +void mpic_end_irq(struct irq_data *d)
> {
> - struct mpic *mpic = mpic_from_irq(irq);
> + struct mpic *mpic = mpic_from_irq(d->irq);
>
> #ifdef DEBUG_IRQ
> - DBG("%s: end_irq: %d\n", mpic->name, irq);
> + DBG("%s: end_irq: %d\n", mpic->name, d->irq);
> #endif
> /* We always EOI on end_irq() even for edge interrupts since that
> * should only lower the priority, the MPIC should have properly
> @@ -720,51 +720,51 @@ void mpic_end_irq(unsigned int irq)
>
> #ifdef CONFIG_MPIC_U3_HT_IRQS
>
> -static void mpic_unmask_ht_irq(unsigned int irq)
> +static void mpic_unmask_ht_irq(struct irq_data *d)
> {
> - struct mpic *mpic = mpic_from_irq(irq);
> - unsigned int src = mpic_irq_to_hw(irq);
> + struct mpic *mpic = mpic_from_irq(d->irq);
> + unsigned int src = mpic_irq_to_hw(d->irq);
>
> - mpic_unmask_irq(irq);
> + mpic_unmask_irq(d);
>
> - if (irq_to_desc(irq)->status & IRQ_LEVEL)
> + if (irq_to_desc(d->irq)->status & IRQ_LEVEL)
> mpic_ht_end_irq(mpic, src);
> }
>
> -static unsigned int mpic_startup_ht_irq(unsigned int irq)
> +static unsigned int mpic_startup_ht_irq(struct irq_data *d)
> {
> - struct mpic *mpic = mpic_from_irq(irq);
> - unsigned int src = mpic_irq_to_hw(irq);
> + struct mpic *mpic = mpic_from_irq(d->irq);
> + unsigned int src = mpic_irq_to_hw(d->irq);
>
> - mpic_unmask_irq(irq);
> - mpic_startup_ht_interrupt(mpic, src, irq_to_desc(irq)->status);
> + mpic_unmask_irq(d);
> + mpic_startup_ht_interrupt(mpic, src, irq_to_desc(d->irq)->status);
>
> return 0;
> }
>
> -static void mpic_shutdown_ht_irq(unsigned int irq)
> +static void mpic_shutdown_ht_irq(struct irq_data *d)
> {
> - struct mpic *mpic = mpic_from_irq(irq);
> - unsigned int src = mpic_irq_to_hw(irq);
> + struct mpic *mpic = mpic_from_irq(d->irq);
> + unsigned int src = mpic_irq_to_hw(d->irq);
>
> - mpic_shutdown_ht_interrupt(mpic, src, irq_to_desc(irq)->status);
> - mpic_mask_irq(irq);
> + mpic_shutdown_ht_interrupt(mpic, src, irq_to_desc(d->irq)->status);
> + mpic_mask_irq(d);
> }
>
> -static void mpic_end_ht_irq(unsigned int irq)
> +static void mpic_end_ht_irq(struct irq_data *d)
> {
> - struct mpic *mpic = mpic_from_irq(irq);
> - unsigned int src = mpic_irq_to_hw(irq);
> + struct mpic *mpic = mpic_from_irq(d->irq);
> + unsigned int src = mpic_irq_to_hw(d->irq);
>
> #ifdef DEBUG_IRQ
> - DBG("%s: end_irq: %d\n", mpic->name, irq);
> + DBG("%s: end_irq: %d\n", mpic->name, d->irq);
> #endif
> /* We always EOI on end_irq() even for edge interrupts since that
> * should only lower the priority, the MPIC should have properly
> * latched another edge interrupt coming in anyway
> */
>
> - if (irq_to_desc(irq)->status & IRQ_LEVEL)
> + if (irq_to_desc(d->irq)->status & IRQ_LEVEL)
> mpic_ht_end_irq(mpic, src);
> mpic_eoi(mpic);
> }
> @@ -772,23 +772,23 @@ static void mpic_end_ht_irq(unsigned int irq)
>
> #ifdef CONFIG_SMP
>
> -static void mpic_unmask_ipi(unsigned int irq)
> +static void mpic_unmask_ipi(struct irq_data *d)
> {
> - struct mpic *mpic = mpic_from_ipi(irq);
> - unsigned int src = mpic_irq_to_hw(irq) - mpic->ipi_vecs[0];
> + struct mpic *mpic = mpic_from_ipi(d);
> + unsigned int src = mpic_irq_to_hw(d->irq) - mpic->ipi_vecs[0];
>
> - DBG("%s: enable_ipi: %d (ipi %d)\n", mpic->name, irq, src);
> + DBG("%s: enable_ipi: %d (ipi %d)\n", mpic->name, d->irq, src);
> mpic_ipi_write(src, mpic_ipi_read(src) & ~MPIC_VECPRI_MASK);
> }
>
> -static void mpic_mask_ipi(unsigned int irq)
> +static void mpic_mask_ipi(struct irq_data *d)
> {
> /* NEVER disable an IPI... that's just plain wrong! */
> }
>
> -static void mpic_end_ipi(unsigned int irq)
> +static void mpic_end_ipi(struct irq_data *d)
> {
> - struct mpic *mpic = mpic_from_ipi(irq);
> + struct mpic *mpic = mpic_from_ipi(d);
>
> /*
> * IPIs are marked IRQ_PER_CPU. This has the side effect of
> @@ -802,10 +802,11 @@ static void mpic_end_ipi(unsigned int irq)
>
> #endif /* CONFIG_SMP */
>
> -int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
> +int mpic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
> + bool force)
> {
> - struct mpic *mpic = mpic_from_irq(irq);
> - unsigned int src = mpic_irq_to_hw(irq);
> + struct mpic *mpic = mpic_from_irq(d->irq);
> + unsigned int src = mpic_irq_to_hw(d->irq);
>
> if (mpic->flags & MPIC_SINGLE_DEST_CPU) {
> int cpuid = irq_choose_cpu(cpumask);
> @@ -848,15 +849,15 @@ static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type)
> }
> }
>
> -int mpic_set_irq_type(unsigned int virq, unsigned int flow_type)
> +int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)
> {
> - struct mpic *mpic = mpic_from_irq(virq);
> - unsigned int src = mpic_irq_to_hw(virq);
> - struct irq_desc *desc = irq_to_desc(virq);
> + struct mpic *mpic = mpic_from_irq(d->irq);
> + unsigned int src = mpic_irq_to_hw(d->irq);
> + struct irq_desc *desc = irq_to_desc(d->irq);
> unsigned int vecpri, vold, vnew;
>
> DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n",
> - mpic, virq, src, flow_type);
> + mpic, d->irq, src, flow_type);
>
> if (src >= mpic->irq_count)
> return -EINVAL;
> @@ -907,28 +908,28 @@ void mpic_set_vector(unsigned int virq, unsigned int vector)
> }
>
> static struct irq_chip mpic_irq_chip = {
> - .mask = mpic_mask_irq,
> - .unmask = mpic_unmask_irq,
> - .eoi = mpic_end_irq,
> - .set_type = mpic_set_irq_type,
> + .irq_mask = mpic_mask_irq,
> + .irq_unmask = mpic_unmask_irq,
> + .irq_eoi = mpic_end_irq,
> + .irq_set_type = mpic_set_irq_type,
> };
>
> #ifdef CONFIG_SMP
> static struct irq_chip mpic_ipi_chip = {
> - .mask = mpic_mask_ipi,
> - .unmask = mpic_unmask_ipi,
> - .eoi = mpic_end_ipi,
> + .irq_mask = mpic_mask_ipi,
> + .irq_unmask = mpic_unmask_ipi,
> + .irq_eoi = mpic_end_ipi,
> };
> #endif /* CONFIG_SMP */
>
> #ifdef CONFIG_MPIC_U3_HT_IRQS
> static struct irq_chip mpic_irq_ht_chip = {
> - .startup = mpic_startup_ht_irq,
> - .shutdown = mpic_shutdown_ht_irq,
> - .mask = mpic_mask_irq,
> - .unmask = mpic_unmask_ht_irq,
> - .eoi = mpic_end_ht_irq,
> - .set_type = mpic_set_irq_type,
> + .irq_startup = mpic_startup_ht_irq,
> + .irq_shutdown = mpic_shutdown_ht_irq,
> + .irq_mask = mpic_mask_irq,
> + .irq_unmask = mpic_unmask_ht_irq,
> + .irq_eoi = mpic_end_ht_irq,
> + .irq_set_type = mpic_set_irq_type,
> };
> #endif /* CONFIG_MPIC_U3_HT_IRQS */
>
> @@ -1060,12 +1061,12 @@ struct mpic * __init mpic_alloc(struct device_node *node,
> mpic->hc_irq = mpic_irq_chip;
> mpic->hc_irq.name = name;
> if (flags & MPIC_PRIMARY)
> - mpic->hc_irq.set_affinity = mpic_set_affinity;
> + mpic->hc_irq.irq_set_affinity = mpic_set_affinity;
> #ifdef CONFIG_MPIC_U3_HT_IRQS
> mpic->hc_ht_irq = mpic_irq_ht_chip;
> mpic->hc_ht_irq.name = name;
> if (flags & MPIC_PRIMARY)
> - mpic->hc_ht_irq.set_affinity = mpic_set_affinity;
> + mpic->hc_ht_irq.irq_set_affinity = mpic_set_affinity;
> #endif /* CONFIG_MPIC_U3_HT_IRQS */
>
> #ifdef CONFIG_SMP
> diff --git a/arch/powerpc/sysdev/mpic.h b/arch/powerpc/sysdev/mpic.h
> index e4a6df7..13f3e89 100644
> --- a/arch/powerpc/sysdev/mpic.h
> +++ b/arch/powerpc/sysdev/mpic.h
> @@ -34,9 +34,10 @@ static inline int mpic_pasemi_msi_init(struct mpic *mpic)
> }
> #endif
>
> -extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type);
> +extern int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type);
> extern void mpic_set_vector(unsigned int virq, unsigned int vector);
> -extern int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask);
> +extern int mpic_set_affinity(struct irq_data *d,
> + const struct cpumask *cpumask, bool force);
> extern void mpic_reset_core(int cpu);
>
> #endif /* _POWERPC_SYSDEV_MPIC_H */
> diff --git a/arch/powerpc/sysdev/mpic_pasemi_msi.c b/arch/powerpc/sysdev/mpic_pasemi_msi.c
> index 320ad5a..0b7794a 100644
> --- a/arch/powerpc/sysdev/mpic_pasemi_msi.c
> +++ b/arch/powerpc/sysdev/mpic_pasemi_msi.c
> @@ -43,24 +43,24 @@ static void mpic_pasemi_msi_mask_irq(struct irq_data *data)
> {
> pr_debug("mpic_pasemi_msi_mask_irq %d\n", data->irq);
> mask_msi_irq(data);
> - mpic_mask_irq(data->irq);
> + mpic_mask_irq(data);
> }
>
> static void mpic_pasemi_msi_unmask_irq(struct irq_data *data)
> {
> pr_debug("mpic_pasemi_msi_unmask_irq %d\n", data->irq);
> - mpic_unmask_irq(data->irq);
> + mpic_unmask_irq(data);
> unmask_msi_irq(data);
> }
>
> static struct irq_chip mpic_pasemi_msi_chip = {
> - .irq_shutdown = mpic_pasemi_msi_mask_irq,
> - .irq_mask = mpic_pasemi_msi_mask_irq,
> - .irq_unmask = mpic_pasemi_msi_unmask_irq,
> - .eoi = mpic_end_irq,
> - .set_type = mpic_set_irq_type,
> - .set_affinity = mpic_set_affinity,
> - .name = "PASEMI-MSI",
> + .irq_shutdown = mpic_pasemi_msi_mask_irq,
> + .irq_mask = mpic_pasemi_msi_mask_irq,
> + .irq_unmask = mpic_pasemi_msi_unmask_irq,
> + .irq_eoi = mpic_end_irq,
> + .irq_set_type = mpic_set_irq_type,
> + .irq_set_affinity = mpic_set_affinity,
> + .name = "PASEMI-MSI",
> };
>
> static int pasemi_msi_check_device(struct pci_dev *pdev, int nvec, int type)
> diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c
> index a2b028b..71900ac 100644
> --- a/arch/powerpc/sysdev/mpic_u3msi.c
> +++ b/arch/powerpc/sysdev/mpic_u3msi.c
> @@ -26,23 +26,23 @@ static struct mpic *msi_mpic;
> static void mpic_u3msi_mask_irq(struct irq_data *data)
> {
> mask_msi_irq(data);
> - mpic_mask_irq(data->irq);
> + mpic_mask_irq(data);
> }
>
> static void mpic_u3msi_unmask_irq(struct irq_data *data)
> {
> - mpic_unmask_irq(data->irq);
> + mpic_unmask_irq(data);
> unmask_msi_irq(data);
> }
>
> static struct irq_chip mpic_u3msi_chip = {
> - .irq_shutdown = mpic_u3msi_mask_irq,
> - .irq_mask = mpic_u3msi_mask_irq,
> - .irq_unmask = mpic_u3msi_unmask_irq,
> - .eoi = mpic_end_irq,
> - .set_type = mpic_set_irq_type,
> - .set_affinity = mpic_set_affinity,
> - .name = "MPIC-U3MSI",
> + .irq_shutdown = mpic_u3msi_mask_irq,
> + .irq_mask = mpic_u3msi_mask_irq,
> + .irq_unmask = mpic_u3msi_unmask_irq,
> + .irq_eoi = mpic_end_irq,
> + .irq_set_type = mpic_set_irq_type,
> + .irq_set_affinity = mpic_set_affinity,
> + .name = "MPIC-U3MSI",
> };
>
> static u64 read_ht_magic_addr(struct pci_dev *pdev, unsigned int pos)
> --
> 1.7.4
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
^ permalink raw reply
* Re: Mpc8315erdb openvpn segmentation fault
From: Vasanth Ragavendran @ 2011-03-08 4:28 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <20110307142207.6e879798@schlenkerla>
Thanks a ton Scott. Actually i was working with the same version of the
kernel on both the boards.
it was 2.6.29.6. neither i changed the u-boot. it was the same in both.
however i recompiled the kernel and i installed on both the boards and it
worked fine! :) thanks again for responding. however i've another question.
my filesystem in the board is non-persistent i.e. the files i create are
erased after i reboot i know the files are getting stored in RAM and i wish
to make them persistent. what do i need to do for this? should i create a
separate partition in the flash and load certain files into that partition?
or how should i make it persistent so that files stay beyond reboot! thanks
again! eagerly awaiting your response.
Scott Wood-2 wrote:
>
> On Mon, 7 Mar 2011 03:09:27 -0800
> Vasanth Ragavendran <ragavendrapec@yahoo.co.in> wrote:
>
>>
>> i'm facing a problem. i've installed openvpn on mpc8315erdb board and
>> when i
>> give the command
>>
>> openvpn --mktun --dev tap0 i get the error
>>
>>
>>
>> [root@mpc8315erdb /]# openvpn --mktun --dev tap0
>> Sat Jan 1 01:04:21 2000 OpenVPNUnable to handle kernel paging request
>> for
>> data
>> at address 0x00000000
>> 2.0.9 ppc-rpm-lFaulting instruction address: 0xc90a208c
>> inux-gnu [SSL] [Oops: Kernel access of bad area, sig: 11 [#1]
>> MPC831x RDB
>> Modules linked in: tun
>> **bleep**: c90a208c LR: c90a2068 CTR: c0288e58
>> REGS: c294fd80 TRAP: 0300 Not tainted (2.6.29.6)
>> MSR: 00009032 <EE,ME,IR,DR> CR: 24002424 XER: 20000000
>> DAR: 00000000, DSISR: 20000000
>> TASK = c70b6440[1635] 'openvpn' THREAD: c294e000
>> GPR00: 00000001 c294fe30 c70b6440 c03ebcf4 bfafa0d4 0000001c c294fe58
>> 0fd8dc58
>> GPR08: 00000000 00000001 ffffffe7 00000000 84002428 100787e0 07ff9000
>> 00000004
>> GPR16: 00000000 00000000 bfafa930 00010000 00010000 ffffffff 00000005
>> 3b9aca00
>> GPR24: c7023d20 c294fe3c bfafa0b8 c653e6e0 00000000 c040baf4 bfafa0b8
>> 800454ca
>> Call Trace:
>> [c294fe30] [c90a2068] 0xc90a2068 (unreliable)
>> [c294fe90] [c008054c] 0xc008054c
>> [c294fea0] [c00809c4] 0xc00809c4
>> [c294ff10] [c0080c9c] 0xc0080c9c
>> [c294ff40] [c001141c] 0xc001141c
>> --- Exception: c01 at 0xfce8268
>> LR = 0xfd6bdec
>> Instruction dump:
>> 4bfffecc 9b81001b 480008ed 3d20c90a 38000001 8129306c 81620308 2f890000
>> 830201a4 83ab0014 817d0124 419e0014 <800b0000> 7c090010 7c000110 7c0000d0
>> LZO] [EPOLL] bui---[ end trace 54eee2a93ccf53d1 ]---
>> lt on Mar 2 2011
>> Sat Jan 1 01:04:21 2000 IMPORTANT: OpenVPN's default port number is now
>> 1194, b
>> ased on an official port number assignment by IANA. OpenVPN 2.0-beta16
>> and
>> earl
>> ier used 5000 as the default port.
>> Sat Jan 1 01:04:21 2000 ******* WARNING *******: all encryption and
>> authenticat
>> ion features disabled -- all data will be tunnelled as cleartext
>> Segmentation fault
>>
>>
>>
>> Some one plz help me out! wat does this mean? Coz with the same kernel
>> image
>> and the same settings i'm able to successfully run the above command on
>> another mpc8315erdb board. but it fails on one of the board! any ideas
>> would
>> be of great help to me!! plz!
>
> Please turn on CONFIG_KALLSYMS, so that symbols will be reported in the
> crash dump, and let us know which kernel you're using.
>
> Are the other boards where it does not fail running the same kernel? Same
> userspace? Same U-Boot? Anything else different?
>
> -Scott
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
>
--
View this message in context: http://old.nabble.com/Mpc8315erdb-openvpn-segmentation-fault-tp31086738p31094242.html
Sent from the linuxppc-dev mailing list archive at Nabble.com.
^ permalink raw reply
* Re: [PATCH 28/28] powerpc: Enable GENERIC_HARDIRQS_NO_DEPRECATED.
From: Grant Likely @ 2011-03-08 4:38 UTC (permalink / raw)
To: Lennert Buytenhek; +Cc: Thomas Gleixner, linuxppc-dev, Stephen Rothwell
In-Reply-To: <20110308000023.GG16649@mail.wantstofly.org>
On Tue, Mar 08, 2011 at 01:00:23AM +0100, Lennert Buytenhek wrote:
> Signed-off-by: Lennert Buytenhek <buytenh@secretlab.ca>
All 28 look good to me, it compiles with all the defconfigs I tried,
and it boots on mpc5200. Feel free to add:
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Ben, I've got this series applied against 2.6.38-rc7 in a branch on my
private repo. If you want me to I can push it out to my powerpc/next
branch so that it gets some linux-next exposure.
g.
> ---
> arch/powerpc/Kconfig | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 7d69e9b..71ba047 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -134,6 +134,7 @@ config PPC
> select HAVE_GENERIC_HARDIRQS
> select HAVE_SPARSE_IRQ
> select IRQ_PER_CPU
> + select GENERIC_HARDIRQS_NO_DEPRECATED
>
> config EARLY_PRINTK
> bool
> --
> 1.7.4
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
^ permalink raw reply
* Re: [PATCH 28/28] powerpc: Enable GENERIC_HARDIRQS_NO_DEPRECATED.
From: Benjamin Herrenschmidt @ 2011-03-08 4:48 UTC (permalink / raw)
To: Grant Likely
Cc: Stephen Rothwell, Thomas Gleixner, linuxppc-dev,
Lennert Buytenhek
In-Reply-To: <20110308043858.GC23260@angua.secretlab.ca>
On Mon, 2011-03-07 at 21:38 -0700, Grant Likely wrote:
>
> All 28 look good to me, it compiles with all the defconfigs I tried,
> and it boots on mpc5200. Feel free to add:
>
> Acked-by: Grant Likely <grant.likely@secretlab.ca>
>
> Ben, I've got this series applied against 2.6.38-rc7 in a branch on my
> private repo. If you want me to I can push it out to my powerpc/next
> branch so that it gets some linux-next exposure.
Nah, I'll pick it up, will do some tests first. I'm just finishing some
CPU hotplug fixes/cleanups now and will do that next.
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH 01/28] powerpc: mpic irq_data conversion.
From: Benjamin Herrenschmidt @ 2011-03-08 4:51 UTC (permalink / raw)
To: Grant Likely
Cc: Stephen Rothwell, Thomas Gleixner, linuxppc-dev,
Lennert Buytenhek
In-Reply-To: <20110308041332.GB23260@angua.secretlab.ca>
On Mon, 2011-03-07 at 21:13 -0700, Grant Likely wrote:
> On Tue, Mar 08, 2011 at 12:59:02AM +0100, Lennert Buytenhek wrote:
> > Signed-off-by: Lennert Buytenhek <buytenh@secretlab.ca>
>
> Hi Lennert,
>
> I'm taking a look over now and running some build testing.
>
> However, this needs a wider audience for review before it gets merged.
> Can you please repost and cc: benh, sfr, tglx, and linux-kernel?
No need to re-CC me. I have picked it up from the list and it's on
patchwork.
If Thomas is interested, he can look at patchwork I suppose :-)
Cheers,
Ben.
> Thanks,
> g.
>
> > ---
> > arch/powerpc/include/asm/mpic.h | 6 +-
> > arch/powerpc/platforms/pasemi/setup.c | 4 +-
> > arch/powerpc/sysdev/mpic.c | 131 +++++++++++++++++----------------
> > arch/powerpc/sysdev/mpic.h | 5 +-
> > arch/powerpc/sysdev/mpic_pasemi_msi.c | 18 ++--
> > arch/powerpc/sysdev/mpic_u3msi.c | 18 ++--
> > 6 files changed, 92 insertions(+), 90 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
> > index e000cce..946ec49 100644
> > --- a/arch/powerpc/include/asm/mpic.h
> > +++ b/arch/powerpc/include/asm/mpic.h
> > @@ -467,11 +467,11 @@ extern void mpic_request_ipis(void);
> > void smp_mpic_message_pass(int target, int msg);
> >
> > /* Unmask a specific virq */
> > -extern void mpic_unmask_irq(unsigned int irq);
> > +extern void mpic_unmask_irq(struct irq_data *d);
> > /* Mask a specific virq */
> > -extern void mpic_mask_irq(unsigned int irq);
> > +extern void mpic_mask_irq(struct irq_data *d);
> > /* EOI a specific virq */
> > -extern void mpic_end_irq(unsigned int irq);
> > +extern void mpic_end_irq(struct irq_data *d);
> >
> > /* Fetch interrupt from a given mpic */
> > extern unsigned int mpic_get_one_irq(struct mpic *mpic);
> > diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
> > index f372ec1..a6067b3 100644
> > --- a/arch/powerpc/platforms/pasemi/setup.c
> > +++ b/arch/powerpc/platforms/pasemi/setup.c
> > @@ -240,7 +240,7 @@ static __init void pas_init_IRQ(void)
> > nmi_virq = irq_create_mapping(NULL, *nmiprop);
> > mpic_irq_set_priority(nmi_virq, 15);
> > set_irq_type(nmi_virq, IRQ_TYPE_EDGE_RISING);
> > - mpic_unmask_irq(nmi_virq);
> > + mpic_unmask_irq(irq_get_irq_data(nmi_virq));
> > }
> >
> > of_node_put(mpic_node);
> > @@ -266,7 +266,7 @@ static int pas_machine_check_handler(struct pt_regs *regs)
> > if (nmi_virq != NO_IRQ && mpic_get_mcirq() == nmi_virq) {
> > printk(KERN_ERR "NMI delivered\n");
> > debugger(regs);
> > - mpic_end_irq(nmi_virq);
> > + mpic_end_irq(irq_get_irq_data(nmi_virq));
> > goto out;
> > }
> >
> > diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
> > index b0c8469..95712f6 100644
> > --- a/arch/powerpc/sysdev/mpic.c
> > +++ b/arch/powerpc/sysdev/mpic.c
> > @@ -611,7 +611,7 @@ static struct mpic *mpic_find(unsigned int irq)
> > if (irq < NUM_ISA_INTERRUPTS)
> > return NULL;
> >
> > - return irq_to_desc(irq)->chip_data;
> > + return get_irq_chip_data(irq);
> > }
> >
> > /* Determine if the linux irq is an IPI */
> > @@ -636,16 +636,16 @@ static inline u32 mpic_physmask(u32 cpumask)
> >
> > #ifdef CONFIG_SMP
> > /* Get the mpic structure from the IPI number */
> > -static inline struct mpic * mpic_from_ipi(unsigned int ipi)
> > +static inline struct mpic * mpic_from_ipi(struct irq_data *d)
> > {
> > - return irq_to_desc(ipi)->chip_data;
> > + return irq_data_get_irq_chip_data(d);
> > }
> > #endif
> >
> > /* Get the mpic structure from the irq number */
> > static inline struct mpic * mpic_from_irq(unsigned int irq)
> > {
> > - return irq_to_desc(irq)->chip_data;
> > + return get_irq_chip_data(irq);
> > }
> >
> > /* Send an EOI */
> > @@ -660,13 +660,13 @@ static inline void mpic_eoi(struct mpic *mpic)
> > */
> >
> >
> > -void mpic_unmask_irq(unsigned int irq)
> > +void mpic_unmask_irq(struct irq_data *d)
> > {
> > unsigned int loops = 100000;
> > - struct mpic *mpic = mpic_from_irq(irq);
> > - unsigned int src = mpic_irq_to_hw(irq);
> > + struct mpic *mpic = mpic_from_irq(d->irq);
> > + unsigned int src = mpic_irq_to_hw(d->irq);
> >
> > - DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
> > + DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, d->irq, src);
> >
> > mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
> > mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) &
> > @@ -681,13 +681,13 @@ void mpic_unmask_irq(unsigned int irq)
> > } while(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK);
> > }
> >
> > -void mpic_mask_irq(unsigned int irq)
> > +void mpic_mask_irq(struct irq_data *d)
> > {
> > unsigned int loops = 100000;
> > - struct mpic *mpic = mpic_from_irq(irq);
> > - unsigned int src = mpic_irq_to_hw(irq);
> > + struct mpic *mpic = mpic_from_irq(d->irq);
> > + unsigned int src = mpic_irq_to_hw(d->irq);
> >
> > - DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
> > + DBG("%s: disable_irq: %d (src %d)\n", mpic->name, d->irq, src);
> >
> > mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
> > mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) |
> > @@ -703,12 +703,12 @@ void mpic_mask_irq(unsigned int irq)
> > } while(!(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK));
> > }
> >
> > -void mpic_end_irq(unsigned int irq)
> > +void mpic_end_irq(struct irq_data *d)
> > {
> > - struct mpic *mpic = mpic_from_irq(irq);
> > + struct mpic *mpic = mpic_from_irq(d->irq);
> >
> > #ifdef DEBUG_IRQ
> > - DBG("%s: end_irq: %d\n", mpic->name, irq);
> > + DBG("%s: end_irq: %d\n", mpic->name, d->irq);
> > #endif
> > /* We always EOI on end_irq() even for edge interrupts since that
> > * should only lower the priority, the MPIC should have properly
> > @@ -720,51 +720,51 @@ void mpic_end_irq(unsigned int irq)
> >
> > #ifdef CONFIG_MPIC_U3_HT_IRQS
> >
> > -static void mpic_unmask_ht_irq(unsigned int irq)
> > +static void mpic_unmask_ht_irq(struct irq_data *d)
> > {
> > - struct mpic *mpic = mpic_from_irq(irq);
> > - unsigned int src = mpic_irq_to_hw(irq);
> > + struct mpic *mpic = mpic_from_irq(d->irq);
> > + unsigned int src = mpic_irq_to_hw(d->irq);
> >
> > - mpic_unmask_irq(irq);
> > + mpic_unmask_irq(d);
> >
> > - if (irq_to_desc(irq)->status & IRQ_LEVEL)
> > + if (irq_to_desc(d->irq)->status & IRQ_LEVEL)
> > mpic_ht_end_irq(mpic, src);
> > }
> >
> > -static unsigned int mpic_startup_ht_irq(unsigned int irq)
> > +static unsigned int mpic_startup_ht_irq(struct irq_data *d)
> > {
> > - struct mpic *mpic = mpic_from_irq(irq);
> > - unsigned int src = mpic_irq_to_hw(irq);
> > + struct mpic *mpic = mpic_from_irq(d->irq);
> > + unsigned int src = mpic_irq_to_hw(d->irq);
> >
> > - mpic_unmask_irq(irq);
> > - mpic_startup_ht_interrupt(mpic, src, irq_to_desc(irq)->status);
> > + mpic_unmask_irq(d);
> > + mpic_startup_ht_interrupt(mpic, src, irq_to_desc(d->irq)->status);
> >
> > return 0;
> > }
> >
> > -static void mpic_shutdown_ht_irq(unsigned int irq)
> > +static void mpic_shutdown_ht_irq(struct irq_data *d)
> > {
> > - struct mpic *mpic = mpic_from_irq(irq);
> > - unsigned int src = mpic_irq_to_hw(irq);
> > + struct mpic *mpic = mpic_from_irq(d->irq);
> > + unsigned int src = mpic_irq_to_hw(d->irq);
> >
> > - mpic_shutdown_ht_interrupt(mpic, src, irq_to_desc(irq)->status);
> > - mpic_mask_irq(irq);
> > + mpic_shutdown_ht_interrupt(mpic, src, irq_to_desc(d->irq)->status);
> > + mpic_mask_irq(d);
> > }
> >
> > -static void mpic_end_ht_irq(unsigned int irq)
> > +static void mpic_end_ht_irq(struct irq_data *d)
> > {
> > - struct mpic *mpic = mpic_from_irq(irq);
> > - unsigned int src = mpic_irq_to_hw(irq);
> > + struct mpic *mpic = mpic_from_irq(d->irq);
> > + unsigned int src = mpic_irq_to_hw(d->irq);
> >
> > #ifdef DEBUG_IRQ
> > - DBG("%s: end_irq: %d\n", mpic->name, irq);
> > + DBG("%s: end_irq: %d\n", mpic->name, d->irq);
> > #endif
> > /* We always EOI on end_irq() even for edge interrupts since that
> > * should only lower the priority, the MPIC should have properly
> > * latched another edge interrupt coming in anyway
> > */
> >
> > - if (irq_to_desc(irq)->status & IRQ_LEVEL)
> > + if (irq_to_desc(d->irq)->status & IRQ_LEVEL)
> > mpic_ht_end_irq(mpic, src);
> > mpic_eoi(mpic);
> > }
> > @@ -772,23 +772,23 @@ static void mpic_end_ht_irq(unsigned int irq)
> >
> > #ifdef CONFIG_SMP
> >
> > -static void mpic_unmask_ipi(unsigned int irq)
> > +static void mpic_unmask_ipi(struct irq_data *d)
> > {
> > - struct mpic *mpic = mpic_from_ipi(irq);
> > - unsigned int src = mpic_irq_to_hw(irq) - mpic->ipi_vecs[0];
> > + struct mpic *mpic = mpic_from_ipi(d);
> > + unsigned int src = mpic_irq_to_hw(d->irq) - mpic->ipi_vecs[0];
> >
> > - DBG("%s: enable_ipi: %d (ipi %d)\n", mpic->name, irq, src);
> > + DBG("%s: enable_ipi: %d (ipi %d)\n", mpic->name, d->irq, src);
> > mpic_ipi_write(src, mpic_ipi_read(src) & ~MPIC_VECPRI_MASK);
> > }
> >
> > -static void mpic_mask_ipi(unsigned int irq)
> > +static void mpic_mask_ipi(struct irq_data *d)
> > {
> > /* NEVER disable an IPI... that's just plain wrong! */
> > }
> >
> > -static void mpic_end_ipi(unsigned int irq)
> > +static void mpic_end_ipi(struct irq_data *d)
> > {
> > - struct mpic *mpic = mpic_from_ipi(irq);
> > + struct mpic *mpic = mpic_from_ipi(d);
> >
> > /*
> > * IPIs are marked IRQ_PER_CPU. This has the side effect of
> > @@ -802,10 +802,11 @@ static void mpic_end_ipi(unsigned int irq)
> >
> > #endif /* CONFIG_SMP */
> >
> > -int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
> > +int mpic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
> > + bool force)
> > {
> > - struct mpic *mpic = mpic_from_irq(irq);
> > - unsigned int src = mpic_irq_to_hw(irq);
> > + struct mpic *mpic = mpic_from_irq(d->irq);
> > + unsigned int src = mpic_irq_to_hw(d->irq);
> >
> > if (mpic->flags & MPIC_SINGLE_DEST_CPU) {
> > int cpuid = irq_choose_cpu(cpumask);
> > @@ -848,15 +849,15 @@ static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type)
> > }
> > }
> >
> > -int mpic_set_irq_type(unsigned int virq, unsigned int flow_type)
> > +int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)
> > {
> > - struct mpic *mpic = mpic_from_irq(virq);
> > - unsigned int src = mpic_irq_to_hw(virq);
> > - struct irq_desc *desc = irq_to_desc(virq);
> > + struct mpic *mpic = mpic_from_irq(d->irq);
> > + unsigned int src = mpic_irq_to_hw(d->irq);
> > + struct irq_desc *desc = irq_to_desc(d->irq);
> > unsigned int vecpri, vold, vnew;
> >
> > DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n",
> > - mpic, virq, src, flow_type);
> > + mpic, d->irq, src, flow_type);
> >
> > if (src >= mpic->irq_count)
> > return -EINVAL;
> > @@ -907,28 +908,28 @@ void mpic_set_vector(unsigned int virq, unsigned int vector)
> > }
> >
> > static struct irq_chip mpic_irq_chip = {
> > - .mask = mpic_mask_irq,
> > - .unmask = mpic_unmask_irq,
> > - .eoi = mpic_end_irq,
> > - .set_type = mpic_set_irq_type,
> > + .irq_mask = mpic_mask_irq,
> > + .irq_unmask = mpic_unmask_irq,
> > + .irq_eoi = mpic_end_irq,
> > + .irq_set_type = mpic_set_irq_type,
> > };
> >
> > #ifdef CONFIG_SMP
> > static struct irq_chip mpic_ipi_chip = {
> > - .mask = mpic_mask_ipi,
> > - .unmask = mpic_unmask_ipi,
> > - .eoi = mpic_end_ipi,
> > + .irq_mask = mpic_mask_ipi,
> > + .irq_unmask = mpic_unmask_ipi,
> > + .irq_eoi = mpic_end_ipi,
> > };
> > #endif /* CONFIG_SMP */
> >
> > #ifdef CONFIG_MPIC_U3_HT_IRQS
> > static struct irq_chip mpic_irq_ht_chip = {
> > - .startup = mpic_startup_ht_irq,
> > - .shutdown = mpic_shutdown_ht_irq,
> > - .mask = mpic_mask_irq,
> > - .unmask = mpic_unmask_ht_irq,
> > - .eoi = mpic_end_ht_irq,
> > - .set_type = mpic_set_irq_type,
> > + .irq_startup = mpic_startup_ht_irq,
> > + .irq_shutdown = mpic_shutdown_ht_irq,
> > + .irq_mask = mpic_mask_irq,
> > + .irq_unmask = mpic_unmask_ht_irq,
> > + .irq_eoi = mpic_end_ht_irq,
> > + .irq_set_type = mpic_set_irq_type,
> > };
> > #endif /* CONFIG_MPIC_U3_HT_IRQS */
> >
> > @@ -1060,12 +1061,12 @@ struct mpic * __init mpic_alloc(struct device_node *node,
> > mpic->hc_irq = mpic_irq_chip;
> > mpic->hc_irq.name = name;
> > if (flags & MPIC_PRIMARY)
> > - mpic->hc_irq.set_affinity = mpic_set_affinity;
> > + mpic->hc_irq.irq_set_affinity = mpic_set_affinity;
> > #ifdef CONFIG_MPIC_U3_HT_IRQS
> > mpic->hc_ht_irq = mpic_irq_ht_chip;
> > mpic->hc_ht_irq.name = name;
> > if (flags & MPIC_PRIMARY)
> > - mpic->hc_ht_irq.set_affinity = mpic_set_affinity;
> > + mpic->hc_ht_irq.irq_set_affinity = mpic_set_affinity;
> > #endif /* CONFIG_MPIC_U3_HT_IRQS */
> >
> > #ifdef CONFIG_SMP
> > diff --git a/arch/powerpc/sysdev/mpic.h b/arch/powerpc/sysdev/mpic.h
> > index e4a6df7..13f3e89 100644
> > --- a/arch/powerpc/sysdev/mpic.h
> > +++ b/arch/powerpc/sysdev/mpic.h
> > @@ -34,9 +34,10 @@ static inline int mpic_pasemi_msi_init(struct mpic *mpic)
> > }
> > #endif
> >
> > -extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type);
> > +extern int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type);
> > extern void mpic_set_vector(unsigned int virq, unsigned int vector);
> > -extern int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask);
> > +extern int mpic_set_affinity(struct irq_data *d,
> > + const struct cpumask *cpumask, bool force);
> > extern void mpic_reset_core(int cpu);
> >
> > #endif /* _POWERPC_SYSDEV_MPIC_H */
> > diff --git a/arch/powerpc/sysdev/mpic_pasemi_msi.c b/arch/powerpc/sysdev/mpic_pasemi_msi.c
> > index 320ad5a..0b7794a 100644
> > --- a/arch/powerpc/sysdev/mpic_pasemi_msi.c
> > +++ b/arch/powerpc/sysdev/mpic_pasemi_msi.c
> > @@ -43,24 +43,24 @@ static void mpic_pasemi_msi_mask_irq(struct irq_data *data)
> > {
> > pr_debug("mpic_pasemi_msi_mask_irq %d\n", data->irq);
> > mask_msi_irq(data);
> > - mpic_mask_irq(data->irq);
> > + mpic_mask_irq(data);
> > }
> >
> > static void mpic_pasemi_msi_unmask_irq(struct irq_data *data)
> > {
> > pr_debug("mpic_pasemi_msi_unmask_irq %d\n", data->irq);
> > - mpic_unmask_irq(data->irq);
> > + mpic_unmask_irq(data);
> > unmask_msi_irq(data);
> > }
> >
> > static struct irq_chip mpic_pasemi_msi_chip = {
> > - .irq_shutdown = mpic_pasemi_msi_mask_irq,
> > - .irq_mask = mpic_pasemi_msi_mask_irq,
> > - .irq_unmask = mpic_pasemi_msi_unmask_irq,
> > - .eoi = mpic_end_irq,
> > - .set_type = mpic_set_irq_type,
> > - .set_affinity = mpic_set_affinity,
> > - .name = "PASEMI-MSI",
> > + .irq_shutdown = mpic_pasemi_msi_mask_irq,
> > + .irq_mask = mpic_pasemi_msi_mask_irq,
> > + .irq_unmask = mpic_pasemi_msi_unmask_irq,
> > + .irq_eoi = mpic_end_irq,
> > + .irq_set_type = mpic_set_irq_type,
> > + .irq_set_affinity = mpic_set_affinity,
> > + .name = "PASEMI-MSI",
> > };
> >
> > static int pasemi_msi_check_device(struct pci_dev *pdev, int nvec, int type)
> > diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c
> > index a2b028b..71900ac 100644
> > --- a/arch/powerpc/sysdev/mpic_u3msi.c
> > +++ b/arch/powerpc/sysdev/mpic_u3msi.c
> > @@ -26,23 +26,23 @@ static struct mpic *msi_mpic;
> > static void mpic_u3msi_mask_irq(struct irq_data *data)
> > {
> > mask_msi_irq(data);
> > - mpic_mask_irq(data->irq);
> > + mpic_mask_irq(data);
> > }
> >
> > static void mpic_u3msi_unmask_irq(struct irq_data *data)
> > {
> > - mpic_unmask_irq(data->irq);
> > + mpic_unmask_irq(data);
> > unmask_msi_irq(data);
> > }
> >
> > static struct irq_chip mpic_u3msi_chip = {
> > - .irq_shutdown = mpic_u3msi_mask_irq,
> > - .irq_mask = mpic_u3msi_mask_irq,
> > - .irq_unmask = mpic_u3msi_unmask_irq,
> > - .eoi = mpic_end_irq,
> > - .set_type = mpic_set_irq_type,
> > - .set_affinity = mpic_set_affinity,
> > - .name = "MPIC-U3MSI",
> > + .irq_shutdown = mpic_u3msi_mask_irq,
> > + .irq_mask = mpic_u3msi_mask_irq,
> > + .irq_unmask = mpic_u3msi_unmask_irq,
> > + .irq_eoi = mpic_end_irq,
> > + .irq_set_type = mpic_set_irq_type,
> > + .irq_set_affinity = mpic_set_affinity,
> > + .name = "MPIC-U3MSI",
> > };
> >
> > static u64 read_ht_magic_addr(struct pci_dev *pdev, unsigned int pos)
> > --
> > 1.7.4
> >
> > _______________________________________________
> > Linuxppc-dev mailing list
> > Linuxppc-dev@lists.ozlabs.org
> > https://lists.ozlabs.org/listinfo/linuxppc-dev
^ permalink raw reply
* Re: [PATCH] powerpc: disable MSI using new interface if possible
From: Nishanth Aravamudan @ 2011-03-08 5:34 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, paulus, miltonm
In-Reply-To: <20110304072444.GA2080@us.ibm.com>
On 03.03.2011 [23:24:44 -0800], Nishanth Aravamudan wrote:
> On 04.03.2011 [14:01:24 +1100], Michael Ellerman wrote:
> > On Thu, 2011-03-03 at 17:41 -0800, Nishanth Aravamudan wrote:
> > > On 04.03.2011 [12:05:29 +1100], Michael Ellerman wrote:
> > > > On Thu, 2011-03-03 at 11:39 -0800, Nishanth Aravamudan wrote:
> > > > > On upcoming hardware, we have a PCI adapter with two functions, one of
> > > > > which uses MSI and the other uses MSI-X. This adapter, when MSI is
> > > > > disabled using the "old" firmware interface (RTAS_CHANGE_FN), still
> > > > > signals an MSI-X interrupt and triggers an EEH. We are working with the
> > > > > vendor to ensure that the hardware is not at fault, but if we use the
> > > > > "new" interface (RTAS_CHANGE_MSI_FN) to disable MSI, we also
> > > > > automatically disable MSI-X and the adapter does not appear to signal
> > > > > any stray MSI-X interrupt.
> > > >
> > > > It seems this could also be a firmware bug, have we heard anything from
> > > > them? PAPR explicitly says that RTAS_CHANGE_FN (function=1) should
> > > > disable MSI _and_ MSI-X (R1???7.3.10.5.1???1).
> > >
> > > We're tracking that down too. I think the fact that the interrupt is
> > > coming in is a hardware bug in this particular adapter.
> > >
> > > I'm looking at PAPR again and I see what might be a contradiction:
> > >
> > > 7.3.10.5.1: "To removing all MSIs, set the Requested Number of
> > > Interrupts to zero."
> > >
> > > Table 71: "Function ... 1: Request to set to a new number of MSI or
> > > MSI-X (platform choice) interrupts (including set to 0)"
> > >
> > > It seems like the Table claims that using RTAS_CHANGE_FN with 0, could
> > > change only MSI or MSI-X and still be not a bug?
> >
> > Yeah I guess you could read it that way, though I think that would be a
> > bug.
> >
> > The idea is that it chooses for you whether it uses MSI or MSI-X. So the
> > only sane semantic is that when deconfiguring it deconfigures either,
> > ie. both, kinds.
>
> I agree with you that is how it should be :) I'm asking the firmware
> folks to make sure I'm not misunderstanding the underlying issue.
It would appear that if a device does support both MSI and MSI-X and the
old (non-explicit) interface is used, only one of MSI or MSI-X is
guaranteed to be disabled, with preference given to MSI. Now, it turns
out that there is also a firmware dragon here (because this particular
device is misbehaving), but we can also fix it by using the new
interface, which shouldn't cause any harm, given the fallback.
> > Looking closer at your patch, now I don't understand :)
> >
> > + /*
> > + * disabling MSI with the explicit interface also disables MSI-X
> > + */
> > + if (rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, 0) != 0) {
> >
> >
> > So we first disable using function 3, which should:
> >
> > 3: Request to set to a new number of MSI interrupts (including set to 0)
> >
> > Which does not mention MSI-X at all, implying it has no effect on them.
> > Which contradicts what you see, and the comment in the code?
>
> Thanks for the thorough review!
>
> Per PAPR 2.4 from Power.org, look at the page before that table, page
> 169:
>
> "Specifying Function 3 (MSI) also disables MSI-X for the specified IOA
> function, and likewise specifying Function 4 (MSI-X) disables MSI for
> the IOA function....Specifying the Requested Number of Interrupts to
> zero for either Function 3 or 4 removes all MSI & MSI-X interrupts from
> the IOA function."
>
> So I'm relying on this aspect of PAPR being enforced by the firmware,
> which I think it is in my testing.
Given all that, do I have your Ack? :)
Thanks,
Nish
--
Nishanth Aravamudan <nacc@us.ibm.com>
IBM Linux Technology Center
^ permalink raw reply
* [PATCH 03/18] powerpc/smp: Fix generic_mach_cpu_die()
From: Benjamin Herrenschmidt @ 2011-03-08 6:37 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1299566250-10516-1-git-send-email-benh@kernel.crashing.org>
This is used by some "soft" hotplug implementations. I needs to
call idle_task_exit() when the CPU is going away, and we remove
the now no-longer needed set_cpu_online() and local_irq_enable()
which are handled by the return to start_secondary
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/kernel/smp.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 1c9956c..3c0fab5 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -362,14 +362,13 @@ void generic_mach_cpu_die(void)
unsigned int cpu;
local_irq_disable();
+ idle_task_exit();
cpu = smp_processor_id();
printk(KERN_DEBUG "CPU%d offline\n", cpu);
__get_cpu_var(cpu_state) = CPU_DEAD;
smp_wmb();
while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
cpu_relax();
- set_cpu_online(cpu, true);
- local_irq_enable();
}
#endif
--
1.7.1
^ permalink raw reply related
* [PATCH 08/18] powerpc/pmac/smp: Fixup smp_core99_cpu_disable() and use it on 64-bit
From: Benjamin Herrenschmidt @ 2011-03-08 6:37 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1299566250-10516-1-git-send-email-benh@kernel.crashing.org>
Use the generic code, just add the MPIC priority setting,
I don't see any use in mucking around with the decrementer,
as 32-bit will have EE off all along, and 64-bit will be able
to deal with it.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/platforms/powermac/smp.c | 17 +++++------------
1 files changed, 5 insertions(+), 12 deletions(-)
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index e0ac7bb..eda4709 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -867,16 +867,14 @@ static void __devinit smp_core99_setup_cpu(int cpu_nr)
#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
-int smp_core99_cpu_disable(void)
+static int smp_core99_cpu_disable(void)
{
- set_cpu_online(smp_processor_id(), false);
+ int rc = generic_cpu_disable();
+ if (rc)
+ return rc;
- /* XXX reset cpu affinity here */
mpic_cpu_set_priority(0xf);
- asm volatile("mtdec %0" : : "r" (0x7fffffff));
- mb();
- udelay(20);
- asm volatile("mtdec %0" : : "r" (0x7fffffff));
+
return 0;
}
@@ -902,12 +900,7 @@ struct smp_ops_t core99_smp_ops = {
.give_timebase = smp_core99_give_timebase,
.take_timebase = smp_core99_take_timebase,
#if defined(CONFIG_HOTPLUG_CPU)
-# if defined(CONFIG_PPC32)
.cpu_disable = smp_core99_cpu_disable,
-# endif
-# if defined(CONFIG_PPC64)
- .cpu_disable = generic_cpu_disable,
-# endif
.cpu_die = generic_cpu_die,
#endif
};
--
1.7.1
^ permalink raw reply related
* [PATCH 05/18] powerpc/smp: Remove unused smp_ops->cpu_enable()
From: Benjamin Herrenschmidt @ 2011-03-08 6:37 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1299566250-10516-1-git-send-email-benh@kernel.crashing.org>
Remove the last remnants of cpu_enable(), everybody uses the normal
__cpu_up() path now
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/include/asm/machdep.h | 1 -
arch/powerpc/kernel/smp.c | 10 ----------
arch/powerpc/platforms/powermac/smp.c | 2 --
3 files changed, 0 insertions(+), 13 deletions(-)
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index fe56a23..bcfc0da 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -37,7 +37,6 @@ struct smp_ops_t {
void (*setup_cpu)(int nr);
void (*take_timebase)(void);
void (*give_timebase)(void);
- int (*cpu_enable)(unsigned int nr);
int (*cpu_disable)(void);
void (*cpu_die)(unsigned int nr);
int (*cpu_bootable)(unsigned int nr);
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 19d0c25..be7d728 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -350,21 +350,11 @@ void generic_mach_cpu_die(void)
}
#endif
-static int __devinit cpu_enable(unsigned int cpu)
-{
- if (smp_ops && smp_ops->cpu_enable)
- return smp_ops->cpu_enable(cpu);
-
- return -ENOSYS;
-}
-
int __cpuinit __cpu_up(unsigned int cpu)
{
int c;
secondary_ti = current_set[cpu];
- if (!cpu_enable(cpu))
- return 0;
if (smp_ops == NULL ||
(smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)))
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index c95215f..ebd2b7e 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -923,8 +923,6 @@ struct smp_ops_t core99_smp_ops = {
# if defined(CONFIG_PPC64)
.cpu_disable = generic_cpu_disable,
.cpu_die = generic_cpu_die,
- /* intentionally do *NOT* assign cpu_enable,
- * the generic code will use kick_cpu then! */
# endif
#endif
};
--
1.7.1
^ permalink raw reply related
* [PATCH 04/18] powerpc/smp: Remove unused generic_cpu_enable()
From: Benjamin Herrenschmidt @ 2011-03-08 6:37 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1299566250-10516-1-git-send-email-benh@kernel.crashing.org>
Nobody uses it, besides we should always use the normal __cpu_up
path anyways
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/include/asm/smp.h | 1 -
arch/powerpc/kernel/smp.c | 22 ----------------------
2 files changed, 0 insertions(+), 23 deletions(-)
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 1de0e97..a629b6f 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -43,7 +43,6 @@ DECLARE_PER_CPU(unsigned int, cpu_pvr);
#ifdef CONFIG_HOTPLUG_CPU
extern void fixup_irqs(const struct cpumask *map);
int generic_cpu_disable(void);
-int generic_cpu_enable(unsigned int cpu);
void generic_cpu_die(unsigned int cpu);
void generic_mach_cpu_die(void);
#endif
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 3c0fab5..19d0c25 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -322,28 +322,6 @@ int generic_cpu_disable(void)
return 0;
}
-int generic_cpu_enable(unsigned int cpu)
-{
- /* Do the normal bootup if we haven't
- * already bootstrapped. */
- if (system_state != SYSTEM_RUNNING)
- return -ENOSYS;
-
- /* get the target out of it's holding state */
- per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
- smp_wmb();
-
- while (!cpu_online(cpu))
- cpu_relax();
-
-#ifdef CONFIG_PPC64
- fixup_irqs(cpu_online_mask);
- /* counter the irq disable in fixup_irqs */
- local_irq_enable();
-#endif
- return 0;
-}
-
void generic_cpu_die(unsigned int cpu)
{
int i;
--
1.7.1
^ permalink raw reply related
* [PATCH 01/18] powerpc: Make decrementer interrupt robust against offlined CPUs
From: Benjamin Herrenschmidt @ 2011-03-08 6:37 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1299566250-10516-1-git-send-email-benh@kernel.crashing.org>
With some implementations, it is possible that a timer interrupt
occurs every few seconds on an offline CPU. In this case, just
re-arm the decrementer and return immediately
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/kernel/time.c | 15 +++++++++++----
1 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 09d31db..ecebc7c 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -577,14 +577,21 @@ void timer_interrupt(struct pt_regs * regs)
struct clock_event_device *evt = &decrementer->event;
u64 now;
+ /* Ensure a positive value is written to the decrementer, or else
+ * some CPUs will continuue to take decrementer exceptions
+ */
+ set_dec(DECREMENTER_MAX);
+
+ /* Some implementations of hotplug will get timer interrupts while
+ * offline, just ignore these
+ */
+ if (!cpu_online(smp_processor_id()))
+ return;
+
trace_timer_interrupt_entry(regs);
__get_cpu_var(irq_stat).timer_irqs++;
- /* Ensure a positive value is written to the decrementer, or else
- * some CPUs will continuue to take decrementer exceptions */
- set_dec(DECREMENTER_MAX);
-
#if defined(CONFIG_PPC32) && defined(CONFIG_PMAC)
if (atomic_read(&ppc_n_lost_interrupts) != 0)
do_IRQ(regs);
--
1.7.1
^ permalink raw reply related
* [PATCH 09/18] powerpc/pmac/smp: Consolidate 32-bit and 64-bit PowerMac cpu_die in one file
From: Benjamin Herrenschmidt @ 2011-03-08 6:37 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1299566250-10516-1-git-send-email-benh@kernel.crashing.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/platforms/powermac/pmac.h | 1 -
arch/powerpc/platforms/powermac/setup.c | 56 -----------------------------
arch/powerpc/platforms/powermac/smp.c | 58 +++++++++++++++++++++++++++++--
3 files changed, 55 insertions(+), 60 deletions(-)
diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h
index f0bc08f..20468f4 100644
--- a/arch/powerpc/platforms/powermac/pmac.h
+++ b/arch/powerpc/platforms/powermac/pmac.h
@@ -33,7 +33,6 @@ extern void pmac_setup_pci_dma(void);
extern void pmac_check_ht_link(void);
extern void pmac_setup_smp(void);
-extern void pmac32_cpu_die(void);
extern void low_cpu_die(void) __attribute__((noreturn));
extern int pmac_nvram_init(void);
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index d5aceb7..aa45281 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -650,51 +650,6 @@ static int pmac_pci_probe_mode(struct pci_bus *bus)
return PCI_PROBE_NORMAL;
return PCI_PROBE_DEVTREE;
}
-
-#ifdef CONFIG_HOTPLUG_CPU
-/* access per cpu vars from generic smp.c */
-DECLARE_PER_CPU(int, cpu_state);
-
-static void pmac64_cpu_die(void)
-{
- /*
- * turn off as much as possible, we'll be
- * kicked out as this will only be invoked
- * on core99 platforms for now ...
- */
-
- printk(KERN_INFO "CPU#%d offline\n", smp_processor_id());
- __get_cpu_var(cpu_state) = CPU_DEAD;
- smp_wmb();
-
- /*
- * during the path that leads here preemption is disabled,
- * reenable it now so that when coming up preempt count is
- * zero correctly
- */
- preempt_enable();
-
- /*
- * hard-disable interrupts for the non-NAP case, the NAP code
- * needs to re-enable interrupts (but soft-disables them)
- */
- hard_irq_disable();
-
- while (1) {
- /* let's not take timer interrupts too often ... */
- set_dec(0x7fffffff);
-
- /* should always be true at this point */
- if (cpu_has_feature(CPU_FTR_CAN_NAP))
- power4_cpu_offline_powersave();
- else {
- HMT_low();
- HMT_very_low();
- }
- }
-}
-#endif /* CONFIG_HOTPLUG_CPU */
-
#endif /* CONFIG_PPC64 */
define_machine(powermac) {
@@ -726,15 +681,4 @@ define_machine(powermac) {
.pcibios_after_init = pmac_pcibios_after_init,
.phys_mem_access_prot = pci_phys_mem_access_prot,
#endif
-#ifdef CONFIG_HOTPLUG_CPU
-#ifdef CONFIG_PPC64
- .cpu_die = pmac64_cpu_die,
-#endif
-#ifdef CONFIG_PPC32
- .cpu_die = pmac32_cpu_die,
-#endif
-#endif
-#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
- .cpu_die = generic_mach_cpu_die,
-#endif
};
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index eda4709..50e15b4 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -865,7 +865,7 @@ static void __devinit smp_core99_setup_cpu(int cpu_nr)
}
-#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
+#ifdef CONFIG_HOTPLUG_CPU
static int smp_core99_cpu_disable(void)
{
@@ -878,7 +878,9 @@ static int smp_core99_cpu_disable(void)
return 0;
}
-void pmac32_cpu_die(void)
+#ifdef CONFIG_PPC32
+
+static void pmac_cpu_die(void)
{
local_irq_disable();
idle_task_exit();
@@ -889,7 +891,52 @@ void pmac32_cpu_die(void)
low_cpu_die();
}
-#endif /* CONFIG_HOTPLUG_CPU && CONFIG_PP32 */
+#else /* CONFIG_PPC32 */
+
+static void pmac_cpu_die(void)
+{
+ local_irq_disable();
+ idle_task_exit();
+
+ /*
+ * turn off as much as possible, we'll be
+ * kicked out as this will only be invoked
+ * on core99 platforms for now ...
+ */
+
+ printk(KERN_INFO "CPU#%d offline\n", smp_processor_id());
+ __get_cpu_var(cpu_state) = CPU_DEAD;
+ smp_wmb();
+
+ /*
+ * during the path that leads here preemption is disabled,
+ * reenable it now so that when coming up preempt count is
+ * zero correctly
+ */
+ preempt_enable();
+
+ /*
+ * hard-disable interrupts for the non-NAP case, the NAP code
+ * needs to re-enable interrupts (but soft-disables them)
+ */
+ hard_irq_disable();
+
+ while (1) {
+ /* let's not take timer interrupts too often ... */
+ set_dec(0x7fffffff);
+
+ /* should always be true at this point */
+ if (cpu_has_feature(CPU_FTR_CAN_NAP))
+ power4_cpu_offline_powersave();
+ else {
+ HMT_low();
+ HMT_very_low();
+ }
+ }
+}
+
+#endif /* else CONFIG_PPC32 */
+#endif /* CONFIG_HOTPLUG_CPU */
/* Core99 Macs (dual G4s and G5s) */
struct smp_ops_t core99_smp_ops = {
@@ -933,5 +980,10 @@ void __init pmac_setup_smp(void)
smp_ops = &psurge_smp_ops;
}
#endif /* CONFIG_PPC32 */
+
+#ifdef CONFIG_HOTPLUG_CPU
+ ppc_md.cpu_die = pmac_cpu_die;
+#endif
}
+
--
1.7.1
^ permalink raw reply related
* [PATCH 06/18] powerpc/pmac/smp: Fix 32-bit PowerMac cpu_die
From: Benjamin Herrenschmidt @ 2011-03-08 6:37 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1299566250-10516-1-git-send-email-benh@kernel.crashing.org>
Use generic cpu_state, call idle_task_exit() properly, and
remove smp_core99_cpu_die() which isn't useful, the generic
function does the job just fine.
---
arch/powerpc/include/asm/smp.h | 1 +
arch/powerpc/platforms/powermac/smp.c | 25 +++++--------------------
2 files changed, 6 insertions(+), 20 deletions(-)
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index a629b6f..9fe5597 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -45,6 +45,7 @@ extern void fixup_irqs(const struct cpumask *map);
int generic_cpu_disable(void);
void generic_cpu_die(unsigned int cpu);
void generic_mach_cpu_die(void);
+DECLARE_PER_CPU(int, cpu_state);
#endif
#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index ebd2b7e..e0ac7bb 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -880,31 +880,17 @@ int smp_core99_cpu_disable(void)
return 0;
}
-static int cpu_dead[NR_CPUS];
-
void pmac32_cpu_die(void)
{
local_irq_disable();
- cpu_dead[smp_processor_id()] = 1;
+ idle_task_exit();
+ printk(KERN_DEBUG "CPU%d offline\n", smp_processor_id());
+ __get_cpu_var(cpu_state) = CPU_DEAD;
+ smp_wmb();
mb();
low_cpu_die();
}
-void smp_core99_cpu_die(unsigned int cpu)
-{
- int timeout;
-
- timeout = 1000;
- while (!cpu_dead[cpu]) {
- if (--timeout == 0) {
- printk("CPU %u refused to die!\n", cpu);
- break;
- }
- msleep(1);
- }
- cpu_dead[cpu] = 0;
-}
-
#endif /* CONFIG_HOTPLUG_CPU && CONFIG_PP32 */
/* Core99 Macs (dual G4s and G5s) */
@@ -918,12 +904,11 @@ struct smp_ops_t core99_smp_ops = {
#if defined(CONFIG_HOTPLUG_CPU)
# if defined(CONFIG_PPC32)
.cpu_disable = smp_core99_cpu_disable,
- .cpu_die = smp_core99_cpu_die,
# endif
# if defined(CONFIG_PPC64)
.cpu_disable = generic_cpu_disable,
- .cpu_die = generic_cpu_die,
# endif
+ .cpu_die = generic_cpu_die,
#endif
};
--
1.7.1
^ permalink raw reply related
* [PATCH 07/18] powerpc/pmac/smp: Rename fixup_irqs() to migrate_irqs() and use it on ppc32
From: Benjamin Herrenschmidt @ 2011-03-08 6:37 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1299566250-10516-1-git-send-email-benh@kernel.crashing.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/include/asm/smp.h | 2 +-
arch/powerpc/kernel/irq.c | 3 ++-
arch/powerpc/kernel/smp.c | 2 +-
3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 9fe5597..7e99771 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -41,7 +41,7 @@ extern void start_secondary_resume(void);
DECLARE_PER_CPU(unsigned int, cpu_pvr);
#ifdef CONFIG_HOTPLUG_CPU
-extern void fixup_irqs(const struct cpumask *map);
+extern void migrate_irqs(void);
int generic_cpu_disable(void);
void generic_cpu_die(unsigned int cpu);
void generic_mach_cpu_die(void);
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index ce557f6..cab8654 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -303,12 +303,13 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
}
#ifdef CONFIG_HOTPLUG_CPU
-void fixup_irqs(const struct cpumask *map)
+void migrate_irqs(void)
{
struct irq_desc *desc;
unsigned int irq;
static int warned;
cpumask_var_t mask;
+ const struct cpumask *map = cpu_online_mask;
alloc_cpumask_var(&mask, GFP_KERNEL);
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index be7d728..f6cc5c1 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -317,8 +317,8 @@ int generic_cpu_disable(void)
set_cpu_online(cpu, false);
#ifdef CONFIG_PPC64
vdso_data->processorCount--;
- fixup_irqs(cpu_online_mask);
#endif
+ migrate_irqs();
return 0;
}
--
1.7.1
^ permalink raw reply related
* [PATCH 02/18] powerpc/smp: soft-replugged CPUs must go back to start_secondary
From: Benjamin Herrenschmidt @ 2011-03-08 6:37 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1299566250-10516-1-git-send-email-benh@kernel.crashing.org>
Various thing are torn down when a CPU is hot-unplugged. That CPU
is expected to go back to start_secondary when re-plugged to re
initialize everything, such as clock sources, maps, ...
Some implementations just return from cpu_die() callback
in the idle loop when the CPU is "re-plugged". This is not enough.
We fix it using a little asm trampoline which resets the stack
and calls back into start_secondary as if we were all fresh from
boot. The trampoline already existed on ppc64, but we add it for
ppc32
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/include/asm/smp.h | 1 +
arch/powerpc/kernel/head_32.S | 9 +++++++++
arch/powerpc/kernel/smp.c | 9 +++++++--
arch/powerpc/platforms/pseries/offline_states.h | 2 --
4 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 66e237b..1de0e97 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -36,6 +36,7 @@ extern void cpu_die(void);
extern void smp_send_debugger_break(int cpu);
extern void smp_message_recv(int);
+extern void start_secondary_resume(void);
DECLARE_PER_CPU(unsigned int, cpu_pvr);
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index 98c4b29..c5c24be 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -890,6 +890,15 @@ __secondary_start:
mtspr SPRN_SRR1,r4
SYNC
RFI
+
+_GLOBAL(start_secondary_resume)
+ /* Reset stack */
+ rlwinm r1,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
+ addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
+ li r3,0
+ std r3,0(r1) /* Zero the stack frame pointer */
+ bl start_secondary
+ b .
#endif /* CONFIG_SMP */
#ifdef CONFIG_KVM_BOOK3S_HANDLER
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 9813605..1c9956c 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -502,7 +502,7 @@ static struct device_node *cpu_to_l2cache(int cpu)
}
/* Activate a secondary processor. */
-int __devinit start_secondary(void *unused)
+void __devinit start_secondary(void *unused)
{
unsigned int cpu = smp_processor_id();
struct device_node *l2_cache;
@@ -558,7 +558,8 @@ int __devinit start_secondary(void *unused)
local_irq_enable();
cpu_idle();
- return 0;
+
+ BUG();
}
int setup_profiling_timer(unsigned int multiplier)
@@ -660,5 +661,9 @@ void cpu_die(void)
{
if (ppc_md.cpu_die)
ppc_md.cpu_die();
+
+ /* If we return, we re-enter start_secondary */
+ start_secondary_resume();
}
+
#endif
diff --git a/arch/powerpc/platforms/pseries/offline_states.h b/arch/powerpc/platforms/pseries/offline_states.h
index 75a6f48..08672d9 100644
--- a/arch/powerpc/platforms/pseries/offline_states.h
+++ b/arch/powerpc/platforms/pseries/offline_states.h
@@ -34,6 +34,4 @@ static inline void set_default_offline_state(int cpu)
#endif
extern enum cpu_state_vals get_preferred_offline_state(int cpu);
-extern int start_secondary(void);
-extern void start_secondary_resume(void);
#endif
--
1.7.1
^ permalink raw reply related
* [PATCH 15/18] powerpc/smp: Don't expose per-cpu "cpu_state" array
From: Benjamin Herrenschmidt @ 2011-03-08 6:37 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1299566250-10516-1-git-send-email-benh@kernel.crashing.org>
Instead, keep it static, expose an accessor and use that from
the PowerMac code. Avoids easy namespace collisions and will
make it easier to consolidate with other implementations.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/include/asm/smp.h | 2 +-
arch/powerpc/kernel/smp.c | 7 ++++++-
arch/powerpc/platforms/powermac/smp.c | 12 ++++++++----
3 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 7e99771..a902a0d 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -45,7 +45,7 @@ extern void migrate_irqs(void);
int generic_cpu_disable(void);
void generic_cpu_die(unsigned int cpu);
void generic_mach_cpu_die(void);
-DECLARE_PER_CPU(int, cpu_state);
+void generic_set_cpu_dead(unsigned int cpu);
#endif
#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index df37397..7beb001 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -305,7 +305,7 @@ void __devinit smp_prepare_boot_cpu(void)
#ifdef CONFIG_HOTPLUG_CPU
/* State of each CPU during hotplug phases */
-DEFINE_PER_CPU(int, cpu_state) = { 0 };
+static DEFINE_PER_CPU(int, cpu_state) = { 0 };
int generic_cpu_disable(void)
{
@@ -348,6 +348,11 @@ void generic_mach_cpu_die(void)
while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
cpu_relax();
}
+
+void generic_set_cpu_dead(unsigned int cpu)
+{
+ __get_cpu_var(cpu_state) = CPU_DEAD;
+}
#endif
int __cpuinit __cpu_up(unsigned int cpu)
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 74a43c6..ce5b4f5 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -920,10 +920,12 @@ static int smp_core99_cpu_disable(void)
static void pmac_cpu_die(void)
{
+ int cpu = smp_processor_id();
+
local_irq_disable();
idle_task_exit();
- printk(KERN_DEBUG "CPU%d offline\n", smp_processor_id());
- __get_cpu_var(cpu_state) = CPU_DEAD;
+ pr_debug("CPU%d offline\n", cpu);
+ generic_set_cpu_dead(cpu);
smp_wmb();
mb();
low_cpu_die();
@@ -933,6 +935,8 @@ static void pmac_cpu_die(void)
static void pmac_cpu_die(void)
{
+ int cpu = smp_processor_id();
+
local_irq_disable();
idle_task_exit();
@@ -942,8 +946,8 @@ static void pmac_cpu_die(void)
* on core99 platforms for now ...
*/
- printk(KERN_INFO "CPU#%d offline\n", smp_processor_id());
- __get_cpu_var(cpu_state) = CPU_DEAD;
+ printk(KERN_INFO "CPU#%d offline\n", cpu);
+ generic_set_cpu_dead(cpu);
smp_wmb();
/*
--
1.7.1
^ permalink raw reply related
* [PATCHES] powerpc: Cleanup and fix CPU hotplug
From: Benjamin Herrenschmidt @ 2011-03-08 6:37 UTC (permalink / raw)
To: linuxppc-dev
This series contain a number of cleanups and fixes to our CPU hotplug
code, including fixing crashes on G5 machines, properly re-initializing
idle threads etc...
Tested on PowerMac G5 and pSeries machines.
^ permalink raw reply
* [PATCH 13/18] powerpc/smp: Add a smp_ops->bringup_up() done callback
From: Benjamin Herrenschmidt @ 2011-03-08 6:37 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1299566250-10516-1-git-send-email-benh@kernel.crashing.org>
This allows us to stop abusing smp_ops->setup_cpu() for cleanup
tasks that have to take place after the initial boot time CPU
bringup.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/include/asm/machdep.h | 1 +
arch/powerpc/kernel/smp.c | 4 ++++
2 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index 578d330..e4f0191 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -35,6 +35,7 @@ struct smp_ops_t {
int (*probe)(void);
void (*kick_cpu)(int nr);
void (*setup_cpu)(int nr);
+ void (*bringup_done)(void);
void (*take_timebase)(void);
void (*give_timebase)(void);
int (*cpu_disable)(void);
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index f6cc5c1..df37397 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -553,7 +553,11 @@ void __init smp_cpus_done(unsigned int max_cpus)
free_cpumask_var(old_mask);
+ if (smp_ops && smp_ops->bringup_done)
+ smp_ops->bringup_done();
+
dump_numa_cpu_topology();
+
}
int arch_sd_sibling_asym_packing(void)
--
1.7.1
^ permalink raw reply related
* [PATCH 10/18] powerpc/pmac/smp: Remove HMT changes for PowerMac offline code
From: Benjamin Herrenschmidt @ 2011-03-08 6:37 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1299566250-10516-1-git-send-email-benh@kernel.crashing.org>
Those instructions do nothing on non-threaded processors such
as 970's used on those machines.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/platforms/powermac/smp.c | 4 ----
1 files changed, 0 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 50e15b4..53bee66 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -928,10 +928,6 @@ static void pmac_cpu_die(void)
/* should always be true at this point */
if (cpu_has_feature(CPU_FTR_CAN_NAP))
power4_cpu_offline_powersave();
- else {
- HMT_low();
- HMT_very_low();
- }
}
}
--
1.7.1
^ permalink raw reply related
* [PATCH 18/18] powerpc/pmac/smp: Remove no-longer needed preempt workaround
From: Benjamin Herrenschmidt @ 2011-03-08 6:37 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1299566250-10516-1-git-send-email-benh@kernel.crashing.org>
The generic code properly re-initializes the preempt count in the
idle thread now
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/platforms/powermac/smp.c | 7 -------
1 files changed, 0 insertions(+), 7 deletions(-)
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index ce5b4f5..a830c5e 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -951,13 +951,6 @@ static void pmac_cpu_die(void)
smp_wmb();
/*
- * during the path that leads here preemption is disabled,
- * reenable it now so that when coming up preempt count is
- * zero correctly
- */
- preempt_enable();
-
- /*
* Re-enable interrupts. The NAP code needs to enable them
* anyways, do it now so we deal with the case where one already
* happened while soft-disabled.
--
1.7.1
^ permalink raw reply related
* [PATCH 16/18] powerpc/smp: Create idle threads on demand and properly reset them
From: Benjamin Herrenschmidt @ 2011-03-08 6:37 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1299566250-10516-1-git-send-email-benh@kernel.crashing.org>
Instead of creating idle threads at boot for all possible CPUs, we
create them on demand, like x86 or ARM, and we properly call init_idle
to re-initialize an idle thread when a CPU was unplugged and is now
re-plugged.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/kernel/smp.c | 100 +++++++++++++++++++++++++++++++++++----------
1 files changed, 78 insertions(+), 22 deletions(-)
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 7beb001..e337073 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -57,6 +57,25 @@
#define DBG(fmt...)
#endif
+
+/* Store all idle threads, this can be reused instead of creating
+* a new thread. Also avoids complicated thread destroy functionality
+* for idle threads.
+*/
+#ifdef CONFIG_HOTPLUG_CPU
+/*
+ * Needed only for CONFIG_HOTPLUG_CPU because __cpuinitdata is
+ * removed after init for !CONFIG_HOTPLUG_CPU.
+ */
+static DEFINE_PER_CPU(struct task_struct *, idle_thread_array);
+#define get_idle_for_cpu(x) (per_cpu(idle_thread_array, x))
+#define set_idle_for_cpu(x, p) (per_cpu(idle_thread_array, x) = (p))
+#else
+static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
+#define get_idle_for_cpu(x) (idle_thread_array[(x)])
+#define set_idle_for_cpu(x, p) (idle_thread_array[(x)] = (p))
+#endif
+
struct thread_info *secondary_ti;
DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map);
@@ -238,23 +257,6 @@ static void __devinit smp_store_cpu_info(int id)
per_cpu(cpu_pvr, id) = mfspr(SPRN_PVR);
}
-static void __init smp_create_idle(unsigned int cpu)
-{
- struct task_struct *p;
-
- /* create a process for the processor */
- p = fork_idle(cpu);
- if (IS_ERR(p))
- panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p));
-#ifdef CONFIG_PPC64
- paca[cpu].__current = p;
- paca[cpu].kstack = (unsigned long) task_thread_info(p)
- + THREAD_SIZE - STACK_FRAME_OVERHEAD;
-#endif
- current_set[cpu] = task_thread_info(p);
- task_thread_info(p)->cpu = cpu;
-}
-
void __init smp_prepare_cpus(unsigned int max_cpus)
{
unsigned int cpu;
@@ -288,10 +290,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
max_cpus = NR_CPUS;
else
max_cpus = 1;
-
- for_each_possible_cpu(cpu)
- if (cpu != boot_cpuid)
- smp_create_idle(cpu);
}
void __devinit smp_prepare_boot_cpu(void)
@@ -355,9 +353,62 @@ void generic_set_cpu_dead(unsigned int cpu)
}
#endif
+struct create_idle {
+ struct work_struct work;
+ struct task_struct *idle;
+ struct completion done;
+ int cpu;
+};
+
+static void __cpuinit do_fork_idle(struct work_struct *work)
+{
+ struct create_idle *c_idle =
+ container_of(work, struct create_idle, work);
+
+ c_idle->idle = fork_idle(c_idle->cpu);
+ complete(&c_idle->done);
+}
+
+static int __cpuinit create_idle(unsigned int cpu)
+{
+ struct thread_info *ti;
+ struct create_idle c_idle = {
+ .cpu = cpu,
+ .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
+ };
+ INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle);
+
+ c_idle.idle = get_idle_for_cpu(cpu);
+
+ /* We can't use kernel_thread since we must avoid to
+ * reschedule the child. We use a workqueue because
+ * we want to fork from a kernel thread, not whatever
+ * userspace process happens to be trying to online us.
+ */
+ if (!c_idle.idle) {
+ schedule_work(&c_idle.work);
+ wait_for_completion(&c_idle.done);
+ } else
+ init_idle(c_idle.idle, cpu);
+ if (IS_ERR(c_idle.idle)) {
+ pr_err("Failed fork for CPU %u: %li", cpu, PTR_ERR(c_idle.idle));
+ return PTR_ERR(c_idle.idle);
+ }
+ ti = task_thread_info(c_idle.idle);
+
+#ifdef CONFIG_PPC64
+ paca[cpu].__current = c_idle.idle;
+ paca[cpu].kstack = (unsigned long)ti + THREAD_SIZE - STACK_FRAME_OVERHEAD;
+#endif
+ ti->cpu = cpu;
+ current_set[cpu] = ti;
+
+ return 0;
+}
+
int __cpuinit __cpu_up(unsigned int cpu)
{
- int c;
+ int rc, c;
secondary_ti = current_set[cpu];
@@ -365,6 +416,11 @@ int __cpuinit __cpu_up(unsigned int cpu)
(smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)))
return -EINVAL;
+ /* Make sure we have an idle thread */
+ rc = create_idle(cpu);
+ if (rc)
+ return rc;
+
/* Make sure callin-map entry is 0 (can be leftover a CPU
* hotplug
*/
--
1.7.1
^ permalink raw reply related
* [PATCH 17/18] powerpc/smp: Increase vdso_data->processorCount, not just decrease it
From: Benjamin Herrenschmidt @ 2011-03-08 6:37 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1299566250-10516-1-git-send-email-benh@kernel.crashing.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/kernel/smp.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index e337073..6023395 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -551,6 +551,10 @@ void __devinit start_secondary(void *unused)
secondary_cpu_time_init();
+#ifdef CONFIG_PPC64
+ if (system_state == SYSTEM_RUNNING)
+ vdso_data->processorCount++;
+#endif
ipi_call_lock();
notify_cpu_starting(cpu);
set_cpu_online(cpu, true);
--
1.7.1
^ permalink raw reply related
* [PATCH 12/18] powerpc/pmac: Rename cpu_state in therm_pm72 to avoid collision
From: Benjamin Herrenschmidt @ 2011-03-08 6:37 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1299566250-10516-1-git-send-email-benh@kernel.crashing.org>
This collides with the cpu_state in our SMP code, use processor_state
instead.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
drivers/macintosh/therm_pm72.c | 60 ++++++++++++++++++++--------------------
1 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index f3a29f2..02b4f13 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -153,7 +153,7 @@ static struct i2c_adapter * u3_0;
static struct i2c_adapter * u3_1;
static struct i2c_adapter * k2;
static struct i2c_client * fcu;
-static struct cpu_pid_state cpu_state[2];
+static struct cpu_pid_state processor_state[2];
static struct basckside_pid_params backside_params;
static struct backside_pid_state backside_state;
static struct drives_pid_state drives_state;
@@ -664,8 +664,8 @@ static int read_eeprom(int cpu, struct mpu_data *out)
static void fetch_cpu_pumps_minmax(void)
{
- struct cpu_pid_state *state0 = &cpu_state[0];
- struct cpu_pid_state *state1 = &cpu_state[1];
+ struct cpu_pid_state *state0 = &processor_state[0];
+ struct cpu_pid_state *state1 = &processor_state[1];
u16 pump_min = 0, pump_max = 0xffff;
u16 tmp[4];
@@ -717,17 +717,17 @@ static ssize_t show_##name(struct device *dev, struct device_attribute *attr, ch
return sprintf(buf, "%d", data); \
}
-BUILD_SHOW_FUNC_FIX(cpu0_temperature, cpu_state[0].last_temp)
-BUILD_SHOW_FUNC_FIX(cpu0_voltage, cpu_state[0].voltage)
-BUILD_SHOW_FUNC_FIX(cpu0_current, cpu_state[0].current_a)
-BUILD_SHOW_FUNC_INT(cpu0_exhaust_fan_rpm, cpu_state[0].rpm)
-BUILD_SHOW_FUNC_INT(cpu0_intake_fan_rpm, cpu_state[0].intake_rpm)
+BUILD_SHOW_FUNC_FIX(cpu0_temperature, processor_state[0].last_temp)
+BUILD_SHOW_FUNC_FIX(cpu0_voltage, processor_state[0].voltage)
+BUILD_SHOW_FUNC_FIX(cpu0_current, processor_state[0].current_a)
+BUILD_SHOW_FUNC_INT(cpu0_exhaust_fan_rpm, processor_state[0].rpm)
+BUILD_SHOW_FUNC_INT(cpu0_intake_fan_rpm, processor_state[0].intake_rpm)
-BUILD_SHOW_FUNC_FIX(cpu1_temperature, cpu_state[1].last_temp)
-BUILD_SHOW_FUNC_FIX(cpu1_voltage, cpu_state[1].voltage)
-BUILD_SHOW_FUNC_FIX(cpu1_current, cpu_state[1].current_a)
-BUILD_SHOW_FUNC_INT(cpu1_exhaust_fan_rpm, cpu_state[1].rpm)
-BUILD_SHOW_FUNC_INT(cpu1_intake_fan_rpm, cpu_state[1].intake_rpm)
+BUILD_SHOW_FUNC_FIX(cpu1_temperature, processor_state[1].last_temp)
+BUILD_SHOW_FUNC_FIX(cpu1_voltage, processor_state[1].voltage)
+BUILD_SHOW_FUNC_FIX(cpu1_current, processor_state[1].current_a)
+BUILD_SHOW_FUNC_INT(cpu1_exhaust_fan_rpm, processor_state[1].rpm)
+BUILD_SHOW_FUNC_INT(cpu1_intake_fan_rpm, processor_state[1].intake_rpm)
BUILD_SHOW_FUNC_FIX(backside_temperature, backside_state.last_temp)
BUILD_SHOW_FUNC_INT(backside_fan_pwm, backside_state.pwm)
@@ -919,8 +919,8 @@ static void do_cpu_pid(struct cpu_pid_state *state, s32 temp, s32 power)
static void do_monitor_cpu_combined(void)
{
- struct cpu_pid_state *state0 = &cpu_state[0];
- struct cpu_pid_state *state1 = &cpu_state[1];
+ struct cpu_pid_state *state0 = &processor_state[0];
+ struct cpu_pid_state *state1 = &processor_state[1];
s32 temp0, power0, temp1, power1;
s32 temp_combi, power_combi;
int rc, intake, pump;
@@ -1150,7 +1150,7 @@ static void do_monitor_cpu_rack(struct cpu_pid_state *state)
/*
* Initialize the state structure for one CPU control loop
*/
-static int init_cpu_state(struct cpu_pid_state *state, int index)
+static int init_processor_state(struct cpu_pid_state *state, int index)
{
int err;
@@ -1205,7 +1205,7 @@ static int init_cpu_state(struct cpu_pid_state *state, int index)
/*
* Dispose of the state data for one CPU control loop
*/
-static void dispose_cpu_state(struct cpu_pid_state *state)
+static void dispose_processor_state(struct cpu_pid_state *state)
{
if (state->monitor == NULL)
return;
@@ -1804,9 +1804,9 @@ static int main_control_loop(void *x)
set_pwm_fan(SLOTS_FAN_PWM_INDEX, SLOTS_FAN_DEFAULT_PWM);
/* Initialize ADCs */
- initialize_adc(&cpu_state[0]);
- if (cpu_state[1].monitor != NULL)
- initialize_adc(&cpu_state[1]);
+ initialize_adc(&processor_state[0]);
+ if (processor_state[1].monitor != NULL)
+ initialize_adc(&processor_state[1]);
fcu_tickle_ticks = FCU_TICKLE_TICKS;
@@ -1833,14 +1833,14 @@ static int main_control_loop(void *x)
if (cpu_pid_type == CPU_PID_TYPE_COMBINED)
do_monitor_cpu_combined();
else if (cpu_pid_type == CPU_PID_TYPE_RACKMAC) {
- do_monitor_cpu_rack(&cpu_state[0]);
- if (cpu_state[1].monitor != NULL)
- do_monitor_cpu_rack(&cpu_state[1]);
+ do_monitor_cpu_rack(&processor_state[0]);
+ if (processor_state[1].monitor != NULL)
+ do_monitor_cpu_rack(&processor_state[1]);
// better deal with UP
} else {
- do_monitor_cpu_split(&cpu_state[0]);
- if (cpu_state[1].monitor != NULL)
- do_monitor_cpu_split(&cpu_state[1]);
+ do_monitor_cpu_split(&processor_state[0]);
+ if (processor_state[1].monitor != NULL)
+ do_monitor_cpu_split(&processor_state[1]);
// better deal with UP
}
/* Then, the rest */
@@ -1885,8 +1885,8 @@ static int main_control_loop(void *x)
*/
static void dispose_control_loops(void)
{
- dispose_cpu_state(&cpu_state[0]);
- dispose_cpu_state(&cpu_state[1]);
+ dispose_processor_state(&processor_state[0]);
+ dispose_processor_state(&processor_state[1]);
dispose_backside_state(&backside_state);
dispose_drives_state(&drives_state);
dispose_slots_state(&slots_state);
@@ -1928,12 +1928,12 @@ static int create_control_loops(void)
/* Create control loops for everything. If any fail, everything
* fails
*/
- if (init_cpu_state(&cpu_state[0], 0))
+ if (init_processor_state(&processor_state[0], 0))
goto fail;
if (cpu_pid_type == CPU_PID_TYPE_COMBINED)
fetch_cpu_pumps_minmax();
- if (cpu_count > 1 && init_cpu_state(&cpu_state[1], 1))
+ if (cpu_count > 1 && init_processor_state(&processor_state[1], 1))
goto fail;
if (init_backside_state(&backside_state))
goto fail;
--
1.7.1
^ permalink raw reply related
* [PATCH 14/18] powerpc/pmac/smp: Fix CPU hotplug crashes on some machines
From: Benjamin Herrenschmidt @ 2011-03-08 6:37 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1299566250-10516-1-git-send-email-benh@kernel.crashing.org>
On some machines that use i2c to synchronize the timebases (such
as PowerMac7,2/7,3 G5 machines), hotplug CPU would crash when
putting back a new CPU online due to the underlying i2c bus being
closed.
This uses the newly added bringup_done() callback to move the close
along with other housekeeping calls, and adds a CPU notifier to
re-open the i2c bus around subsequent hotplug operations
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/platforms/powermac/smp.c | 71 +++++++++++++++++++++++++-------
1 files changed, 55 insertions(+), 16 deletions(-)
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 837989e..74a43c6 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -840,30 +840,68 @@ static void __devinit smp_core99_setup_cpu(int cpu_nr)
/* Setup openpic */
mpic_setup_this_cpu();
+}
- if (cpu_nr == 0) {
-#ifdef CONFIG_PPC64
- extern void g5_phy_disable_cpu1(void);
+#ifdef CONFIG_HOTPLUG_CPU
+static int smp_core99_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ int rc;
- /* Close i2c bus if it was used for tb sync */
+ switch(action) {
+ case CPU_UP_PREPARE:
+ case CPU_UP_PREPARE_FROZEN:
+ /* Open i2c bus if it was used for tb sync */
if (pmac_tb_clock_chip_host) {
- pmac_i2c_close(pmac_tb_clock_chip_host);
- pmac_tb_clock_chip_host = NULL;
+ rc = pmac_i2c_open(pmac_tb_clock_chip_host, 1);
+ if (rc) {
+ pr_err("Failed to open i2c bus for time sync\n");
+ return notifier_from_errno(rc);
+ }
}
+ break;
+ case CPU_ONLINE:
+ case CPU_UP_CANCELED:
+ /* Close i2c bus if it was used for tb sync */
+ if (pmac_tb_clock_chip_host)
+ pmac_i2c_close(pmac_tb_clock_chip_host);
+ break;
+ default:
+ break;
+ }
+ return NOTIFY_OK;
+}
- /* If we didn't start the second CPU, we must take
- * it off the bus
- */
- if (of_machine_is_compatible("MacRISC4") &&
- num_online_cpus() < 2)
- g5_phy_disable_cpu1();
-#endif /* CONFIG_PPC64 */
+static struct notifier_block __cpuinitdata smp_core99_cpu_nb = {
+ .notifier_call = smp_core99_cpu_notify,
+};
+#endif /* CONFIG_HOTPLUG_CPU */
- if (ppc_md.progress)
- ppc_md.progress("core99_setup_cpu 0 done", 0x349);
+static void __init smp_core99_bringup_done(void)
+{
+#ifdef CONFIG_PPC64
+ extern void g5_phy_disable_cpu1(void);
+
+ /* Close i2c bus if it was used for tb sync */
+ if (pmac_tb_clock_chip_host)
+ pmac_i2c_close(pmac_tb_clock_chip_host);
+
+ /* If we didn't start the second CPU, we must take
+ * it off the bus.
+ */
+ if (of_machine_is_compatible("MacRISC4") &&
+ num_online_cpus() < 2) {
+ set_cpu_present(1, false);
+ g5_phy_disable_cpu1();
}
-}
+#endif /* CONFIG_PPC64 */
+#ifdef CONFIG_HOTPLUG_CPU
+ register_cpu_notifier(&smp_core99_cpu_nb);
+#endif
+ if (ppc_md.progress)
+ ppc_md.progress("smp_core99_bringup_done", 0x349);
+}
#ifdef CONFIG_HOTPLUG_CPU
@@ -940,6 +978,7 @@ static void pmac_cpu_die(void)
struct smp_ops_t core99_smp_ops = {
.message_pass = smp_mpic_message_pass,
.probe = smp_core99_probe,
+ .bringup_done = smp_core99_bringup_done,
.kick_cpu = smp_core99_kick_cpu,
.setup_cpu = smp_core99_setup_cpu,
.give_timebase = smp_core99_give_timebase,
--
1.7.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox