LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* How to find out what a process has been doing on a PPC-440 system
From: Kallol Biswas @ 2006-06-02  0:36 UTC (permalink / raw)
  To: External List

Hi,
   I have a list of processes running in a linux system (2.6.11 kernel).
One of the processes invokes send() system call and does not return.
The command "ps" shows that the process is in "RUNNING" state. With an ICE
I could dump each process structures and all the fields, but can't find a way to get the stack trace for each process. Not sure how contexts are saved on ppc-4xx kernel. It seems that they are saved in kernel stack. How do we
get the top of the stack from the task_struct pointers? How to find out
where in kernel send() blocks (not sleeping/scheduled)?

Kallol

^ permalink raw reply

* RE: How to find out what a process has been doing on a PPC-440 sy stem
From: Kallol Biswas @ 2006-06-02  0:47 UTC (permalink / raw)
  To: Kallol Biswas, External List

I think reading the .*switch() macros/functions we can get the answers.

-----Original Message-----
From: linuxppc-dev-bounces+biswaska=pmc-sierra.com@ozlabs.org [mailto:linuxppc-dev-bounces+biswaska=pmc-sierra.com@ozlabs.org] On Behalf Of Kallol Biswas
Sent: Thursday, June 01, 2006 5:36 PM
To: External List
Subject: How to find out what a process has been doing on a PPC-440 system

Hi,
   I have a list of processes running in a linux system (2.6.11 kernel).
One of the processes invokes send() system call and does not return.
The command "ps" shows that the process is in "RUNNING" state. With an ICE
I could dump each process structures and all the fields, but can't find a way to get the stack trace for each process. Not sure how contexts are saved on ppc-4xx kernel. It seems that they are saved in kernel stack. How do we
get the top of the stack from the task_struct pointers? How to find out
where in kernel send() blocks (not sleeping/scheduled)?

Kallol


_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* RE: How to find out what a process has been doing on a PPC-440 sy stem
From: Kallol Biswas @ 2006-06-02  1:02 UTC (permalink / raw)
  To: External List

There is a tsk->thread.ksp (kernel stack pointer) but tsk->thread.regs is null. Next job is to get the register values from the ksp. If anyone has done it before it will save me some time.

-----Original Message-----
From: Kallol Biswas 
Sent: Thursday, June 01, 2006 5:47 PM
To: Kallol Biswas; External List
Subject: RE: How to find out what a process has been doing on a PPC-440 system

I think reading the .*switch() macros/functions we can get the answers.

-----Original Message-----
From: linuxppc-dev-bounces+biswaska=pmc-sierra.com@ozlabs.org [mailto:linuxppc-dev-bounces+biswaska=pmc-sierra.com@ozlabs.org] On Behalf Of Kallol Biswas
Sent: Thursday, June 01, 2006 5:36 PM
To: External List
Subject: How to find out what a process has been doing on a PPC-440 system

Hi,
   I have a list of processes running in a linux system (2.6.11 kernel).
One of the processes invokes send() system call and does not return.
The command "ps" shows that the process is in "RUNNING" state. With an ICE
I could dump each process structures and all the fields, but can't find a way to get the stack trace for each process. Not sure how contexts are saved on ppc-4xx kernel. It seems that they are saved in kernel stack. How do we
get the top of the stack from the task_struct pointers? How to find out
where in kernel send() blocks (not sleeping/scheduled)?

Kallol


_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* RE: How to find out what a process has been doing on a PPC-440 sy stem
From: Kallol Biswas @ 2006-06-02  1:45 UTC (permalink / raw)
  To: External List

>From ksp it is very easy to find all the register values. Just read _switch() macro.

-----Original Message-----
From: Kallol Biswas 
Sent: Thursday, June 01, 2006 6:02 PM
To: 'External List'
Subject: RE: How to find out what a process has been doing on a PPC-440 system

There is a tsk->thread.ksp (kernel stack pointer) but tsk->thread.regs is null. Next job is to get the register values from the ksp. If anyone has done it before it will save me some time.

-----Original Message-----
From: Kallol Biswas 
Sent: Thursday, June 01, 2006 5:47 PM
To: Kallol Biswas; External List
Subject: RE: How to find out what a process has been doing on a PPC-440 system

I think reading the .*switch() macros/functions we can get the answers.

-----Original Message-----
From: linuxppc-dev-bounces+biswaska=pmc-sierra.com@ozlabs.org [mailto:linuxppc-dev-bounces+biswaska=pmc-sierra.com@ozlabs.org] On Behalf Of Kallol Biswas
Sent: Thursday, June 01, 2006 5:36 PM
To: External List
Subject: How to find out what a process has been doing on a PPC-440 system

Hi,
   I have a list of processes running in a linux system (2.6.11 kernel).
One of the processes invokes send() system call and does not return.
The command "ps" shows that the process is in "RUNNING" state. With an ICE
I could dump each process structures and all the fields, but can't find a way to get the stack trace for each process. Not sure how contexts are saved on ppc-4xx kernel. It seems that they are saved in kernel stack. How do we
get the top of the stack from the task_struct pointers? How to find out
where in kernel send() blocks (not sleeping/scheduled)?

Kallol


_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* MPC85xx PCI transfer disconnect
From: Martin, Tim @ 2006-06-02  3:09 UTC (permalink / raw)
  To: linuxppc-embedded

I know this is probably a question for Freescale directly, but I thought
I would post here to see if anyone else has seen similar issues with the
MPC85xx PCI under Linux.

I'm using a Freescale MPC85xx (8541) processor and seeing an extreme
slowness to the PCI bus.

I'm attemping to do 2048 byte PCI burst reads from an external PCI
master.  So an external chip is the PCI master ("initiator") and the
MPC85xx is the PCI slave ("target")

When initiating the PCI burst read, there is a 270 ns delay from the
MPC85xx claiming the transaction (DEVSEL# going low) to being ready
(TRDY# going low).  Then 64 bytes (a single cacheline) are transferred,
and TRDY# goes inactive.  Next, STOP# goes low, terminating the
transfer.  I believe this is considered a PCI DISCONNECT type 1 since
IRDY# is active the entire time.

What I would expect is that the entire 2048 bytes are transferred in one
PCI bus mastership, but instead there are several re-arbitrations and
long delays in between several 64 byte transfers.

Additional info:
The PCI bus is 64bit running at 66 MHz.
I'm running a modified Linux 2.6.9 kernel (elinos-111).
The PCI CCSR piwar1 =3D 0xa0f4401d.

Freescale has an FAQ 21021 that describes having a PCI DISCONNECT 2,
which sounds similar to my problem, but I've already confirmed I'm doing
what the FAQ suggests (enable prefetching in the piwar register)
(http://www.freescale.com/webapp/sps/utils/SingleFaq.jsp?FAQ-21021.xml)

Any thoughts/suggestions would be appreciated,
Tim

^ permalink raw reply

* RE: MPC85xx PCI transfer disconnect
From: Liu Dave-r63238 @ 2006-06-02  3:52 UTC (permalink / raw)
  To: 'Martin, Tim', linuxppc-embedded


> I know this is probably a question for Freescale directly, 
> but I thought I would post here to see if anyone else has 
> seen similar issues with the MPC85xx PCI under Linux.
> 
> I'm using a Freescale MPC85xx (8541) processor and seeing an 
> extreme slowness to the PCI bus.
> 
> I'm attemping to do 2048 byte PCI burst reads from an 
> external PCI master.  So an external chip is the PCI master 
> ("initiator") and the MPC85xx is the PCI slave ("target")
> 
> When initiating the PCI burst read, there is a 270 ns delay 
> from the MPC85xx claiming the transaction (DEVSEL# going low) 
> to being ready (TRDY# going low).  Then 64 bytes (a single 
> cacheline) are transferred, and TRDY# goes inactive.  Next, 
> STOP# goes low, terminating the transfer.  I believe this is 
> considered a PCI DISCONNECT type 1 since IRDY# is active the 
> entire time.
> 

The 85xx cacheline is 32 bytes. 
Did you enable Memory Read Multiple command of your PCI master?

> What I would expect is that the entire 2048 bytes are 
> transferred in one PCI bus mastership, but instead there are 
> several re-arbitrations and long delays in between several 64 
> byte transfers.
> 
> Additional info:
> The PCI bus is 64bit running at 66 MHz.
> I'm running a modified Linux 2.6.9 kernel (elinos-111).
> The PCI CCSR piwar1 = 0xa0f4401d.
> 
> Freescale has an FAQ 21021 that describes having a PCI 
> DISCONNECT 2, which sounds similar to my problem, but I've 
> already confirmed I'm doing what the FAQ suggests (enable 
> prefetching in the piwar register)
> (http://www.freescale.com/webapp/sps/utils/SingleFaq.jsp?FAQ-2
1021.xml)

Any thoughts/suggestions would be appreciated,
Tim
_______________________________________________
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-embedded

^ permalink raw reply

* [PATCH] [2.6.18] U4 DART improvements
From: Olof Johansson @ 2006-06-02  4:04 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

Hi Paul,

I've given this a good beating tonight, since I finally got a pci-e
ethernet card for the new g5 to do loopback with. Profiles looked good,
I think we're good to go for 2.6.18 with this, especially if it gets
in early for extra testing.


-Olof

---

Implement single-entry TLB invalidations in the U4 DART.

Simple benchmarking with loopback flood pings of various sizes show that
the previous flush-all code will spend ~5% of the time in flush, while
the new selective invalidations will spend about an order of magnitude
less in the same code path.

This could possibly mean that invalidations larger than, say, 16
entries would better be handled in bulk, but until we have a workload
that actually shows problems or bottlenecks let's keep doing single
invalidations at all mapping sizes.

Signed-off-by: Olof Johansson <olof@lixom.net>


diff --git a/arch/powerpc/sysdev/dart.h b/arch/powerpc/sysdev/dart.h
index c2d0576..1c8817c 100644
Index: 2.6.17-rc5-git8/arch/powerpc/sysdev/dart.h
===================================================================
--- 2.6.17-rc5-git8.orig/arch/powerpc/sysdev/dart.h
+++ 2.6.17-rc5-git8/arch/powerpc/sysdev/dart.h
@@ -47,8 +47,12 @@
 /* U4 registers */
 #define DART_BASE_U4_BASE_MASK	0xffffff
 #define DART_BASE_U4_BASE_SHIFT	0
-#define DART_CNTL_U4_FLUSHTLB	0x20000000
 #define DART_CNTL_U4_ENABLE	0x80000000
+#define DART_CNTL_U4_IONE	0x40000000
+#define DART_CNTL_U4_FLUSHTLB	0x20000000
+#define DART_CNTL_U4_IDLE	0x10000000
+#define DART_CNTL_U4_PAR_EN	0x08000000
+#define DART_CNTL_U4_IONE_MASK	0x07ffffff
 #define DART_SIZE_U4_SIZE_MASK	0x1fff
 #define DART_SIZE_U4_SIZE_SHIFT	0
 
Index: 2.6.17-rc5-git8/arch/powerpc/sysdev/dart_iommu.c
===================================================================
--- 2.6.17-rc5-git8.orig/arch/powerpc/sysdev/dart_iommu.c
+++ 2.6.17-rc5-git8/arch/powerpc/sysdev/dart_iommu.c
@@ -101,8 +101,8 @@ retry:
 	if (l == (1L << limit)) {
 		if (limit < 4) {
 			limit++;
-		        reg = DART_IN(DART_CNTL);
-		        reg &= ~inv_bit;
+			reg = DART_IN(DART_CNTL);
+			reg &= ~inv_bit;
 			DART_OUT(DART_CNTL, reg);
 			goto retry;
 		} else
@@ -111,11 +111,40 @@ retry:
 	}
 }
 
+static inline void dart_tlb_invalidate_one(unsigned long bus_rpn)
+{
+	unsigned int reg;
+	unsigned int l, limit;
+
+	reg = DART_CNTL_U4_ENABLE | DART_CNTL_U4_IONE |
+		(bus_rpn & DART_CNTL_U4_IONE_MASK);
+	DART_OUT(DART_CNTL, reg);
+	mb();
+
+	limit = 0;
+wait_more:
+	l = 0;
+	while ((DART_IN(DART_CNTL) & DART_CNTL_U4_IONE) && l < (1L << limit)) {
+		rmb();
+		l++;
+	}
+
+	if (l == (1L << limit)) {
+		if (limit < 4) {
+			limit++;
+			goto wait_more;
+		} else
+			panic("DART: TLB did not flush after waiting a long "
+			      "time. Buggy U4 ?");
+	}
+}
+
 static void dart_flush(struct iommu_table *tbl)
 {
-	if (dart_dirty)
+	if (dart_dirty) {
 		dart_tlb_invalidate_all();
-	dart_dirty = 0;
+		dart_dirty = 0;
+	}
 }
 
 static void dart_build(struct iommu_table *tbl, long index,
@@ -124,6 +153,7 @@ static void dart_build(struct iommu_tabl
 {
 	unsigned int *dp;
 	unsigned int rpn;
+	long l;
 
 	DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr);
 
@@ -135,7 +165,8 @@ static void dart_build(struct iommu_tabl
 	/* On U3, all memory is contigous, so we can move this
 	 * out of the loop.
 	 */
-	while (npages--) {
+	l = npages;
+	while (l--) {
 		rpn = virt_to_abs(uaddr) >> DART_PAGE_SHIFT;
 
 		*(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK);
@@ -143,7 +174,14 @@ static void dart_build(struct iommu_tabl
 		uaddr += DART_PAGE_SIZE;
 	}
 
-	dart_dirty = 1;
+	if (dart_is_u4) {
+		rpn = index;
+		mb(); /* make sure all updates have reached memory */
+		while (npages--)
+			dart_tlb_invalidate_one(rpn++);
+	} else {
+		dart_dirty = 1;
+	}
 }
 
 

^ permalink raw reply

* pSeries_mach_cpu_die() question
From: Benjamin Herrenschmidt @ 2006-06-02  5:16 UTC (permalink / raw)
  To: linuxppc-dev list; +Cc: Nathan Lynch

While doing some autumn cleaning of the irq stuff in general and xics
specifically, I found out that
the low level pSeriesLP_cppr_info() is exported because
pSeries_mach_cpu_die() calls it:

static void pSeries_mach_cpu_die(void)
{
	local_irq_disable();
	idle_task_exit();
	/* Some hardware requires clearing the CPPR, while other hardware does
not
	 * it is safe either way
	 */
	pSeriesLP_cppr_info(0, 0);
	rtas_stop_self();
	/* Should never get here... */
	BUG();
	for(;;);
}

This leads to a few questions:

 - We always pass "0" as the CPU. Is that right ? I seems not, but maybe
pHyp doesn't care and always assume the calling CPU ...

 - xics has a xics_teardown_cpu() now, used by kexec, that does
something very similar except that it passes the proper CPU number, and
for secondary CPUs also does an EOI of any pending IPI (just in case). I
think that could be used instead of the direct call to the low level
pSeriesLP_* funciton (which I itend to unexport and rename anyway as
part of my rework). Can whoever knows that code confirm ?

 - There is a comment about "some hardware....", what does it mean ? Is
it ok to do it unconditionally ? I suppose so but heh...

Cheers,
Ben.

^ permalink raw reply

* Re: pSeries_mach_cpu_die() question
From: Nathan Lynch @ 2006-06-02  6:19 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list, Nathan Lynch
In-Reply-To: <1149225392.16202.52.camel@localhost.localdomain>

Benjamin Herrenschmidt wrote:
> While doing some autumn cleaning of the irq stuff in general and xics
> specifically, I found out that
> the low level pSeriesLP_cppr_info() is exported because
> pSeries_mach_cpu_die() calls it:
> 
> static void pSeries_mach_cpu_die(void)
> {
> 	local_irq_disable();
> 	idle_task_exit();
> 	/* Some hardware requires clearing the CPPR, while other hardware does
> not
> 	 * it is safe either way
> 	 */
> 	pSeriesLP_cppr_info(0, 0);
> 	rtas_stop_self();
> 	/* Should never get here... */
> 	BUG();
> 	for(;;);
> }
> 
> This leads to a few questions:
> 
>  - We always pass "0" as the CPU. Is that right ? I seems not, but maybe
> pHyp doesn't care and always assume the calling CPU ...

The cpu parameter is actually unused by in the lpar case:

void pSeriesLP_cppr_info(int n_cpu, u8 value)
{
	unsigned long lpar_rc;

	lpar_rc = plpar_cppr(value);
	if (lpar_rc != H_SUCCESS)
		panic("bad return code cppr - rc = %lx\n", lpar_rc);
}


>  - xics has a xics_teardown_cpu() now, used by kexec, that does
> something very similar except that it passes the proper CPU number, and
> for secondary CPUs also does an EOI of any pending IPI (just in case). I
> think that could be used instead of the direct call to the low level
> pSeriesLP_* funciton (which I itend to unexport and rename anyway as
> part of my rework). Can whoever knows that code confirm ?

Sounds okay to me.


>  - There is a comment about "some hardware....", what does it mean ? Is
> it ok to do it unconditionally ? I suppose so but heh...

The comment should be changed or removed really.  We got away without
doing plpar_cppr() on the Power4 hypervisor but we found out it was
necessary when testing Power5.  I think it's required by the
architecture regardless, and yes, it's safe on both platforms.

^ permalink raw reply

* Re: pSeries_mach_cpu_die() question
From: Benjamin Herrenschmidt @ 2006-06-02  6:26 UTC (permalink / raw)
  To: Nathan Lynch; +Cc: linuxppc-dev list, Nathan Lynch
In-Reply-To: <20060602061929.GM8934@localdomain>

On Fri, 2006-06-02 at 01:19 -0500, Nathan Lynch wrote:

> The cpu parameter is actually unused by in the lpar case:

Ok, missed that :)

> >  - xics has a xics_teardown_cpu() now, used by kexec, that does
> > something very similar except that it passes the proper CPU number, and
> > for secondary CPUs also does an EOI of any pending IPI (just in case). I
> > think that could be used instead of the direct call to the low level
> > pSeriesLP_* funciton (which I itend to unexport and rename anyway as
> > part of my rework). Can whoever knows that code confirm ?
> 
> Sounds okay to me.

Ok. I'll call it with 0 for the "secondary" argument so it doesn't do
the additional EOI of the IPI in order to not change behaviour from the
current code. We can do differently in the future if we want.

> The comment should be changed or removed really.  We got away without
> doing plpar_cppr() on the Power4 hypervisor but we found out it was
> necessary when testing Power5.  I think it's required by the
> architecture regardless, and yes, it's safe on both platforms.

I'll remove the comment.

Thanks !

Cheers,
Ben.

^ permalink raw reply

* RE: [PATCH/2.6.17-rc4 1/10] Powerpc: Add general support for mpc7 448h pc2 (Taiga) platform
From: Zang Roy-r61911 @ 2006-06-02  7:29 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linuxppc-dev list, Yang Xin-Xin-r48390, Paul Mackerras,
	Alexandre.Bounine


> > +static void __init mpc7448_hpc2_map_io(void) {
> > +	/* PCI IO  mapping */
> > +	io_block_mapping(MPC7448_HPC2_PCI_IO_BASE_VIRT,
> > +			 MPC7448_HPC2_PCI_IO_BASE_PHYS, 
> 0x00800000, _PAGE_IO);
> > +	/* Tsi108 CSR mapping */
> > +	io_block_mapping(TSI108_CSR_ADDR_VIRT, TSI108_CSR_ADDR_PHYS,
> > +			 0x100000, _PAGE_IO);
> > +
> > +	/* PCI Config mapping */
> > +	io_block_mapping(MPC7448_HPC2_PCI_CFG_BASE_VIRT,
> > +			 MPC7448_HPC2_PCI_CFG_BASE_PHYS,
> > +			 MPC7448_HPC2_PCI_CFG_SIZE, _PAGE_IO);
> > +
> > +	tsi108_pci_cfg_base = MPC7448_HPC2_PCI_CFG_BASE_VIRT;
> > +	/* NVRAM mapping */
> > +	io_block_mapping(MPC7448_HPC2_NVRAM_BASE_ADDR,
> > +			 MPC7448_HPC2_NVRAM_BASE_ADDR, 
> MPC7448_HPC2_NVRAM_SIZE,
> > +			 _PAGE_IO);
> > +}
> 
> io_block_mapping is bad ! see endless discussions in the 
> archives of why ... Use ioremap.

If I really need to use bat0 or bat1( I see that the general mmu use bat2 and bat3, 
where should I set up them?

For tsi108 pci configuration access, I need to map 16Mbyte 
physical address.  If I do not use an extra bat, I can not get the correct 
virtual address use ioremap.

^ permalink raw reply

* RE: [PATCH/2.6.17-rc4 1/10] Powerpc: Add general support for mpc7 448h pc2 (Taiga) platform
From: Benjamin Herrenschmidt @ 2006-06-02  7:32 UTC (permalink / raw)
  To: Zang Roy-r61911
  Cc: linuxppc-dev list, Yang Xin-Xin-r48390, Paul Mackerras,
	Alexandre.Bounine
In-Reply-To: <9FCDBA58F226D911B202000BDBAD4673066CF5BE@zch01exm40.ap.freescale.net>


> If I really need to use bat0 or bat1( I see that the general mmu use bat2 and bat3, 
> where should I set up them?
> 
> For tsi108 pci configuration access, I need to map 16Mbyte 
> physical address.  If I do not use an extra bat, I can not get the correct 
> virtual address use ioremap.

What do you mean ? An ioremap will work, it will give you any virtual
address, you just have to store that in a global instead of hard coding
it. Hard coded virtual addresses are bad. Especially for things like PCI
config space that really isn't performance sensitive.

Ben.

^ permalink raw reply

* RE: [PATCH/2.6.17-rc4 1/10] Powerpc: Add general support for mpc7 448h pc2 (Taiga) platform
From: Liu Dave-r63238 @ 2006-06-02  7:38 UTC (permalink / raw)
  To: 'Benjamin Herrenschmidt', Zang Roy-r61911
  Cc: linuxppc-dev list, Paul Mackerras, Alexandre.Bounine,
	Yang Xin-Xin-r48390


> > If I really need to use bat0 or bat1( I see that the 
> general mmu use 
> > bat2 and bat3,
> > where should I set up them?
> > 
> > For tsi108 pci configuration access, I need to map 16Mbyte
> > physical address.  If I do not use an extra bat, I can not 
> get the correct 
> > virtual address use ioremap.
> 
> What do you mean ? An ioremap will work, it will give you any 
> virtual address, you just have to store that in a global 
> instead of hard coding it. Hard coded virtual addresses are 
> bad. Especially for things like PCI config space that really 
> isn't performance sensitive.
> 

I agree ben about PCI config space, It should use ioremap
 to get virtual address. No performace indeed. 

I think we need find the root cause that the ioremap failed.

Dave

^ permalink raw reply

* RE: [PATCH/2.6.17-rc4 1/10] Powerpc: Add general support for mpc7 448h pc2 (Taiga) platform
From: Zang Roy-r61911 @ 2006-06-02  7:40 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linuxppc-dev list, Yang Xin-Xin-r48390, Paul Mackerras,
	Alexandre.Bounine

> 
> > If I really need to use bat0 or bat1( I see that the 
> general mmu use 
> > bat2 and bat3, where should I set up them?
> > 
> > For tsi108 pci configuration access, I need to map 16Mbyte physical 
> > address.  If I do not use an extra bat, I can not get the correct 
> > virtual address use ioremap.
> 
> What do you mean ? An ioremap will work, it will give you any 
> virtual address, you just have to store that in a global 
> instead of hard coding it. Hard coded virtual addresses are 
> bad. Especially for things like PCI config space that really 
> isn't performance sensitive.
> 
> Ben.
> 
>
 

^ permalink raw reply

* Recall: [PATCH/2.6.17-rc4 1/10] Powerpc: Add general support for mpc7 448h pc2 (Taiga) platform
From: Zang Roy-r61911 @ 2006-06-02  7:40 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linuxppc-dev list, Yang Xin-Xin-r48390, Paul Mackerras,
	Alexandre.Bounine

Zang Roy-r61911 would like to recall the message, "[PATCH/2.6.17-rc4 1/10] Powerpc: Add general support for mpc7 448h pc2 (Taiga) platform".

^ permalink raw reply

* RE: [PATCH/2.6.17-rc4 1/10] Powerpc: Add general support for mpc7 448h pc2 (Taiga) platform
From: Zang Roy-r61911 @ 2006-06-02  8:05 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linuxppc-dev list, Yang Xin-Xin-r48390, Paul Mackerras,
	Alexandre.Bounine


> > If I really need to use bat0 or bat1( I see that the 
> general mmu use 
> > bat2 and bat3, where should I set up them?
> > 
> > For tsi108 pci configuration access, I need to map 16Mbyte physical 
> > address.  If I do not use an extra bat, I can not get the correct 
> > virtual address use ioremap.
> 
> What do you mean ? An ioremap will work, it will give you any 
> virtual address, you just have to store that in a global 
> instead of hard coding it. Hard coded virtual addresses are 
> bad. Especially for things like PCI config space that really 
> isn't performance sensitive.
> 
> Ben.
> 

I had hoped to get the pci configure base address by ioremap, but failed.
the tsi108 register locates at 0xc000,0000 ~0xC001,0000. It is OK to 
access them by ioremap. While pci configure access need to ioremap 
0xfb00,0000 ~0xfc00,0000. 
I traced my code, when I do ioremap, there is no bat match, I get the virtual
address from ioremap_bot. the init ioremap_bot is 0xfe000000. When I do
tsi108_csr_vir_base = ioremap(0xfb000000,0x1000000), 
the ioremap_bot is 0xfdffe000 ( I get the serial port ioremap steal some space), 
tsi108_csr_vir_base = 0xfdfee000, I can not access the configure space with this
address.
While if I use bat0 or bat1 to map my tsi108 register space, the ioremap_bot will keep
to 0xfe000000 until I do 
tsi108_csr_vir_base = ioremap(0xfb000000,0x1000000)
then I get  tsi108_csr_vir_base = 0xfd000000. Everything is OK.

Roy

^ permalink raw reply

* RE: [PATCH/2.6.17-rc4 1/10] Powerpc: Add general support for mpc7 448h pc2 (Taiga) platform
From: Benjamin Herrenschmidt @ 2006-06-02  8:17 UTC (permalink / raw)
  To: Liu Dave-r63238
  Cc: Alexandre.Bounine, linuxppc-dev list, Paul Mackerras,
	Yang Xin-Xin-r48390
In-Reply-To: <9FCDBA58F226D911B202000BDBAD4673026FD937@zch01exm40.ap.freescale.net>

On Fri, 2006-06-02 at 15:38 +0800, Liu Dave-r63238 wrote:
> > > If I really need to use bat0 or bat1( I see that the 
> > general mmu use 
> > > bat2 and bat3,
> > > where should I set up them?
> > > 
> > > For tsi108 pci configuration access, I need to map 16Mbyte
> > > physical address.  If I do not use an extra bat, I can not 
> > get the correct 
> > > virtual address use ioremap.
> > 
> > What do you mean ? An ioremap will work, it will give you any 
> > virtual address, you just have to store that in a global 
> > instead of hard coding it. Hard coded virtual addresses are 
> > bad. Especially for things like PCI config space that really 
> > isn't performance sensitive.
> > 
> 
> I agree ben about PCI config space, It should use ioremap
>  to get virtual address. No performace indeed. 
> 
> I think we need find the root cause that the ioremap failed.

How much RAM do you have ? Maybe you are running out of virtual space ?

Ben.

^ permalink raw reply

* Re: Recall: [PATCH/2.6.17-rc4 1/10] Powerpc: Add general support for  mpc7 448h pc2 (Taiga) platform
From: Benjamin Herrenschmidt @ 2006-06-02  8:17 UTC (permalink / raw)
  To: Zang Roy-r61911
  Cc: linuxppc-dev list, Yang Xin-Xin-r48390, Paul Mackerras,
	Alexandre.Bounine
In-Reply-To: <9FCDBA58F226D911B202000BDBAD4673066CF61F@zch01exm40.ap.freescale.net>

On Fri, 2006-06-02 at 15:40 +0800, Zang Roy-r61911 wrote:
> Zang Roy-r61911 would like to recall the message, "[PATCH/2.6.17-rc4 1/10] Powerpc: Add general support for mpc7 448h pc2 (Taiga) platform".

Recalling of emails doesn't quite work :) Don't bother :)

Ben.

^ permalink raw reply

* RE: [PATCH/2.6.17-rc4 1/10] Powerpc: Add general support for mpc7 448h pc2 (Taiga) platform
From: Benjamin Herrenschmidt @ 2006-06-02  8:19 UTC (permalink / raw)
  To: Zang Roy-r61911
  Cc: linuxppc-dev list, Yang Xin-Xin-r48390, Paul Mackerras,
	Alexandre.Bounine
In-Reply-To: <9FCDBA58F226D911B202000BDBAD4673066CF6DF@zch01exm40.ap.freescale.net>

On Fri, 2006-06-02 at 16:05 +0800, Zang Roy-r61911 wrote:
> > > If I really need to use bat0 or bat1( I see that the 
> > general mmu use 
> > > bat2 and bat3, where should I set up them?
> > > 
> > > For tsi108 pci configuration access, I need to map 16Mbyte physical 
> > > address.  If I do not use an extra bat, I can not get the correct 
> > > virtual address use ioremap.
> > 
> > What do you mean ? An ioremap will work, it will give you any 
> > virtual address, you just have to store that in a global 
> > instead of hard coding it. Hard coded virtual addresses are 
> > bad. Especially for things like PCI config space that really 
> > isn't performance sensitive.
> > 
> > Ben.
> > 
> 
> I had hoped to get the pci configure base address by ioremap, but failed.
> the tsi108 register locates at 0xc000,0000 ~0xC001,0000. It is OK to 
> access them by ioremap. While pci configure access need to ioremap 
> 0xfb00,0000 ~0xfc00,0000. 
> I traced my code, when I do ioremap, there is no bat match, I get the virtual
> address from ioremap_bot. the init ioremap_bot is 0xfe000000. When I do
> tsi108_csr_vir_base = ioremap(0xfb000000,0x1000000), 
> the ioremap_bot is 0xfdffe000 ( I get the serial port ioremap steal some space), 
> tsi108_csr_vir_base = 0xfdfee000, I can not access the configure space with this
> address.

What happens if you try ?

> While if I use bat0 or bat1 to map my tsi108 register space, the ioremap_bot will keep
> to 0xfe000000 until I do 
> tsi108_csr_vir_base = ioremap(0xfb000000,0x1000000)
> then I get  tsi108_csr_vir_base = 0xfd000000. Everything is OK.

Both should work fine

Ben.

^ permalink raw reply

* RE: [PATCH/2.6.17-rc4 1/10] Powerpc: Add general support for mpc7 448h pc2 (Taiga) platform
From: Zang Roy-r61911 @ 2006-06-02  8:20 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linuxppc-dev list, Paul Mackerras, Liu Dave-r63238,
	Alexandre.Bounine, Yang Xin-Xin-r48390


> How much RAM do you have ? Maybe you are running out of 
> virtual space ?
> 
> Ben.
> 
> 

512MBytes

Roy

^ permalink raw reply

* RE: [PATCH/2.6.17-rc4 1/10] Powerpc: Add general support for mpc7 448h pc2 (Taiga) platform
From: Liu Dave-r63238 @ 2006-06-02  8:33 UTC (permalink / raw)
  To: 'Benjamin Herrenschmidt', Zang Roy-r61911
  Cc: linuxppc-dev list, Paul Mackerras, Alexandre.Bounine,
	Yang Xin-Xin-r48390

> > I had hoped to get the pci configure base address by ioremap, but 
> > failed. the tsi108 register locates at 0xc000,0000 
> ~0xC001,0000. It is 
> > OK to access them by ioremap. While pci configure access need to 
> > ioremap 0xfb00,0000 ~0xfc00,0000. I traced my code, when I 
> do ioremap, 
> > there is no bat match, I get the virtual address from 
> ioremap_bot. the 
> > init ioremap_bot is 0xfe000000. When I do tsi108_csr_vir_base = 
> > ioremap(0xfb000000,0x1000000), the ioremap_bot is 
> 0xfdffe000 ( I get 
> > the serial port ioremap steal some space), tsi108_csr_vir_base = 
> > 0xfdfee000, I can not access the configure space with this address.
> 
> What happens if you try ?
> 
> > While if I use bat0 or bat1 to map my tsi108 register space, the 
> > ioremap_bot will keep to 0xfe000000 until I do 
> tsi108_csr_vir_base = 
> > ioremap(0xfb000000,0x1000000) then I get  tsi108_csr_vir_base = 
> > 0xfd000000. Everything is OK.
> 
> Both should work fine
> 
> Ben.
> 

The smallest BAT size of 74xx is 128KB, but the MPC7448_HPC2_NVRAM_SIZE
Is 0x8000 (32KB) you set in your code. I suggest you set the
MPC7448_HPC2_NVRAM_SIZE is 0x20000, try it.

Dave

^ permalink raw reply

* USB on MPC8349 with MPH controller
From: almoeli @ 2006-06-02  8:55 UTC (permalink / raw)
  To: linuxppc-embedded

Hi,

im using kernel 2.6.16.18 with the ehci-fsl and a patch from this list
to get USB working.
So SCCR and SICRL register are set correctly.
The external connected PHY is a SMSC 3300-EZK which has an ULPI interface.
If I configure the USB controller of the MPC8349 to use the DR
controller, port 1 can be used with low, full and high speed devices
without any errors.
But if the USB controller is switched to MPH, the port 0 and port 1
cannot read the device descriptor.
Error message is:

fsl-usb2-mph: devpath1 ep0in 3strikes
fsl-usb2-mph: devpath1 ep0in 3strikes
fsl-usb2-mph: devpath1 ep0in 3strikes
usb1-1: device decriptor read/64, error -71

Does anyone know this problem or knows a solution?

Oliver

^ permalink raw reply

* MPC880 cannot use SCC4 together with FECs
From: Antonio Di Bacco @ 2006-06-02  9:21 UTC (permalink / raw)
  To: linuxppc-embedded

This is a question for a Freescale guy or anyone that already used the MPC880.
I'm using an MPC880, both the FECs are used and SMC1, SMC2 and SCC3 are 
currently being used too. Now I need to use the SCC4 as an asynchronous 
serial port (only two pins) but my hardware engineer is saying that is not 
possible because pins are missing. I cannot believe this, they told me that 
RXD4 could use pins: PA11 or PD8 or PE25 but actually PA11 is used by the 
first FEC for MII1-TXD0,
PD8 for MDC and PE25 for second FEC MII2-TXD3.

Is this correct?

Bye,
Antonio.
 

^ permalink raw reply

* snd-aoa: using feature calls for GPIOs
From: Johannes Berg @ 2006-06-01 18:42 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list

Hi,

The following patch ought to add the possibility of using feature calls
for the GPIOs instead of platform functions. Note that it doesn't
actually hook up the new gpio functions, that needs to be done in the
fabric.

However, the whole thing doesn't work for me yet. In fact, as soon as I
try using this patch, I need to reboot my computer to make the tas react
again to i2c commands. Very strange.

I looked into snd-powermac, and it does very weird things with the
GPIOs. I notice, for example, the following code:
        base = (u32 *)get_property(node, "audio-gpio-active-state", NULL);
        if (base) {
                gp->active_state = *base;
                gp->active_val = (*base) ? 0x5 : 0x4;
                gp->inactive_val = (*base) ? 0x4 : 0x5;

As far as I can see that's bogus. The 0x4/0x5 values aren't ever
actually written to the register, they are just the software values
Darwin uses for unmute/mute (or was it reset/run?).

I don't see where this comes from, looking at Darwin gives you that all
GPIO writes in PlatformInterfaceGPIO_Mapped are either 0 or 1 depending
on the activestate value and using assertGPIO/negateGPIO. I think the
4/5 comes from confusing the kGPIO_* values with what is actually
written to the register.

Also, snd-powermac says: "Try to find the active state, default to 0 !".
That isn't what Darwin does, it defaults to 1.

Anyway, I'm sure I'm doing something stupid in there and just can't find
it, I even 'disassembled' all the platform functions I have to see what
happens in them, and they also write 0 or 1 just like the code below...
Maybe I got some offsets wrong?

--- snd-aoa.orig/aoa.h	2006-06-01 20:29:56.252070199 +0200
+++ snd-aoa/aoa.h	2006-06-01 20:31:03.972070199 +0200
@@ -125,6 +125,7 @@ extern int aoa_snd_ctl_add(struct snd_kc
 
 /* GPIO stuff */
 extern struct gpio_methods *pmf_gpio_methods;
+extern struct gpio_methods *ftr_gpio_methods;
 /* extern struct gpio_methods *map_gpio_methods; */
 
 #endif /* __AOA_H */
--- snd-aoa.orig/core/Makefile	2006-06-01 20:29:56.252070199 +0200
+++ snd-aoa/core/Makefile	2006-06-01 20:31:03.972070199 +0200
@@ -1,4 +1,5 @@
 obj-$(CONFIG_SND_AOA) += snd-aoa.o
 snd-aoa-objs := snd-aoa-core.o \
 		snd-aoa-alsa.o \
-		snd-aoa-gpio-pmf.o
+		snd-aoa-gpio-pmf.o \
+		snd-aoa-gpio-feature.o
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ snd-aoa/core/snd-aoa-gpio-feature.c	2006-06-01 20:31:03.992070199 +0200
@@ -0,0 +1,322 @@
+/*
+ * Apple Onboard Audio feature call GPIO control
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPL v2, can be found in COPYING.
+ */
+
+#include <asm/pmac_feature.h>
+#include <linux/interrupt.h>
+#include "../aoa.h"
+
+static int headphone_mute_gpio;
+static int amp_mute_gpio;
+static int lineout_mute_gpio;
+static int hw_reset_gpio;
+static int lineout_detect_gpio;
+static int headphone_detect_gpio;
+static int linein_detect_gpio;
+
+static int headphone_mute_gpio_activestate;
+static int amp_mute_gpio_activestate;
+static int lineout_mute_gpio_activestate;
+static int hw_reset_gpio_activestate;
+static int lineout_detect_gpio_activestate;
+static int headphone_detect_gpio_activestate;
+static int linein_detect_gpio_activestate;
+
+static int lineout_detect_irq;
+static int linein_detect_irq;
+static int headphone_detect_irq;
+
+static void get_gpio(char *name, int *gpioptr, int *gpioactiveptr)
+{
+	struct device_node *np;
+	u32 *reg;
+
+	*gpioptr = -1;
+
+	np = of_find_node_by_name(NULL, name);
+	if (!np)
+		return;
+
+	reg = (u32 *)get_property(np, "reg", NULL);
+	if (!reg)
+		return;
+
+	*gpioptr = *reg;
+
+	/* this is a hack, usually the GPIOs 'reg' property
+	 * should have the offset based from the GPIO space
+	 * which is at 0x50, but apparently not always... */
+	if (*gpioptr < 0x50)
+		*gpioptr += 0x50;
+
+	reg = (u32 *)get_property(np, "audio-gpio-active-state", NULL);
+	if (!reg)
+		*gpioactiveptr = 1;
+	else
+		*gpioactiveptr = *reg;
+
+	printk(KERN_DEBUG "gpio %s = %d (active = %d)\n", name, *gpioptr, *gpioactiveptr);
+}
+
+static void get_irq(char *name, int *irqptr)
+{
+	struct device_node *np;
+
+	*irqptr = -1;
+	np = of_find_node_by_name(NULL, name);
+	if (!np)
+		return;
+	if (np->n_intrs != 1)
+		return;
+	*irqptr = np->intrs[0].line;
+
+	printk(KERN_DEBUG "got %s irq = %d\n", name, *irqptr);
+}
+
+#define SWITCH_GPIO(name, on)					\
+	((on)?(name##_gpio_activestate==0?0:1):(name##_gpio_activestate==0?1:0))
+
+#define FTR_GPIO(name, bit)					\
+static void ftr_gpio_set_##name(struct gpio_runtime *rt, int on)\
+{								\
+	if (unlikely(!rt)) return;				\
+								\
+	if (name##_mute_gpio < 0)				\
+		return;						\
+								\
+	pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL,		\
+			  name##_mute_gpio,			\
+			  SWITCH_GPIO(name##_mute, on));	\
+								\
+	rt->implementation_private &= ~(1<<bit);		\
+	rt->implementation_private |= (!!on << bit);		\
+}								\
+static int ftr_gpio_get_##name(struct gpio_runtime *rt)		\
+{								\
+	if (unlikely(!rt)) return 0;				\
+	return (rt->implementation_private>>bit)&1;		\
+}
+
+FTR_GPIO(headphone, 0);
+FTR_GPIO(amp, 1);
+FTR_GPIO(lineout, 2);
+
+static void ftr_gpio_set_hw_reset(struct gpio_runtime *rt, int on)
+{
+	if (unlikely(!rt)) return;
+	if (hw_reset_gpio < 0)
+		return;
+
+	pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL,
+			  hw_reset_gpio, SWITCH_GPIO(hw_reset, on));
+}
+
+static void ftr_gpio_all_amps_off(struct gpio_runtime *rt)
+{
+	int saved;
+
+	if (unlikely(!rt)) return;
+	saved = rt->implementation_private;
+	ftr_gpio_set_headphone(rt, 0);
+	ftr_gpio_set_amp(rt, 0);
+	ftr_gpio_set_lineout(rt, 0);
+	rt->implementation_private = saved;
+}
+
+static void ftr_gpio_all_amps_restore(struct gpio_runtime *rt)
+{
+	int s;
+
+	if (unlikely(!rt)) return;
+	s = rt->implementation_private;
+	ftr_gpio_set_headphone(rt, (s>>0)&1);
+	ftr_gpio_set_amp(rt, (s>>1)&1);
+	ftr_gpio_set_lineout(rt, (s>>2)&1);
+}
+
+static void ftr_handle_notify(void *data)
+{
+	struct gpio_notification *notif = data;
+
+	mutex_lock(&notif->mutex);
+	if (notif->notify)
+		notif->notify(notif->data);
+	mutex_unlock(&notif->mutex);
+}
+
+static void ftr_gpio_init(struct gpio_runtime *rt)
+{
+	get_gpio("headphone-mute", &headphone_mute_gpio,
+				   &headphone_mute_gpio_activestate);
+	get_gpio("amp-mute", &amp_mute_gpio,
+			     &amp_mute_gpio_activestate);
+	get_gpio("lineout-mute", &lineout_mute_gpio,
+				 &lineout_mute_gpio_activestate);
+	get_gpio("hw-reset", &hw_reset_gpio,
+			     &hw_reset_gpio_activestate);
+	get_gpio("headphone-detect", &headphone_detect_gpio,
+				     &headphone_detect_gpio_activestate);
+	get_gpio("lineout-detect", &lineout_detect_gpio,
+				   &lineout_detect_gpio_activestate);
+	get_gpio("linein-detect", &linein_detect_gpio,
+				  &linein_detect_gpio_activestate);
+
+	get_irq("headphone-detect", &headphone_detect_irq);
+	get_irq("lineout-detect", &lineout_detect_irq);
+	get_irq("linein-detect", &linein_detect_irq);
+
+	ftr_gpio_all_amps_off(rt);
+	rt->implementation_private = 0;
+	INIT_WORK(&rt->headphone_notify.work, ftr_handle_notify, &rt->headphone_notify);
+	INIT_WORK(&rt->line_in_notify.work, ftr_handle_notify, &rt->line_in_notify);
+	INIT_WORK(&rt->line_out_notify.work, ftr_handle_notify, &rt->line_out_notify);
+	mutex_init(&rt->headphone_notify.mutex);
+	mutex_init(&rt->line_in_notify.mutex);
+	mutex_init(&rt->line_out_notify.mutex);
+}
+
+static void ftr_gpio_exit(struct gpio_runtime *rt)
+{
+	ftr_gpio_all_amps_off(rt);
+	rt->implementation_private = 0;
+	if (rt->headphone_notify.notify)
+		free_irq(headphone_detect_irq, &rt->headphone_notify);
+	if (rt->line_in_notify.gpio_private)
+		free_irq(linein_detect_irq, &rt->line_in_notify);
+	if (rt->line_out_notify.gpio_private)
+		free_irq(lineout_detect_irq, &rt->line_out_notify);
+	cancel_delayed_work(&rt->headphone_notify.work);
+	cancel_delayed_work(&rt->line_in_notify.work);
+	cancel_delayed_work(&rt->line_out_notify.work);
+	flush_scheduled_work();
+	mutex_destroy(&rt->headphone_notify.mutex);
+	mutex_destroy(&rt->line_in_notify.mutex);
+	mutex_destroy(&rt->line_out_notify.mutex);
+}
+
+irqreturn_t ftr_handle_notify_irq(int xx, void *data, struct pt_regs *regs)
+{
+	struct gpio_notification *notif = data;
+
+	schedule_work(&notif->work);
+
+	return IRQ_HANDLED;
+}
+
+static int ftr_set_notify(struct gpio_runtime *rt,
+			  enum notify_type type,
+			  notify_func_t notify,
+			  void *data)
+{
+	struct gpio_notification *notif;
+	notify_func_t old;
+	int irq;
+	char *name;
+	int err = -EBUSY;
+
+	switch (type) {
+	case AOA_NOTIFY_HEADPHONE:
+		notif = &rt->headphone_notify;
+		name = "headphone-detect";
+		irq = headphone_detect_irq;
+		break;
+	case AOA_NOTIFY_LINE_IN:
+		notif = &rt->line_in_notify;
+		name = "linein-detect";
+		irq = linein_detect_irq;
+		break;
+	case AOA_NOTIFY_LINE_OUT:
+		notif = &rt->line_out_notify;
+		name = "lineout-detect";
+		irq = lineout_detect_irq;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (irq == -1)
+		return -ENODEV;
+
+	mutex_lock(&notif->mutex);
+
+	old = notif->notify;
+
+	if (!old && !notify) {
+		err = 0;
+		goto out_unlock;
+	}
+
+	if (old && notify) {
+		if (old == notify && notif->data == data)
+			err = 0;
+		goto out_unlock;
+	}
+
+	if (old && !notify) {
+		free_irq(irq, notif);
+	}
+	if (!old && notify) {
+		request_irq(irq, ftr_handle_notify_irq, 0, name, notif);
+	}
+	notif->notify = notify;
+	notif->data = data;
+
+	err = 0;
+ out_unlock:
+	mutex_unlock(&notif->mutex);
+	return err;
+}
+
+static int ftr_get_detect(struct gpio_runtime *rt,
+			  enum notify_type type)
+{
+	int gpio, ret, active;
+
+	switch (type) {
+	case AOA_NOTIFY_HEADPHONE:
+		gpio = headphone_detect_gpio;
+		active = headphone_detect_gpio_activestate;
+		break;
+	case AOA_NOTIFY_LINE_IN:
+		gpio = linein_detect_gpio;
+		active = linein_detect_gpio_activestate;
+		break;
+	case AOA_NOTIFY_LINE_OUT:
+		gpio = lineout_detect_gpio;
+		active = lineout_detect_gpio_activestate;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (gpio == -1)
+		return -ENODEV;
+
+	ret = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio, 0);
+	if (ret < 0)
+		return ret;
+	return ((ret >> 1) & 1) == active;
+}
+
+static struct gpio_methods methods = {
+	.init			= ftr_gpio_init,
+	.exit			= ftr_gpio_exit,
+	.all_amps_off		= ftr_gpio_all_amps_off,
+	.all_amps_restore	= ftr_gpio_all_amps_restore,
+	.set_headphone		= ftr_gpio_set_headphone,
+	.set_speakers		= ftr_gpio_set_amp,
+	.set_lineout		= ftr_gpio_set_lineout,
+	.set_hw_reset		= ftr_gpio_set_hw_reset,
+	.get_headphone		= ftr_gpio_get_headphone,
+	.get_speakers		= ftr_gpio_get_amp,
+	.get_lineout		= ftr_gpio_get_lineout,
+	.set_notify		= ftr_set_notify,
+	.get_detect		= ftr_get_detect,
+};
+
+struct gpio_methods *ftr_gpio_methods = &methods;
+EXPORT_SYMBOL_GPL(ftr_gpio_methods);

^ permalink raw reply

* Re: [PATCH] [2.6.18] U4 DART improvements
From: Segher Boessenkool @ 2006-06-02 12:44 UTC (permalink / raw)
  To: Olof Johansson; +Cc: linuxppc-dev, paulus
In-Reply-To: <20060602040426.GA28528@pb15.lixom.net>

Hi Olof,

Looks good.  One request:

> +static inline void dart_tlb_invalidate_one(unsigned long bus_rpn)
> +{
> +	unsigned int reg;
> +	unsigned int l, limit;
> +
> +	reg = DART_CNTL_U4_ENABLE | DART_CNTL_U4_IONE |
> +		(bus_rpn & DART_CNTL_U4_IONE_MASK);
> +	DART_OUT(DART_CNTL, reg);
> +	mb();

Could you please comment the memory barriers, to say exactly _why_ a
certain barrier is needed?  I can't see why wmb() wouldn't work here,
for example (note I'm not saying it would -- I just don't see why it
wouldn't).

Same goes for every single memory barrier in the whole kernel source
code, but I have to start somewhere, heh.


Segher

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox