LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] of/device: Don't register disabled devices
From: Grant Likely @ 2011-01-07 17:23 UTC (permalink / raw)
  To: David Gibson, Blanchard, Hollis, devicetree-discuss, linuxppc-dev,
	linux-kernel, Scott Wood, Benjamin Herrenschmidt, Saxena, Deepak
In-Reply-To: <20110105233535.GB8846@yookeroo>

On Thu, Jan 06, 2011 at 10:35:35AM +1100, David Gibson wrote:
> On Wed, Jan 05, 2011 at 02:53:27PM -0800, Blanchard, Hollis wrote:
> > On 01/03/2011 03:01 PM, Grant Likely wrote:
> > > Device nodes with the property status="disabled" are not usable and so
> > > don't register them when parsing the device tree for devices.
> > >
> > This is great and all, but a fair amount of driver code explicitly 
> > searches the tree, rather than registering a probe function. That's why 
> > our earlier patches in this area were more comprehensive.

As your patch set shows, the total set isn't unmanageable, and the
preference for new code is to use the device model infrastructure if
at all possible.

> > 
> > What are your thoughts on handling those cases?
> 
> One by one.  Trying to handle the explicit searches automagically is
> just asking for trouble.

Just as David says, the special cases are... well... special.
Anything making decisions about registering devices needs to follow
the status!="okay" rules.

g.

^ permalink raw reply

* Re: [RFC] MPIC Bindings and Bindings for AMP Systems
From: Blanchard, Hollis @ 2011-01-07 20:30 UTC (permalink / raw)
  To: Grant Likely; +Cc: Scott Wood, Inge, Meador, devicetree-discuss, linuxppc-dev
In-Reply-To: <AANLkTikY8z3V-opZ6K3j28QfyBV_p8jEAhxOKywjX27T@mail.gmail.com>

On 01/07/2011 08:44 AM, Grant Likely wrote:
> On Fri, Jan 7, 2011 at 9:00 AM, Blanchard, Hollis
> <Hollis_Blanchard@mentor.com>  wrote:
>> On 01/07/2011 07:48 AM, Grant Likely wrote:
>>> Actually, for a while now the kernel has been moving towards =
userspace
>>> being responsible for device identification.  That's what udev is =
for.
>>>    The kernel udev looks at the available information when a device =
is
>>> registered/bound, and it creates useful symlinks to the dynamically
>>> assigned major/minor devices.  The rest of userspace doesn't need to
>>> know about it; it can simply use the symlinks in /dev, but it is
>>> appropriate to let udev figure out the correct naming.
>> Can you point out an example of how this is done for Open Firmware
>> devices currently?
> Nope, because while it has been a theoretical concern, in practice the
> issue hasn't come up on any of the hardware I've worked on or I've
> seen patches for.
That is still this case here: it's a theoretical concern. Don't forget:=20
we're talking about eight registers in the MPIC. There is no bus, no=20
hotplug, nothing. Really, the only requirement is that somehow we can=20
match the names used in the hardware documentation.
> Mostly this is because the device tree
> representations are internally self consistent;
> dependencies/connections are explicitly expressed with phandles or
> full paths which eliminates any need for enumeration in all the cases
> I've had to deal with.
The device tree on every platform contains devices which must be=20
referenced by userspace. That is the problem we're trying to solve --=20
let's not get distracted by theoretical principles of enumeration.

The closest analogy might be serial devices, which unlike ethernet=20
devices don't have other distinguishing information for udev to=20
interpret. To my surprise, when I reverse the order of the serial nodes=20
in the device tree, the ttyS0/S1 ordering reverses too. This is exactly=20
the problem we were trying to avoid... but it seems nobody has solved it =

anywhere. :(

Hollis Blanchard
Mentor Graphics, Embedded Systems Division

^ permalink raw reply

* Re: [RFC] MPIC Bindings and Bindings for AMP Systems
From: Scott Wood @ 2011-01-07 20:57 UTC (permalink / raw)
  To: Blanchard, Hollis; +Cc: Inge, Meador, devicetree-discuss, linuxppc-dev
In-Reply-To: <DD7A9A95166BF4418C4C1EB2033B6EE2038FA90D@na3-mail.mgc.mentorg.com>

On Fri, 7 Jan 2011 12:30:52 -0800
"Blanchard, Hollis" <Hollis_Blanchard@mentor.com> wrote:

> On 01/07/2011 08:44 AM, Grant Likely wrote:
> > On Fri, Jan 7, 2011 at 9:00 AM, Blanchard, Hollis
> > <Hollis_Blanchard@mentor.com>  wrote:
> >> On 01/07/2011 07:48 AM, Grant Likely wrote:
> >>> Actually, for a while now the kernel has been moving towards userspace
> >>> being responsible for device identification.  That's what udev is for.
> >>>    The kernel udev looks at the available information when a device is
> >>> registered/bound, and it creates useful symlinks to the dynamically
> >>> assigned major/minor devices.  The rest of userspace doesn't need to
> >>> know about it; it can simply use the symlinks in /dev, but it is
> >>> appropriate to let udev figure out the correct naming.
> >> Can you point out an example of how this is done for Open Firmware
> >> devices currently?
> > Nope, because while it has been a theoretical concern, in practice the
> > issue hasn't come up on any of the hardware I've worked on or I've
> > seen patches for.
> That is still this case here: it's a theoretical concern. Don't forget: 
> we're talking about eight registers in the MPIC. There is no bus, no 
> hotplug, nothing. Really, the only requirement is that somehow we can 
> match the names used in the hardware documentation.

It's a practical concern on other devices, and we need to solve that.
Once that happens, the same infrastructure should be usable to deal
with this as well -- though really, it's a separate issue from what
goes in the device tree.

The established mechanism for "match the names used in the hardware
documentation" is aliases.

In this particular case, if you want userspace to just see timers 0-7,
have the kernel driver look for the standard aliases to determine which
block is which, and expose it to userspace in the manner of your
choosing.

> > Mostly this is because the device tree
> > representations are internally self consistent;
> > dependencies/connections are explicitly expressed with phandles or
> > full paths which eliminates any need for enumeration in all the cases
> > I've had to deal with.
> The device tree on every platform contains devices which must be 
> referenced by userspace. That is the problem we're trying to solve -- 
> let's not get distracted by theoretical principles of enumeration.
> 
> The closest analogy might be serial devices, which unlike ethernet 
> devices don't have other distinguishing information for udev to 
> interpret. To my surprise, when I reverse the order of the serial nodes 
> in the device tree, the ttyS0/S1 ordering reverses too. This is exactly 
> the problem we were trying to avoid... but it seems nobody has solved it 
> anywhere. :(

What if you plug in a PCI serial card?  Or USB?  What if you're under a
hypervisor and you have a variety of virtual serial/console/etc.
objects that don't have any meaningful enumeration order?

As Grant suggested, udev should be made aware of device-tree aliases --
which would be the distinguishing information udev needs.

In the absence of aliases or other good information, perhaps the udev
rule could fall back on heuristics such as bus type and address to at
least reduce unpredictability.

-Scott

^ permalink raw reply

* PCI woes with 2.6.37
From: Gary Thomas @ 2011-01-07 23:06 UTC (permalink / raw)
  To: Linux PPC Development

I just tried porting my target (MPC8347) from 2.6.28 (remember
that one?) to 2.6.37.  Recently I tried this with 2.6.32 without
a lot of success, so I thought I'd try the latest :-)  The changes
are very simple, pretty much just the addition of my 8347 based
platform DTS.

Sadly, it fails even worse than it did on 2.6.32.

For some reason, although everything seems to report that the
PCI bus is alive, MEM access fails completely.  If I try to
access various PCI devices via their memory space (I only have
memory peripherals so I can't test IO space access), I get
what I assume are BUS timeouts - all 0xFFFFFFFF

My PCI bus is defined in DTS like this:
	pci0: pci@ff008500 {
		cell-index = <1>;
		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
		interrupt-map = <
				/* IDSEL 0x0B (SIL SATA) */
				 0x5800 0x0 0x0 0x1 &ipic 0x16 8
				 0x5800 0x0 0x0 0x2 &ipic 0x16 8
				 0x5800 0x0 0x0 0x3 &ipic 0x16 8
				 0x5800 0x0 0x0 0x4 &ipic 0x16 8

				/* IDSEL 0x0C (Fujitsu Coral-P) */
				 0x6000 0x0 0x0 0x1 &ipic 0x13 8
				 0x6000 0x0 0x0 0x2 &ipic 0x13 8
				 0x6000 0x0 0x0 0x3 &ipic 0x13 8
				 0x6000 0x0 0x0 0x4 &ipic 0x13 8
                                 >;
		interrupt-parent = <&ipic>;
		interrupts = <0x13 0x8
                               0x14 0x8>;
		bus-range = <0 0>;
		ranges = <0x02000000 0x0 0xC0000000 0xC0000000 0x0 0x20000000
			  0x01000000 0x0 0x00000000 0xB8000000 0x0 0x00100000>;
		clock-frequency = <33333333>;
		#interrupt-cells = <1>;
		#size-cells = <2>;
		#address-cells = <3>;
		reg = <0xff008500 0x100		/* Internal registers */
		       0xff008300 0x8>;         /* Config Space registers */
		compatible = "fsl,mpc8349-pci";
		device_type = "pci";
	};

When I boot, I get these messages indicating that the PCI bus is found,
mapped, scanned, etc:

PCI: Probing PCI hardware
PCI: Scanning PHB /pci@ff008500
PCI: PHB IO resource    = 0000000000000000-00000000000FF FFf [100]
PCI: PHB MEM resource 0 = 00000000c0000000-00000000dFF FFfff [200]
PCI: PHB MEM offset     = 0000000000000000
PCI: PHB IO  offset     = 00000000
     probe mode: 0
PCI:0000:00:0b.0 Resource 0 0000000000001000-0000000000001007 [40101] fixup...
PCI:0000:00:0b.0            0000000000001000-0000000000001007
PCI:0000:00:0b.0 Resource 1 0000000000001008-000000000000100b [40101] fixup...
PCI:0000:00:0b.0            0000000000001008-000000000000100b
PCI:0000:00:0b.0 Resource 2 0000000000001010-0000000000001017 [40101] fixup...
PCI:0000:00:0b.0            0000000000001010-0000000000001017
PCI:0000:00:0b.0 Resource 3 0000000000001018-000000000000101b [40101] fixup...
PCI:0000:00:0b.0            0000000000001018-000000000000101b
PCI:0000:00:0b.0 Resource 4 0000000000001020-000000000000102f [40101] fixup...
PCI:0000:00:0b.0            0000000000001020-000000000000102f
PCI:0000:00:0b.0 Resource 5 0000000000100000-00000000001001ff [40200] fixup...
PCI:0000:00:0b.0            0000000000100000-00000000001001ff
PCI:0000:00:0b.0 Resource 6 0000000000000000-000000000007FF FF [4e200] is unassigned
PCI:0000:00:0c.0 Resource 0 0000000004000000-0000000007FF FFff [40200] fixup...
PCI:0000:00:0c.0            0000000004000000-0000000007FF FFff
PCI: Fixup bus devices 0 (PHB)
PCI: Try to map irq for 0000:00:0b.0...
  Got one, spec 2 cells (0x00000016 0x00000008...) on /soc8349@ff000000/pic@700
  Mapped to linux irq 22
PCI: Try to map irq for 0000:00:0c.0...
  Got one, spec 2 cells (0x00000013 0x00000008...) on /soc8349@ff000000/pic@700
  Mapped to linux irq 19
PCI: Allocating bus resources for 0000:00...
PCI: PHB (bus 0) bridge rsrc 0: 0000000000000000-00000000000FF FFf [0x100], parent c03b5740 (PCI IO)
PCI: PHB (bus 0) bridge rsrc 1: 00000000c0000000-00000000dFF FFfff [0x200], parent c03b5724 (PCI mem)
PCI: Allocating 0000:00:0b.0: Resource 0: 0000000000001000..0000000000001007 [40101]
PCI: Allocating 0000:00:0b.0: Resource 1: 0000000000001008..000000000000100b [40101]
PCI: Allocating 0000:00:0b.0: Resource 2: 0000000000001010..0000000000001017 [40101]
PCI: Allocating 0000:00:0b.0: Resource 3: 0000000000001018..000000000000101b [40101]
PCI: Allocating 0000:00:0b.0: Resource 4: 0000000000001020..000000000000102f [40101]
PCI: Allocating 0000:00:0b.0: Resource 5: 0000000000100000..00000000001001ff [40200]
PCI: Cannot allocate resource region 5 of device 0000:00:0b.0, will remap
PCI: Allocating 0000:00:0c.0: Resource 0: 0000000004000000..0000000007FF FFff [40200]
PCI: Cannot allocate resource region 0 of device 0000:00:0c.0, will remap
Reserving legacy ranges for domain 0000
Candidate legacy IO: [io  0x0000-0x0fff]
hose mem offset: 0000000000000000
hose mem res: [mem 0xc0000000-0xdFF FFfff]
Local memory hole: [mem 0xc0000000-0xc01FF FFf]
PCI: Assigning unassigned resources...
pci 0000:00:0c.0: BAR 0: assigned [mem 0xc4000000-0xc7FF FFff]
pci 0000:00:0c.0: BAR 0: set to [mem 0xc4000000-0xc7FF FFff] (PCI address [0xc4000000-0xc7FF FFff])
pci 0000:00:0b.0: BAR 6: assigned [mem 0xc0200000-0xc027FF FF pref]
pci 0000:00:0b.0: BAR 5: assigned [mem 0xc0280000-0xc02801ff]
pci 0000:00:0b.0: BAR 5: set to [mem 0xc0280000-0xc02801ff] (PCI address [0xc0280000-0xc02801ff])
   ...
Coral-P FB [1024x768x24] at 0xc4000000..0xc7FF FFff [0xd1100000]
D1100000: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
D1100010: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
D1100020: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
D1100030: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
D1100040: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
D1100050: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
D1100060: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
D1100070: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
  ...
scsi0 : sata_sil
scsi1 : sata_sil
ata1: SATA max UDMA/100 mmio m512@0xc0280000 tf 0xc0280080 irq 22
ata2: SATA max UDMA/100 mmio m512@0xc0280000 tf 0xc02800c0 irq 22
ata1: failed to resume link (SControl FFFFFFFF)
ata1: SATA link down (SStatus FFFFFFFF SControl FFFFFFFF)
ata2: failed to resume link (SControl FFFFFFFF)
ata2: SATA link down (SStatus FFFFFFFF SControl FFFFFFFF)

Things of note:
   * The 'local memory hole' is a space I have to steal from the PCI
     address space so that the Coral-P gets mapped to something other
     than PCI memory address 0x0 (relative).  This device is dirt stupid
     (previously discussed) and refuses to work at 0x0
   * The dump after the Coral-P FB line is what it sees in it's memory
     space.  It _should_ look something like this:
C4140600: FF FF FF 00 FF FF FF 00  FF FF FF 00 FF FF FF 00  |................|
C4140610: FF FF FF 00 FF FF FF 00  FF FF FF 00 FF FF FF 00  |................|
C4140620: FF FF FF 00 FF FF FF 00  FF FF FF 00 FF FF FF 00  |................|
C4140630: FF FF FF 00 FF FF FF 00  FF FF FF 00 FF FF FF 00  |................|
C4140640: FF FF FF 00 FF FF FF 00  FF FD FF 00 FF FD FF 00  |................|
C4140650: FF FD FF 00 FF FD FF 00  FF FD FF 00 FF FD FF 00  |................|
     Notice how byte 3 of every longword is 0x00?
   * The SATA device driver is failing along similar lines.

Any ideas what I'm doing wrong?  or what I can look at?

Thanks

-- 
------------------------------------------------------------
Gary Thomas                 |  Consulting for the
MLB Associates              |    Embedded world
------------------------------------------------------------

^ permalink raw reply

* [PATCH] ppc: update dynamic dma support
From: Nishanth Aravamudan @ 2011-01-08  2:53 UTC (permalink / raw)
  To: sonnyrao, miltonm, Benjamin Herrenschmidt, Paul Mackerras,
	Grant Likely, Anton Blanchard, linuxppc-dev
In-Reply-To: <20101211000744.GA12355@us.ibm.com>

On 10.12.2010 [16:07:44 -0800], Nishanth Aravamudan wrote:
> On 09.12.2010 [11:09:20 -0800], Nishanth Aravamudan wrote:
> > On 26.10.2010 [20:35:17 -0700], Nishanth Aravamudan wrote:
> > > If firmware allows us to map all of a partition's memory for DMA on a
> > > particular bridge, create a 1:1 mapping of that memory. Add hooks for
> > > dealing with hotplug events. Dyanmic DMA windows can use larger than the
> > > default page size, and we use the largest one possible.
> > > 
> > > Not-yet-signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
> > > 
> > > ---
> > > 
> > > I've tested this briefly on a machine with suitable firmware/hardware.
> > > Things seem to work well, but I want to do more exhaustive I/O testing
> > > before asking for upstream merging. I would really appreciate any
> > > feedback on the updated approach.
> > > 
> > > Specific questions:
> > > 
> > > Ben, did I hook into the dma_set_mask() platform callback as you
> > > expected? Anything I can do better or which perhaps might lead to
> > > gotchas later?
> > > 
> > > I've added a disable_ddw option, but perhaps it would be better to
> > > just disable the feature if iommu=force?
> > 
> > So for the final version, I probably should document this option in
> > kernel-parameters.txt w/ the patch, right?
> 
> Here's an updated version. Ben, think you can pick this up to your tree?

Hi Ben,

I have a small follow-on patch that tidies up the code a bit and deals
with an error condition on dlpar remove of ddw slots. I'm putting it
below as a follow-on patch, but I can roll it into the v3 patch and post
a v4 if you'd prefer?

Thanks,
Nish


pseries: ddw cleanups
    
Use symbolic constants to access RTAS responses.
    
Disable reconfig notifier's clearing of TCEs and removal of DMA window.
This is handled by firmware currently. If the kernel were to do it, we'd
need a new callback action before the isolation of the slot in question,
or else we'd always get permission errors (firmware revokes the window
automatically).
    
Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>

diff --git a/arch/powerpc/include/asm/ppc-pci.h b/arch/powerpc/include/asm/ppc-pci.h
index 43268f1..c17adf7 100644
--- a/arch/powerpc/include/asm/ppc-pci.h
+++ b/arch/powerpc/include/asm/ppc-pci.h
@@ -47,6 +47,20 @@ extern int rtas_setup_phb(struct pci_controller *phb);
 
 extern unsigned long pci_probe_only;
 
+/* Dynamic DMA Window support */
+struct ddw_query_response {
+        u32 windows_available;
+        u32 largest_available_block;
+        u32 page_size;
+        u32 migration_capable;
+};
+
+struct ddw_create_response {
+        u32 liobn;
+        u32 addr_hi;
+        u32 addr_lo;
+};
+
 /* ---- EEH internal-use-only related routines ---- */
 #ifdef CONFIG_EEH
 
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 4ba2338..b6f73c6 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -323,7 +323,7 @@ static int tce_clearrange_multi_pSeriesLP(unsigned long start_pfn,
 		dma_offset = next + be64_to_cpu(maprange->dma_base);
 
 		rc = plpar_tce_stuff((u64)be32_to_cpu(maprange->liobn),
-					    (u64)dma_offset,
+					     dma_offset,
 					     0, limit);
 		num_tce -= limit;
 	} while (num_tce > 0 && !rc);
@@ -383,7 +383,7 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,
 		}
 
 		rc = plpar_tce_put_indirect(liobn,
-					    (u64)dma_offset,
+					    dma_offset,
 					    (u64)virt_to_abs(tcep),
 					    limit);
 
@@ -731,7 +731,8 @@ static u64 dupe_ddw_if_kexec(struct pci_dev *dev, struct device_node *pdn)
 	return dma_addr;
 }
 
-static int query_ddw(struct pci_dev *dev, const u32 *ddr_avail, u32 *query)
+static int query_ddw(struct pci_dev *dev, const u32 *ddr_avail,
+			struct ddw_query_response *query)
 {
 	struct device_node *dn;
 	struct pci_dn *pcidn;
@@ -751,7 +752,7 @@ static int query_ddw(struct pci_dev *dev, const u32 *ddr_avail, u32 *query)
 	if (pcidn->eeh_pe_config_addr)
 		cfg_addr = pcidn->eeh_pe_config_addr;
 	buid = pcidn->phb->buid;
-	ret = rtas_call(ddr_avail[0], 3, 5, query,
+	ret = rtas_call(ddr_avail[0], 3, 5, (u32 *)query,
 		  cfg_addr, BUID_HI(buid), BUID_LO(buid));
 	dev_info(&dev->dev, "ibm,query-pe-dma-windows(%x) %x %x %x"
 		" returned %d\n", ddr_avail[0], cfg_addr, BUID_HI(buid),
@@ -759,7 +760,9 @@ static int query_ddw(struct pci_dev *dev, const u32 *ddr_avail, u32 *query)
 	return ret;
 }
 
-static int create_ddw(struct pci_dev *dev, const u32 *ddr_avail, u32 *create, int page_shift, int window_shift)
+static int create_ddw(struct pci_dev *dev, const u32 *ddr_avail,
+			struct ddw_create_response *create, int page_shift,
+		       	int window_shift)
 {
 	struct device_node *dn;
 	struct pci_dn *pcidn;
@@ -782,14 +785,14 @@ static int create_ddw(struct pci_dev *dev, const u32 *ddr_avail, u32 *create, in
 
 	do {
 		/* extra outputs are LIOBN and dma-addr (hi, lo) */
-		ret = rtas_call(ddr_avail[1], 5, 4, &create[0], cfg_addr,
+		ret = rtas_call(ddr_avail[1], 5, 4, (u32 *)create, cfg_addr,
 				BUID_HI(buid), BUID_LO(buid), page_shift, window_shift);
 	} while(rtas_busy_delay(ret));
 	dev_info(&dev->dev,
 		"ibm,create-pe-dma-window(%x) %x %x %x %x %x returned %d "
 		"(liobn = 0x%x starting addr = %x %x)\n", ddr_avail[1],
 		 cfg_addr, BUID_HI(buid), BUID_LO(buid), page_shift,
-		 window_shift, ret, create[0], create[1], create[2]);
+		 window_shift, ret, create->liobn, create->addr_hi, create->addr_lo);
 	
 	return ret;
 }
@@ -808,7 +811,8 @@ static int create_ddw(struct pci_dev *dev, const u32 *ddr_avail, u32 *create, in
 static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
 {
 	int len, ret;
-	u32 query[4], create[3];
+        struct ddw_query_response query;
+        struct ddw_create_response create;
 	int page_shift;
 	u64 dma_addr, max_addr;
 	struct device_node *dn;
@@ -846,11 +850,11 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
 	 * of page sizes: supported and supported for migrate-dma.
 	 */
 	dn = pci_device_to_OF_node(dev);
-	ret = query_ddw(dev, ddr_avail, &query[0]);
+	ret = query_ddw(dev, ddr_avail, &query);
 	if (ret != 0)
 		goto out_unlock;
 
-	if (!query[0]) {
+	if (query.windows_available == 0) {
 		/*
 		 * no additional windows are available for this device.
 		 * We might be able to reallocate the existing window,
@@ -859,23 +863,23 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
 		dev_dbg(&dev->dev, "no free dynamic windows");
 		goto out_unlock;
 	}
-	if (query[2] & 4) {
+	if (query.page_size & 4) {
 		page_shift = 24; /* 16MB */
-	} else if (query[2] & 2) {
+	} else if (query.page_size & 2) {
 		page_shift = 16; /* 64kB */
-	} else if (query[2] & 1) {
+	} else if (query.page_size & 1) {
 		page_shift = 12; /* 4kB */
 	} else {
 		dev_dbg(&dev->dev, "no supported direct page size in mask %x",
-			  query[2]);
+			  query.page_size);
 		goto out_unlock;
 	}
 	/* verify the window * number of ptes will map the partition */
 	/* check largest block * page size > max memory hotplug addr */
 	max_addr = memory_hotplug_max();
-	if (query[1] < (max_addr >> page_shift)) {
+	if (query.largest_available_block < (max_addr >> page_shift)) {
 		dev_dbg(&dev->dev, "can't map partiton max 0x%llx with %u "
-			  "%llu-sized pages\n", max_addr,  query[1],
+			  "%llu-sized pages\n", max_addr,  query.largest_available_block,
 			  1ULL << page_shift);
 		goto out_unlock;
 	}
@@ -894,19 +898,17 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
 		goto out_free_prop;
 	}
 
-	ret = create_ddw(dev, ddr_avail, &create[0], page_shift, len);
+	ret = create_ddw(dev, ddr_avail, &create, page_shift, len);
 	if (ret != 0)
 		goto out_free_prop;
 
-	*ddwprop = (struct dynamic_dma_window_prop) {
-		.liobn = cpu_to_be32(create[0]),
-		.dma_base = cpu_to_be64(((u64)create[1] << 32) + (u64)create[2]),
-		.tce_shift = cpu_to_be32(page_shift),
-		.window_shift = cpu_to_be32(len)
-	};
+	ddwprop->liobn = cpu_to_be32(create.liobn);
+	ddwprop->dma_base = cpu_to_be64(of_read_number(&create.addr_hi, 2));
+	ddwprop->tce_shift = cpu_to_be32(page_shift);
+	ddwprop->window_shift = cpu_to_be32(len);
 
 	dev_dbg(&dev->dev, "created tce table LIOBN 0x%x for %s\n",
-		  create[0], dn->full_name);
+		  create.liobn, dn->full_name);
 
 	window = kzalloc(sizeof(*window), GFP_KERNEL);
 	if (!window)
@@ -933,7 +935,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
 	list_add(&window->list, &direct_window_list);
 	spin_unlock(&direct_window_list_lock);
 
-	dma_addr = of_read_number(&create[1], 2);
+	dma_addr = of_read_number(&create.addr_hi, 2);
 	set_dma_offset(&dev->dev, dma_addr);
 	goto out_unlock;
 
@@ -1118,7 +1120,15 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti
 		}
 		spin_unlock(&direct_window_list_lock);
 
-		remove_ddw(np);
+		/*
+		 * Because the notifier runs after isolation of the
+		 * slot, we are guaranteed any DMA window has already
+		 * been revoked and the TCEs have been marked invalid,
+		 * so we don't need a call to remove_ddw(np). However,
+		 * if an additional notifier action is added before the
+		 * isolate call, we should update this code for
+		 * completeness with such a call.
+		 */
 		break;
 	default:
 		err = NOTIFY_DONE;

-- 
Nishanth Aravamudan <nacc@us.ibm.com>
IBM Linux Technology Center

^ permalink raw reply related

* Re: PCI woes with 2.6.37
From: Benjamin Herrenschmidt @ 2011-01-08  7:33 UTC (permalink / raw)
  To: Gary Thomas; +Cc: Linux PPC Development
In-Reply-To: <4D279C90.8000006@mlbassoc.com>

On Fri, 2011-01-07 at 16:06 -0700, Gary Thomas wrote:
> I just tried porting my target (MPC8347) from 2.6.28 (remember
> that one?) to 2.6.37.  Recently I tried this with 2.6.32 without
> a lot of success, so I thought I'd try the latest :-)  The changes
> are very simple, pretty much just the addition of my 8347 based
> platform DTS.
> 
> Sadly, it fails even worse than it did on 2.6.32.
> 
> For some reason, although everything seems to report that the
> PCI bus is alive, MEM access fails completely.  If I try to
> access various PCI devices via their memory space (I only have
> memory peripherals so I can't test IO space access), I get
> what I assume are BUS timeouts - all 0xFFFFFFFF
> 
> My PCI bus is defined in DTS like this:

>    		ranges = <0x02000000 0x0 0xC0000000 0xC0000000 0x0 0x20000000

What are the #address-cells and #size-cells properties of the parent of
the PCI controller node ?

PCI has 3 cells, so that accounts for the first 3 numbers of each of
these. That leaves only 3 numbers, so either you have #address-cells = 1
and #size-cells = 2 or the other way around.

The first sounds the most plausible and would mean that you are mapping
c0000000 CPU space to c0000000 PCI space and the window is 512M long.

Now of course, one needs to double check that the HW is configured that
way (I suppose fsl_pci.c does the configuration based on the "ranges"
property but I don't know for sure).

So far nothing strikes me as totally odd.

> 			  0x01000000 0x0 0x00000000 0xB8000000 0x0 0x00100000>;

This looks reasonable too with the same assumption as above.

> PCI: Probing PCI hardware
> PCI: Scanning PHB /pci@ff008500
> PCI: PHB IO resource    = 0000000000000000-00000000000FF FFf [100]
> PCI: PHB MEM resource 0 = 00000000c0000000-00000000dFF FFfff [200]

Did you edit those by hand ? :-) They look correct tho as far as I can
tell.

> PCI: PHB MEM offset     = 0000000000000000
> PCI: PHB IO  offset     = 00000000

And that too.

>      probe mode: 0
> PCI:0000:00:0b.0 Resource 0 0000000000001000-0000000000001007 [40101] fixup...
> PCI:0000:00:0b.0            0000000000001000-0000000000001007
> PCI:0000:00:0b.0 Resource 1 0000000000001008-000000000000100b [40101] fixup...
> PCI:0000:00:0b.0            0000000000001008-000000000000100b
> PCI:0000:00:0b.0 Resource 2 0000000000001010-0000000000001017 [40101] fixup...
> PCI:0000:00:0b.0            0000000000001010-0000000000001017
> PCI:0000:00:0b.0 Resource 3 0000000000001018-000000000000101b [40101] fixup...
> PCI:0000:00:0b.0            0000000000001018-000000000000101b
> PCI:0000:00:0b.0 Resource 4 0000000000001020-000000000000102f [40101] fixup...
> PCI:0000:00:0b.0            0000000000001020-000000000000102f
> PCI:0000:00:0b.0 Resource 5 0000000000100000-00000000001001ff [40200] fixup...
> PCI:0000:00:0b.0            0000000000100000-00000000001001ff
> PCI:0000:00:0b.0 Resource 6 0000000000000000-000000000007FF FF [4e200] is unassigned
> PCI:0000:00:0c.0 Resource 0 0000000004000000-0000000007FF FFff [40200] fixup...
> PCI:0000:00:0c.0            0000000004000000-0000000007FF FFff
> PCI: Fixup bus devices 0 (PHB)
> PCI: Try to map irq for 0000:00:0b.0...
>   Got one, spec 2 cells (0x00000016 0x00000008...) on /soc8349@ff000000/pic@700
>   Mapped to linux irq 22
> PCI: Try to map irq for 0000:00:0c.0...
>   Got one, spec 2 cells (0x00000013 0x00000008...) on /soc8349@ff000000/pic@700
>   Mapped to linux irq 19
> PCI: Allocating bus resources for 0000:00...
> PCI: PHB (bus 0) bridge rsrc 0: 0000000000000000-00000000000FF FFf [0x100], parent c03b5740 (PCI IO)
> PCI: PHB (bus 0) bridge rsrc 1: 00000000c0000000-00000000dFF FFfff [0x200], parent c03b5724 (PCI mem)
> PCI: Allocating 0000:00:0b.0: Resource 0: 0000000000001000..0000000000001007 [40101]
> PCI: Allocating 0000:00:0b.0: Resource 1: 0000000000001008..000000000000100b [40101]
> PCI: Allocating 0000:00:0b.0: Resource 2: 0000000000001010..0000000000001017 [40101]
> PCI: Allocating 0000:00:0b.0: Resource 3: 0000000000001018..000000000000101b [40101]
> PCI: Allocating 0000:00:0b.0: Resource 4: 0000000000001020..000000000000102f [40101]
> PCI: Allocating 0000:00:0b.0: Resource 5: 0000000000100000..00000000001001ff [40200]
> PCI: Cannot allocate resource region 5 of device 0000:00:0b.0, will remap
> PCI: Allocating 0000:00:0c.0: Resource 0: 0000000004000000..0000000007FF FFff [40200]

That's huge, is this your "Coral" framebuffer ? It's clearly using a
different address scheme which won't fit, so the kernel decides to remap
it, so far so good.

> PCI: Cannot allocate resource region 0 of device 0000:00:0c.0, will remap
> Reserving legacy ranges for domain 0000
> Candidate legacy IO: [io  0x0000-0x0fff]
> hose mem offset: 0000000000000000
> hose mem res: [mem 0xc0000000-0xdFF FFfff]
> Local memory hole: [mem 0xc0000000-0xc01FF FFf]

Now I can't grep the above string, what is it ? What is this "memory
hole" ? It covers a good part of your PCI mapping ...

> PCI: Assigning unassigned resources...
> pci 0000:00:0c.0: BAR 0: assigned [mem 0xc4000000-0xc7FF FFff]
> pci 0000:00:0c.0: BAR 0: set to [mem 0xc4000000-0xc7FF FFff] (PCI address [0xc4000000-0xc7FF FFff])

So you fb looks like it has now landed at c4000000, which doesn't strike
me as wrong nor strange so far...
 
> pci 0000:00:0b.0: BAR 6: assigned [mem 0xc0200000-0xc027FF FF pref]
> pci 0000:00:0b.0: BAR 5: assigned [mem 0xc0280000-0xc02801ff]
> pci 0000:00:0b.0: BAR 5: set to [mem 0xc0280000-0xc02801ff] (PCI address [0xc0280000-0xc02801ff])
>    ...
> Coral-P FB [1024x768x24] at 0xc4000000..0xc7FF FFff [0xd1100000]

I suspect 0xd1100000 is the result of ioremap ?

> D1100000: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
> D1100010: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
> D1100020: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
> D1100030: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
> D1100040: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
> D1100050: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
> D1100060: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
> D1100070: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
>   ...
> scsi0 : sata_sil
> scsi1 : sata_sil
> ata1: SATA max UDMA/100 mmio m512@0xc0280000 tf 0xc0280080 irq 22
> ata2: SATA max UDMA/100 mmio m512@0xc0280000 tf 0xc02800c0 irq 22
> ata1: failed to resume link (SControl FFFFFFFF)
> ata1: SATA link down (SStatus FFFFFFFF SControl FFFFFFFF)
> ata2: failed to resume link (SControl FFFFFFFF)
> ata2: SATA link down (SStatus FFFFFFFF SControl FFFFFFFF)
> 
> Things of note:
>    * The 'local memory hole' is a space I have to steal from the PCI
>      address space so that the Coral-P gets mapped to something other
>      than PCI memory address 0x0 (relative).  This device is dirt stupid
>      (previously discussed) and refuses to work at 0x0
>    * The dump after the Coral-P FB line is what it sees in it's memory
>      space.  It _should_ look something like this:
> C4140600: FF FF FF 00 FF FF FF 00  FF FF FF 00 FF FF FF 00  |................|
> C4140610: FF FF FF 00 FF FF FF 00  FF FF FF 00 FF FF FF 00  |................|
> C4140620: FF FF FF 00 FF FF FF 00  FF FF FF 00 FF FF FF 00  |................|
> C4140630: FF FF FF 00 FF FF FF 00  FF FF FF 00 FF FF FF 00  |................|
> C4140640: FF FF FF 00 FF FF FF 00  FF FD FF 00 FF FD FF 00  |................|
> C4140650: FF FD FF 00 FF FD FF 00  FF FD FF 00 FF FD FF 00  |................|
>      Notice how byte 3 of every longword is 0x00?
>    * The SATA device driver is failing along similar lines.
> 
> Any ideas what I'm doing wrong?  or what I can look at?

I can't see anything obviously wrong in what you've pasted there, but I
am not familiar with fsl PCI or SoC's, so it's possible that there's
something there going on ... We'll have to wait for somebody from FSL to
have a look, unless you can find something in the doco.

Cheers,
Ben.

^ permalink raw reply

* Re: PCI woes with 2.6.37
From: Gary Thomas @ 2011-01-08 13:07 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Linux PPC Development
In-Reply-To: <1294472036.17779.253.camel@pasglop>

On 01/08/2011 12:33 AM, Benjamin Herrenschmidt wrote:
> On Fri, 2011-01-07 at 16:06 -0700, Gary Thomas wrote:
>> I just tried porting my target (MPC8347) from 2.6.28 (remember
>> that one?) to 2.6.37.  Recently I tried this with 2.6.32 without
>> a lot of success, so I thought I'd try the latest :-)  The changes
>> are very simple, pretty much just the addition of my 8347 based
>> platform DTS.
>>
>> Sadly, it fails even worse than it did on 2.6.32.
>>
>> For some reason, although everything seems to report that the
>> PCI bus is alive, MEM access fails completely.  If I try to
>> access various PCI devices via their memory space (I only have
>> memory peripherals so I can't test IO space access), I get
>> what I assume are BUS timeouts - all 0xFFFFFFFF
>>
>> My PCI bus is defined in DTS like this:
>
>>     		ranges =<0x02000000 0x0 0xC0000000 0xC0000000 0x0 0x20000000
>
> What are the #address-cells and #size-cells properties of the parent of
> the PCI controller node ?
>
> PCI has 3 cells, so that accounts for the first 3 numbers of each of
> these. That leaves only 3 numbers, so either you have #address-cells = 1
> and #size-cells = 2 or the other way around.
>
> The first sounds the most plausible and would mean that you are mapping
> c0000000 CPU space to c0000000 PCI space and the window is 512M long.
>
> Now of course, one needs to double check that the HW is configured that
> way (I suppose fsl_pci.c does the configuration based on the "ranges"
> property but I don't know for sure).
>
> So far nothing strikes me as totally odd.
>
>> 			0x01000000 0x0 0x00000000 0xB8000000 0x0 0x00100000>;
>
> This looks reasonable too with the same assumption as above.
>
>> PCI: Probing PCI hardware
>> PCI: Scanning PHB /pci@ff008500
>> PCI: PHB IO resource    = 0000000000000000-00000000000FF FFf [100]
>> PCI: PHB MEM resource 0 = 00000000c0000000-00000000dFF FFfff [200]
>
> Did you edit those by hand ? :-) They look correct tho as far as I can
> tell.

Sorry, I did a little editing of the dump below (to make it more readable,
no content changes) and "find & replace" went wild on me :-(  It should
have read:
   PCI: PHB MEM resource 0 = 00000000c0000000-00000000dfffffff [200]

>
>
>> PCI: PHB MEM offset     = 0000000000000000
>> PCI: PHB IO  offset     = 00000000
>
> And that too.
>
>>       probe mode: 0
>> PCI:0000:00:0b.0 Resource 0 0000000000001000-0000000000001007 [40101] fixup...
>> PCI:0000:00:0b.0            0000000000001000-0000000000001007
>> PCI:0000:00:0b.0 Resource 1 0000000000001008-000000000000100b [40101] fixup...
>> PCI:0000:00:0b.0            0000000000001008-000000000000100b
>> PCI:0000:00:0b.0 Resource 2 0000000000001010-0000000000001017 [40101] fixup...
>> PCI:0000:00:0b.0            0000000000001010-0000000000001017
>> PCI:0000:00:0b.0 Resource 3 0000000000001018-000000000000101b [40101] fixup...
>> PCI:0000:00:0b.0            0000000000001018-000000000000101b
>> PCI:0000:00:0b.0 Resource 4 0000000000001020-000000000000102f [40101] fixup...
>> PCI:0000:00:0b.0            0000000000001020-000000000000102f
>> PCI:0000:00:0b.0 Resource 5 0000000000100000-00000000001001ff [40200] fixup...
>> PCI:0000:00:0b.0            0000000000100000-00000000001001ff
>> PCI:0000:00:0b.0 Resource 6 0000000000000000-000000000007FF FF [4e200] is unassigned
>> PCI:0000:00:0c.0 Resource 0 0000000004000000-0000000007FF FFff [40200] fixup...
>> PCI:0000:00:0c.0            0000000004000000-0000000007FF FFff
>> PCI: Fixup bus devices 0 (PHB)
>> PCI: Try to map irq for 0000:00:0b.0...
>>    Got one, spec 2 cells (0x00000016 0x00000008...) on /soc8349@ff000000/pic@700
>>    Mapped to linux irq 22
>> PCI: Try to map irq for 0000:00:0c.0...
>>    Got one, spec 2 cells (0x00000013 0x00000008...) on /soc8349@ff000000/pic@700
>>    Mapped to linux irq 19
>> PCI: Allocating bus resources for 0000:00...
>> PCI: PHB (bus 0) bridge rsrc 0: 0000000000000000-00000000000FF FFf [0x100], parent c03b5740 (PCI IO)
>> PCI: PHB (bus 0) bridge rsrc 1: 00000000c0000000-00000000dFF FFfff [0x200], parent c03b5724 (PCI mem)
>> PCI: Allocating 0000:00:0b.0: Resource 0: 0000000000001000..0000000000001007 [40101]
>> PCI: Allocating 0000:00:0b.0: Resource 1: 0000000000001008..000000000000100b [40101]
>> PCI: Allocating 0000:00:0b.0: Resource 2: 0000000000001010..0000000000001017 [40101]
>> PCI: Allocating 0000:00:0b.0: Resource 3: 0000000000001018..000000000000101b [40101]
>> PCI: Allocating 0000:00:0b.0: Resource 4: 0000000000001020..000000000000102f [40101]
>> PCI: Allocating 0000:00:0b.0: Resource 5: 0000000000100000..00000000001001ff [40200]
>> PCI: Cannot allocate resource region 5 of device 0000:00:0b.0, will remap
>> PCI: Allocating 0000:00:0c.0: Resource 0: 0000000004000000..0000000007FF FFff [40200]
>
> That's huge, is this your "Coral" framebuffer ? It's clearly using a
> different address scheme which won't fit, so the kernel decides to remap
> it, so far so good.

Indeed, the frame buffer takes 4MB

>
>> PCI: Cannot allocate resource region 0 of device 0000:00:0c.0, will remap
>> Reserving legacy ranges for domain 0000
>> Candidate legacy IO: [io  0x0000-0x0fff]
>> hose mem offset: 0000000000000000
>> hose mem res: [mem 0xc0000000-0xdFF FFfff]
>> Local memory hole: [mem 0xc0000000-0xc01FF FFf]
>
> Now I can't grep the above string, what is it ? What is this "memory
> hole" ? It covers a good part of your PCI mapping ...
>
>> PCI: Assigning unassigned resources...
>> pci 0000:00:0c.0: BAR 0: assigned [mem 0xc4000000-0xc7FF FFff]
>> pci 0000:00:0c.0: BAR 0: set to [mem 0xc4000000-0xc7FF FFff] (PCI address [0xc4000000-0xc7FF FFff])
>
> So you fb looks like it has now landed at c4000000, which doesn't strike
> me as wrong nor strange so far...
>
>> pci 0000:00:0b.0: BAR 6: assigned [mem 0xc0200000-0xc027FF FF pref]
>> pci 0000:00:0b.0: BAR 5: assigned [mem 0xc0280000-0xc02801ff]
>> pci 0000:00:0b.0: BAR 5: set to [mem 0xc0280000-0xc02801ff] (PCI address [0xc0280000-0xc02801ff])
>>     ...
>> Coral-P FB [1024x768x24] at 0xc4000000..0xc7FF FFff [0xd1100000]
>
> I suspect 0xd1100000 is the result of ioremap ?
>
>> D1100000: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
>> D1100010: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
>> D1100020: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
>> D1100030: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
>> D1100040: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
>> D1100050: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
>> D1100060: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
>> D1100070: FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF   |................|
>>    ...
>> scsi0 : sata_sil
>> scsi1 : sata_sil
>> ata1: SATA max UDMA/100 mmio m512@0xc0280000 tf 0xc0280080 irq 22
>> ata2: SATA max UDMA/100 mmio m512@0xc0280000 tf 0xc02800c0 irq 22
>> ata1: failed to resume link (SControl FFFFFFFF)
>> ata1: SATA link down (SStatus FFFFFFFF SControl FFFFFFFF)
>> ata2: failed to resume link (SControl FFFFFFFF)
>> ata2: SATA link down (SStatus FFFFFFFF SControl FFFFFFFF)
>>
>> Things of note:
>>     * The 'local memory hole' is a space I have to steal from the PCI
>>       address space so that the Coral-P gets mapped to something other
>>       than PCI memory address 0x0 (relative).  This device is dirt stupid
>>       (previously discussed) and refuses to work at 0x0
>>     * The dump after the Coral-P FB line is what it sees in it's memory
>>       space.  It _should_ look something like this:
>> C4140600: FF FF FF 00 FF FF FF 00  FF FF FF 00 FF FF FF 00  |................|
>> C4140610: FF FF FF 00 FF FF FF 00  FF FF FF 00 FF FF FF 00  |................|
>> C4140620: FF FF FF 00 FF FF FF 00  FF FF FF 00 FF FF FF 00  |................|
>> C4140630: FF FF FF 00 FF FF FF 00  FF FF FF 00 FF FF FF 00  |................|
>> C4140640: FF FF FF 00 FF FF FF 00  FF FD FF 00 FF FD FF 00  |................|
>> C4140650: FF FD FF 00 FF FD FF 00  FF FD FF 00 FF FD FF 00  |................|
>>       Notice how byte 3 of every longword is 0x00?
>>     * The SATA device driver is failing along similar lines.
>>
>> Any ideas what I'm doing wrong?  or what I can look at?
>
> I can't see anything obviously wrong in what you've pasted there, but I
> am not familiar with fsl PCI or SoC's, so it's possible that there's
> something there going on ... We'll have to wait for somebody from FSL to
> have a look, unless you can find something in the doco.

The curious thing is that this exact same setup works perfectly
in 2.6.28 and near perfectly in 2.6.32.  Unless something else
changed in the PCI handling between 2.6.32 and 2.6.37, I would
hope it work work there as well.

I'll keep looking for differences between those two system versions.

Thanks

-- 
------------------------------------------------------------
Gary Thomas                 |  Consulting for the
MLB Associates              |    Embedded world
------------------------------------------------------------

^ permalink raw reply

* [PATCH] powerpc/mpc8xxx_gpio: simplify searching for 'fsl, qoriq-gpio' compatiable
From: Anatolij Gustschin @ 2011-01-08 15:51 UTC (permalink / raw)
  To: linuxppc-dev

Commit da3ed89e7ce272ebcc918487e2a28736ca0dd6bb added
'fsl,qoriq-gpio' compatiable searching in the old way
using for_each_compatible_node(). But the driver have
previously been changed to use a struct of_device_id
compatible list passed to for_each_matching_node().

Add 'fsl,qoriq-gpio' compatiable to the existing
compatible list instead of adding another
for_each_compatible_node() loop.

Signed-off-by: Anatolij Gustschin <agust@denx.de>
---
 arch/powerpc/sysdev/mpc8xxx_gpio.c |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c
index c48cd81..0c2a91a 100644
--- a/arch/powerpc/sysdev/mpc8xxx_gpio.c
+++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c
@@ -310,6 +310,7 @@ static struct of_device_id mpc8xxx_gpio_ids[] __initdata = {
 	{ .compatible = "fsl,mpc8572-gpio", },
 	{ .compatible = "fsl,mpc8610-gpio", },
 	{ .compatible = "fsl,mpc5121-gpio", .data = mpc512x_irq_set_type, },
+	{ .compatible = "fsl,qoriq-gpio",   },
 	{}
 };
 
@@ -389,9 +390,6 @@ static int __init mpc8xxx_add_gpiochips(void)
 	for_each_matching_node(np, mpc8xxx_gpio_ids)
 		mpc8xxx_add_controller(np);
 
-	for_each_compatible_node(np, NULL, "fsl,qoriq-gpio")
-		mpc8xxx_add_controller(np);
-
 	return 0;
 }
 arch_initcall(mpc8xxx_add_gpiochips);
-- 
1.7.1

^ permalink raw reply related

* Re: mpc880 linux-2.6.32 slow running processes
From: Joakim Tjernlund @ 2011-01-08 21:43 UTC (permalink / raw)
  To: Rafael Beims; +Cc: michael, linuxppc-dev, scottwood, RFeany
In-Reply-To: <AANLkTinbdEc2kTVHZp3b31V6sFSqOfquUidb5BZYdgEX@mail.gmail.com>

Rafael Beims <rbeims@gmail.com> wrote on 2011/01/07 11:00:56:
>
> On Thu, Jan 6, 2011 at 2:52 PM, Joakim Tjernlund
> <joakim.tjernlund@transmode.se> wrote:
>
> >
> > The 8xx tlbil_va should not be needed in recent 2.6 after I fixed t=
he 8xx TLB code
> > to workaround the dcbst bug there instead. See
> > http://git.kernel.org/?p=3Dlinux/kernel/git/torvalds/linux-2.6.git;=
a=3Dcommitdiff;h=3D0a2ab51ffb8dfdf51402dcfb446629648c96bc78;hp=3D60e071=
fee994ff98c37d03a4a7c5a3f8b1e3b8e5
> >
> > Not sure what release it went into though.
> >
> > =A0Jocke
>
> I saw that the commit you mention did make it in the 2.6.33 version. =
I
> will try to boot it here and see if the problem is also solved in thi=
s
> version.

Once you have tested it and it works, please send a patch to remove the=
 8xx workaround.
Make sure Scott is cc:ed=

^ permalink raw reply

* [PATCH 2/2] powerpc/boot/Makefile: Use $(src) and $(obj) as per makefiles.txt
From: Ben Hutchings @ 2011-01-09  0:25 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <1294532641.3283.70.camel@localhost>

$(src) and $(obj) are normally the same, but are supposed to be used
for paths under $(srctree) and $(objtree) respectively.

Also use $(dtstree) and $(wrapper) as appropriate.

Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
This is totally untested, so please review carefully!

Ben.

 arch/powerpc/boot/Makefile |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 8917816..bd7abba 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -33,7 +33,7 @@ ifeq ($(call cc-option-yn, -fstack-protector),y)
 BOOTCFLAGS	+=3D -fno-stack-protector
 endif
=20
-BOOTCFLAGS	+=3D -I$(obj) -I$(srctree)/$(obj)
+BOOTCFLAGS	+=3D -I$(obj) -I$(srctree)/$(src)
=20
 DTC_FLAGS	?=3D -p 1024
=20
@@ -399,10 +399,10 @@ $(extra-installed)	: $(DESTDIR)$(WRAPPER_OBJDIR)/% : =
$(obj)/% | $(DESTDIR)$(WRAP
 $(hostprogs-installed)  : $(DESTDIR)$(WRAPPER_BINDIR)/% : $(obj)/% | $(DES=
TDIR)$(WRAPPER_BINDIR)
 	$(call cmd,install_exe)
=20
-$(dts-installed)	: $(DESTDIR)$(WRAPPER_DTSDIR)/% : $(srctree)/$(obj)/dts/%=
 | $(DESTDIR)$(WRAPPER_DTSDIR)
+$(dts-installed)	: $(DESTDIR)$(WRAPPER_DTSDIR)/% : $(dtstree)/% | $(DESTDI=
R)$(WRAPPER_DTSDIR)
 	$(call cmd,install_dts)
=20
-$(wrapper-installed): $(DESTDIR)$(WRAPPER_BINDIR) $(srctree)/$(obj)/wrappe=
r | $(DESTDIR)$(WRAPPER_BINDIR)
+$(wrapper-installed): $(DESTDIR)$(WRAPPER_BINDIR) $(wrapper) | $(DESTDIR)$=
(WRAPPER_BINDIR)
 	$(call cmd,install_wrapper)
=20
 $(obj)/bootwrapper_install: $(all-installed)
--=20
1.7.2.3

^ permalink raw reply related

* [PATCH 1/2] powerpc/boot/dts: Install dts from the right directory
From: Ben Hutchings @ 2011-01-09  0:24 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras; +Cc: linuxppc-dev

The dts-installed variable is initialised using a wildcard path that
will be expanded relative to the build directory.  Use the existing
variable dtstree to generate an absolute wildcard path that will work
when building in a separate directory.

Reported-by: Gerhard Pircher <gerhard_pircher@gmx.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Tested-by: Gerhard Pircher <gerhard_pircher@gmx.net> [against 2.6.32]
---
 arch/powerpc/boot/Makefile |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 96deec6..8917816 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -368,7 +368,7 @@ INSTALL :=3D install
 extra-installed		:=3D $(patsubst $(obj)/%, $(DESTDIR)$(WRAPPER_OBJDIR)/%, =
$(extra-y))
 hostprogs-installed	:=3D $(patsubst %, $(DESTDIR)$(WRAPPER_BINDIR)/%, $(ho=
stprogs-y))
 wrapper-installed	:=3D $(DESTDIR)$(WRAPPER_BINDIR)/wrapper
-dts-installed		:=3D $(patsubst $(obj)/dts/%, $(DESTDIR)$(WRAPPER_DTSDIR)/%=
, $(wildcard $(obj)/dts/*.dts))
+dts-installed		:=3D $(patsubst $(dtstree)/%, $(DESTDIR)$(WRAPPER_DTSDIR)/%=
, $(wildcard $(dtstree)/*.dts))
=20
 all-installed		:=3D $(extra-installed) $(hostprogs-installed) $(wrapper-in=
stalled) $(dts-installed)
=20
--=20
1.7.2.3

^ permalink raw reply related

* [PATCH #upstream-fixes] pata_mpc52xx: inherit from ata_bmdma_port_ops
From: Tejun Heo @ 2011-01-09 22:48 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-ide, linuxppc-dev, Sergei Shtylyov, Roman Fietze
In-Reply-To: <4D21FA4D.3030506@mvista.com>

pata_mpc52xx supports BMDMA but inherits ata_sff_port_ops which
triggers BUG_ON() when a DMA command is issued.  Fix it.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: Roman Fietze <roman.fietze@telemotive.de>
Cc: Sergei Shtylyov <sshtylyov@mvista.com>
Cc: stable@kernel.org
---
 drivers/ata/pata_mpc52xx.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c
index 8cc536e..d7d8026 100644
--- a/drivers/ata/pata_mpc52xx.c
+++ b/drivers/ata/pata_mpc52xx.c
@@ -610,7 +610,7 @@ static struct scsi_host_template mpc52xx_ata_sht = {
 };
 
 static struct ata_port_operations mpc52xx_ata_port_ops = {
-	.inherits		= &ata_sff_port_ops,
+	.inherits		= &ata_bmdma_port_ops,
 	.sff_dev_select		= mpc52xx_ata_dev_select,
 	.set_piomode		= mpc52xx_ata_set_piomode,
 	.set_dmamode		= mpc52xx_ata_set_dmamode,

^ permalink raw reply related

* gianfar: incorrect TCP checksum when timestamps are enabled
From: Alex Dubov @ 2011-01-10  6:22 UTC (permalink / raw)
  To: linuxppc-dev

Greetings.=0A=0AI'm working on MPC8548 based board (I started with 2.6.37-r=
c7, now upgraded=0Ato post release 2.6.37 git head).=0A=0AIt so appears, th=
at when tcp timestamps are enabled (default setting)=0ATCP checksums of out=
going SYN packets are calculated incorrectly. This=0Acauses remote machines=
 to reject such packets, effectively preventing any=0Auseful network use. T=
he problem is reproducible every time.=0A=0AOther protocols appear to work =
reliably (UDP/DHCP do work).=0A=0AIf tcp timestamps are disabled, checksums=
 are calculated correctly.=0A=0ANetdev guys tend to think that the problem =
is with hardware checksum=0Aoffloading, the theory I'm going to test now.=
=0A=0A=0A=0A      

^ permalink raw reply

* Re: [PATCH #upstream-fixes] pata_mpc52xx: inherit from ata_bmdma_port_ops
From: Roman Fietze @ 2011-01-10  7:26 UTC (permalink / raw)
  To: Tejun Heo; +Cc: linux-ide, Jeff Garzik, linuxppc-dev, Sergei Shtylyov
In-Reply-To: <20110109224820.GB26607@mtj.dyndns.org>

Hello Tejun,

On Sunday, 09.January.2011 23:48:20 Tejun Heo wrote:

> Fix it.

I can confirm that, it's fixed.

Thank's a lot. Should have looked into it, that was really a simple
fix.


Roman

-- 
Roman Fietze              Telemotive AG Buero Muehlhausen
Breitwiesen                             73347 Muehlhausen
Tel.: +49(0)7335/18493-45        http://www.telemotive.de

^ permalink raw reply

* [PATCH] USB: Fix USB Kconfig dependency problem on 85xx/QoirQ platforms
From: Xulei @ 2011-01-10 10:06 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Xulei, Kumar Gala

For FSL PPC SoCs USB_ARCH_HAS_EHCI currently on depends on PPC_83xx.
However that excludes support for USB on 85xx & QorIQ devices.  Use
FSL_SOC insted which will get us 83xx, 85xx, QorIQ, and 5xxx which all
have the same USB IP on them.

Signed-off-by: Xulei <B33228@freescale.com>
Signed-off-by: Kumar Gala <kumar.gala@freescale.com>
---
 drivers/usb/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 6a58cb1..d513d3a 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -57,7 +57,7 @@ config USB_ARCH_HAS_OHCI
 # some non-PCI hcds implement EHCI
 config USB_ARCH_HAS_EHCI
 	boolean
-	default y if PPC_83xx
+	default y if FSL_SOC
 	default y if SOC_AU1200
 	default y if ARCH_IXP4XX
 	default y if ARCH_W90X900
-- 
1.7.0.4

^ permalink raw reply related

* Re: PCI woes with 2.6.37
From: Gary Thomas @ 2011-01-10 14:01 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Linux PPC Development
In-Reply-To: <4D28617A.8020606@mlbassoc.com>

On 01/08/2011 06:07 AM, Gary Thomas wrote:
> On 01/08/2011 12:33 AM, Benjamin Herrenschmidt wrote:
>> On Fri, 2011-01-07 at 16:06 -0700, Gary Thomas wrote:
>>> I just tried porting my target (MPC8347) from 2.6.28 (remember
>>> that one?) to 2.6.37. Recently I tried this with 2.6.32 without
>>> a lot of success, so I thought I'd try the latest :-) The changes
>>> are very simple, pretty much just the addition of my 8347 based
>>> platform DTS.
>>>
>>> Sadly, it fails even worse than it did on 2.6.32.
>>>
>>> For some reason, although everything seems to report that the
>>> PCI bus is alive, MEM access fails completely. If I try to
>>> access various PCI devices via their memory space (I only have
>>> memory peripherals so I can't test IO space access), I get
>>> what I assume are BUS timeouts - all 0xFFFFFFFF
>>>
>>> My PCI bus is defined in DTS like this:
>>
>>> ranges =<0x02000000 0x0 0xC0000000 0xC0000000 0x0 0x20000000
>>
>> What are the #address-cells and #size-cells properties of the parent of
>> the PCI controller node ?
>>
>> PCI has 3 cells, so that accounts for the first 3 numbers of each of
>> these. That leaves only 3 numbers, so either you have #address-cells = 1
>> and #size-cells = 2 or the other way around.
>>
>> The first sounds the most plausible and would mean that you are mapping
>> c0000000 CPU space to c0000000 PCI space and the window is 512M long.
>>
>> Now of course, one needs to double check that the HW is configured that
>> way (I suppose fsl_pci.c does the configuration based on the "ranges"
>> property but I don't know for sure).
>>
>> So far nothing strikes me as totally odd.
>>
>>> 0x01000000 0x0 0x00000000 0xB8000000 0x0 0x00100000>;
>>
>> This looks reasonable too with the same assumption as above.
>>
>>> PCI: Probing PCI hardware
>>> PCI: Scanning PHB /pci@ff008500
>>> PCI: PHB IO resource = 0000000000000000-00000000000FF FFf [100]
>>> PCI: PHB MEM resource 0 = 00000000c0000000-00000000dFF FFfff [200]
>>
>> Did you edit those by hand ? :-) They look correct tho as far as I can
>> tell.
>
> Sorry, I did a little editing of the dump below (to make it more readable,
> no content changes) and "find & replace" went wild on me :-( It should
> have read:
> PCI: PHB MEM resource 0 = 00000000c0000000-00000000dfffffff [200]
>
>>
>>
>>> PCI: PHB MEM offset = 0000000000000000
>>> PCI: PHB IO offset = 00000000
>>
>> And that too.
>>
>>> probe mode: 0
>>> PCI:0000:00:0b.0 Resource 0 0000000000001000-0000000000001007 [40101] fixup...
>>> PCI:0000:00:0b.0 0000000000001000-0000000000001007
>>> PCI:0000:00:0b.0 Resource 1 0000000000001008-000000000000100b [40101] fixup...
>>> PCI:0000:00:0b.0 0000000000001008-000000000000100b
>>> PCI:0000:00:0b.0 Resource 2 0000000000001010-0000000000001017 [40101] fixup...
>>> PCI:0000:00:0b.0 0000000000001010-0000000000001017
>>> PCI:0000:00:0b.0 Resource 3 0000000000001018-000000000000101b [40101] fixup...
>>> PCI:0000:00:0b.0 0000000000001018-000000000000101b
>>> PCI:0000:00:0b.0 Resource 4 0000000000001020-000000000000102f [40101] fixup...
>>> PCI:0000:00:0b.0 0000000000001020-000000000000102f
>>> PCI:0000:00:0b.0 Resource 5 0000000000100000-00000000001001ff [40200] fixup...
>>> PCI:0000:00:0b.0 0000000000100000-00000000001001ff
>>> PCI:0000:00:0b.0 Resource 6 0000000000000000-000000000007FF FF [4e200] is unassigned
>>> PCI:0000:00:0c.0 Resource 0 0000000004000000-0000000007FF FFff [40200] fixup...
>>> PCI:0000:00:0c.0 0000000004000000-0000000007FF FFff
>>> PCI: Fixup bus devices 0 (PHB)
>>> PCI: Try to map irq for 0000:00:0b.0...
>>> Got one, spec 2 cells (0x00000016 0x00000008...) on /soc8349@ff000000/pic@700
>>> Mapped to linux irq 22
>>> PCI: Try to map irq for 0000:00:0c.0...
>>> Got one, spec 2 cells (0x00000013 0x00000008...) on /soc8349@ff000000/pic@700
>>> Mapped to linux irq 19
>>> PCI: Allocating bus resources for 0000:00...
>>> PCI: PHB (bus 0) bridge rsrc 0: 0000000000000000-00000000000FF FFf [0x100], parent c03b5740 (PCI IO)
>>> PCI: PHB (bus 0) bridge rsrc 1: 00000000c0000000-00000000dFF FFfff [0x200], parent c03b5724 (PCI mem)
>>> PCI: Allocating 0000:00:0b.0: Resource 0: 0000000000001000..0000000000001007 [40101]
>>> PCI: Allocating 0000:00:0b.0: Resource 1: 0000000000001008..000000000000100b [40101]
>>> PCI: Allocating 0000:00:0b.0: Resource 2: 0000000000001010..0000000000001017 [40101]
>>> PCI: Allocating 0000:00:0b.0: Resource 3: 0000000000001018..000000000000101b [40101]
>>> PCI: Allocating 0000:00:0b.0: Resource 4: 0000000000001020..000000000000102f [40101]
>>> PCI: Allocating 0000:00:0b.0: Resource 5: 0000000000100000..00000000001001ff [40200]
>>> PCI: Cannot allocate resource region 5 of device 0000:00:0b.0, will remap
>>> PCI: Allocating 0000:00:0c.0: Resource 0: 0000000004000000..0000000007FF FFff [40200]
>>
>> That's huge, is this your "Coral" framebuffer ? It's clearly using a
>> different address scheme which won't fit, so the kernel decides to remap
>> it, so far so good.
>
> Indeed, the frame buffer takes 4MB
>
>>
>>> PCI: Cannot allocate resource region 0 of device 0000:00:0c.0, will remap
>>> Reserving legacy ranges for domain 0000
>>> Candidate legacy IO: [io 0x0000-0x0fff]
>>> hose mem offset: 0000000000000000
>>> hose mem res: [mem 0xc0000000-0xdFF FFfff]
>>> Local memory hole: [mem 0xc0000000-0xc01FF FFf]
>>
>> Now I can't grep the above string, what is it ? What is this "memory
>> hole" ? It covers a good part of your PCI mapping ...
>>
>>> PCI: Assigning unassigned resources...
>>> pci 0000:00:0c.0: BAR 0: assigned [mem 0xc4000000-0xc7FF FFff]
>>> pci 0000:00:0c.0: BAR 0: set to [mem 0xc4000000-0xc7FF FFff] (PCI address [0xc4000000-0xc7FF FFff])
>>
>> So you fb looks like it has now landed at c4000000, which doesn't strike
>> me as wrong nor strange so far...
>>
>>> pci 0000:00:0b.0: BAR 6: assigned [mem 0xc0200000-0xc027FF FF pref]
>>> pci 0000:00:0b.0: BAR 5: assigned [mem 0xc0280000-0xc02801ff]
>>> pci 0000:00:0b.0: BAR 5: set to [mem 0xc0280000-0xc02801ff] (PCI address [0xc0280000-0xc02801ff])
>>> ...
>>> Coral-P FB [1024x768x24] at 0xc4000000..0xc7FF FFff [0xd1100000]
>>
>> I suspect 0xd1100000 is the result of ioremap ?
>>
>>> D1100000: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF |................|
>>> D1100010: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF |................|
>>> D1100020: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF |................|
>>> D1100030: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF |................|
>>> D1100040: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF |................|
>>> D1100050: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF |................|
>>> D1100060: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF |................|
>>> D1100070: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF |................|
>>> ...
>>> scsi0 : sata_sil
>>> scsi1 : sata_sil
>>> ata1: SATA max UDMA/100 mmio m512@0xc0280000 tf 0xc0280080 irq 22
>>> ata2: SATA max UDMA/100 mmio m512@0xc0280000 tf 0xc02800c0 irq 22
>>> ata1: failed to resume link (SControl FFFFFFFF)
>>> ata1: SATA link down (SStatus FFFFFFFF SControl FFFFFFFF)
>>> ata2: failed to resume link (SControl FFFFFFFF)
>>> ata2: SATA link down (SStatus FFFFFFFF SControl FFFFFFFF)
>>>
>>> Things of note:
>>> * The 'local memory hole' is a space I have to steal from the PCI
>>> address space so that the Coral-P gets mapped to something other
>>> than PCI memory address 0x0 (relative). This device is dirt stupid
>>> (previously discussed) and refuses to work at 0x0
>>> * The dump after the Coral-P FB line is what it sees in it's memory
>>> space. It _should_ look something like this:
>>> C4140600: FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 |................|
>>> C4140610: FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 |................|
>>> C4140620: FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 |................|
>>> C4140630: FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 |................|
>>> C4140640: FF FF FF 00 FF FF FF 00 FF FD FF 00 FF FD FF 00 |................|
>>> C4140650: FF FD FF 00 FF FD FF 00 FF FD FF 00 FF FD FF 00 |................|
>>> Notice how byte 3 of every longword is 0x00?
>>> * The SATA device driver is failing along similar lines.
>>>
>>> Any ideas what I'm doing wrong? or what I can look at?
>>
>> I can't see anything obviously wrong in what you've pasted there, but I
>> am not familiar with fsl PCI or SoC's, so it's possible that there's
>> something there going on ... We'll have to wait for somebody from FSL to
>> have a look, unless you can find something in the doco.
>
> The curious thing is that this exact same setup works perfectly
> in 2.6.28 and near perfectly in 2.6.32. Unless something else
> changed in the PCI handling between 2.6.32 and 2.6.37, I would
> hope it work work there as well.
>
> I'll keep looking for differences between those two system versions.

I found the problem - a change I had in <2.6.32 that I hadn't
pushed forward.  It seems to be related to how I have the PCI
controller setup (in RedBoot).  Because of this, using these
settings in my DTS make things work properly:
     ranges = <0x02000000 0x0 0x00000000 0xC0000000 0x0 0x20000000
               0x01000000 0x0 0x00000000 0xB8000000 0x0 0x00100000>;
Instead of
     ranges = <0x02000000 0x0 0xC0000000 0xC0000000 0x0 0x20000000
               0x01000000 0x0 0x00000000 0xB8000000 0x0 0x00100000>;

Sorry for the noise (wild goose chase), but discussing it did help
me to work out some PCI issues in general.

Now that this is working, I'm trying to move to the next problem.
The system works fine, but only to a point.  In this [embedded]
system, I have an SIL SATA controller on the PCI bus.  On 2.6.28,
this device is rock solid.  On 2.6.32 and now 2.6.37, I have issues.
Operations work on the device (connected to a SSD), but after some
arbitrary time, an operation will fail, causing the PCI bus (and
indeed the whole system) to hang.  I've tried to peek in using a
BDI and once it hangs, even the BDI can't access the CPU any more.

I'm pretty lost on this one - it will execute hundreds of SATA operations
properly and then die.  Turning on SATA/SCSI traces, I can see the
final operation be issued and there seems to be no substantive difference
between this operation and the previous ones that all worked.  In fact
if I reset and rerun the same program, it _will_ fail but never on
the same operation :-(

Any ideas what could cause this failure?  I have a similar system
that uses a different SATA controller that I'm going to try.  Maybe
it's something peculiar to the SIL device as opposed to generic PCI
operations.

Thanks for any feedback

-- 
------------------------------------------------------------
Gary Thomas                 |  Consulting for the
MLB Associates              |    Embedded world
------------------------------------------------------------

^ permalink raw reply

* Re: [PATCH] USB: Fix USB Kconfig dependency problem on 85xx/QoirQ platforms
From: Kumar Gala @ 2011-01-10 16:22 UTC (permalink / raw)
  To: Xulei Lei-B33228; +Cc: Greg KH, linux-usb, linuxppc-dev
In-Reply-To: <1294654017-32568-1-git-send-email-B33228@freescale.com>


On Jan 10, 2011, at 4:06 AM, Xulei wrote:

> For FSL PPC SoCs USB_ARCH_HAS_EHCI currently on depends on PPC_83xx.
> However that excludes support for USB on 85xx & QorIQ devices.  Use
> FSL_SOC insted which will get us 83xx, 85xx, QorIQ, and 5xxx which all
> have the same USB IP on them.
> 
> Signed-off-by: Xulei <B33228@freescale.com>
> Signed-off-by: Kumar Gala <kumar.gala@freescale.com>
> ---
> drivers/usb/Kconfig |    2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
> index 6a58cb1..d513d3a 100644
> --- a/drivers/usb/Kconfig
> +++ b/drivers/usb/Kconfig
> @@ -57,7 +57,7 @@ config USB_ARCH_HAS_OHCI
> # some non-PCI hcds implement EHCI
> config USB_ARCH_HAS_EHCI
> 	boolean
> -	default y if PPC_83xx
> +	default y if FSL_SOC
> 	default y if SOC_AU1200
> 	default y if ARCH_IXP4XX
> 	default y if ARCH_W90X900
> -- 
> 1.7.0.4

This really should have been CC'd to the USB list & maintainer.

- k

^ permalink raw reply

* Re: mpc880 linux-2.6.32 slow running processes
From: Rafael Beims @ 2011-01-10 16:35 UTC (permalink / raw)
  To: Joakim Tjernlund; +Cc: michael, linuxppc-dev, scottwood, RFeany
In-Reply-To: <OFBA8894F8.FF5AA75D-ONC1257812.00773DA9-C1257812.00776196@transmode.se>

>
> Once you have tested it and it works, please send a patch to remove the 8xx workaround.
> Make sure Scott is cc:ed
>
>

I tested linux-2.6.33 on my ppc880 board today, and even without the
slowdown.patch applied, the board runs processes with good
performance.
It really seems that the problem is solved from linux-2.6.33 on.

I'm not sure what you mean by sending a patch to remove the
workaround. The only thing that I did in the 2.6.32 version was to
apply the slowdown.patch attached in the message from Michael.

Could you clarify please?

Thanks for all the help so far,
Rafael

^ permalink raw reply

* Re: mpc880 linux-2.6.32 slow running processes
From: Joakim Tjernlund @ 2011-01-10 16:55 UTC (permalink / raw)
  To: Rafael Beims; +Cc: michael, linuxppc-dev, scottwood, RFeany
In-Reply-To: <AANLkTi=cAswFh1cFCU=nomd6yg5Ux9jK0x9h9s7f2571@mail.gmail.com>

Rafael Beims <rbeims@gmail.com> wrote on 2011/01/10 17:35:38:
> >
> > Once you have tested it and it works, please send a patch to remove the 8xx workaround.
> > Make sure Scott is cc:ed
> >
> >
>
> I tested linux-2.6.33 on my ppc880 board today, and even without the
> slowdown.patch applied, the board runs processes with good
> performance.
> It really seems that the problem is solved from linux-2.6.33 on.
>
> I'm not sure what you mean by sending a patch to remove the
> workaround. The only thing that I did in the 2.6.32 version was to
> apply the slowdown.patch attached in the message from Michael.
>
> Could you clarify please?

Yes, this part in arch/powerpc/mm/pgtable.c:
#ifdef CONFIG_8xx
			/* On 8xx, cache control instructions (particularly
			 * "dcbst" from flush_dcache_icache) fault as write
			 * operation if there is an unpopulated TLB entry
			 * for the address in question. To workaround that,
			 * we invalidate the TLB here, thus avoiding dcbst
			 * misbehaviour.
			 */
			/* 8xx doesn't care about PID, size or ind args */
			_tlbil_va(addr, 0, 0, 0);
#endif /* CONFIG_8xx */

Should be removed in >= 2.6.33 kernels.
My 8xx TLB work fixes this problem more efficiently.

    Jocke

^ permalink raw reply

* [PATCH 0/4] De-couple sysfs memory directories from memory sections
From: Nathan Fontenot @ 2011-01-10 18:08 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-mm, linuxppc-dev, linux-kernel, KAMEZAWA Hiroyuki,
	Robin Holt

This is a re-send of the remaining patches that did not make it
into the last kernel release for de-coupling sysfs memory
directories from memory sections.  The first three patches of the
previous set went in, and this is the remaining patches that
need to be applied.

The patches decouple the concept that a single memory
section corresponds to a single directory in 
/sys/devices/system/memory/.  On systems
with large amounts of memory (1+ TB) there are performance issues
related to creating the large number of sysfs directories.  For
a powerpc machine with 1 TB of memory we are creating 63,000+
directories.  This is resulting in boot times of around 45-50
minutes for systems with 1 TB of memory and 8 hours for systems
with 2 TB of memory.  With this patch set applied I am now seeing
boot times of 5 minutes or less.

The root of this issue is in sysfs directory creation. Every time
a directory is created a string compare is done against all sibling
directories to ensure we do not create duplicates.  The list of
directory nodes in sysfs is kept as an unsorted list which results
in this being an exponentially longer operation as the number of
directories are created.

The solution solved by this patch set is to allow a single
directory in sysfs to span multiple memory sections.  This is
controlled by an optional architecturally defined function
memory_block_size_bytes().  The default definition of this
routine returns a memory block size equal to the memory section
size. This maintains the current layout of sysfs memory
directories as it appears to userspace to remain the same as it
is today.

For architectures that define their own version of this routine,
as is done for powerpc and x86 in this patchset, the view in userspace
would change such that each memoryXXX directory would span
multiple memory sections.  The number of sections spanned would
depend on the value reported by memory_block_size_bytes.

-Nathan Fontenot

^ permalink raw reply

* [PATCH 1/4] allow memory blocks to span multiple memory sections
From: Nathan Fontenot @ 2011-01-10 18:11 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-mm, linuxppc-dev, linux-kernel, KAMEZAWA Hiroyuki,
	Robin Holt
In-Reply-To: <4D2B4B38.80102@austin.ibm.com>

Update the memory sysfs code such that each sysfs memory directory is now
considered a memory block that can span multiple memory sections per
memory block.  The default size of each memory block is SECTION_SIZE_BITS
to maintain the current behavior of having a single memory section per
memory block (i.e. one sysfs directory per memory section).

For architectures that want to have memory blocks span multiple
memory sections they need only define their own memory_block_size_bytes()
routine.

Update the memory hotplug documentation to reflect the new behaviors of
memory blocks reflected in sysfs.

Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com>
Reviewed-by: Robin Holt <holt@sgi.com>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>

---
 Documentation/memory-hotplug.txt |   47 +++++++----
 drivers/base/memory.c            |  155 +++++++++++++++++++++++++++------------
 2 files changed, 139 insertions(+), 63 deletions(-)

Index: linux-2.6/Documentation/memory-hotplug.txt
===================================================================
--- linux-2.6.orig/Documentation/memory-hotplug.txt	2011-01-05 10:08:16.000000000 -0600
+++ linux-2.6/Documentation/memory-hotplug.txt	2011-01-05 10:17:37.000000000 -0600
@@ -126,36 +126,51 @@ config options.
 --------------------------------
 4 sysfs files for memory hotplug
 --------------------------------
-All sections have their device information under /sys/devices/system/memory as
+All sections have their device information in sysfs.  Each section is part of
+a memory block under /sys/devices/system/memory as
 
 /sys/devices/system/memory/memoryXXX
-(XXX is section id.)
+(XXX is the section id.)
 
-Now, XXX is defined as start_address_of_section / section_size.
+Now, XXX is defined as (start_address_of_section / section_size) of the first
+section contained in the memory block.  The files 'phys_index' and
+'end_phys_index' under each directory report the beginning and end section id's
+for the memory block covered by the sysfs directory.  It is expected that all
+memory sections in this range are present and no memory holes exist in the
+range. Currently there is no way to determine if there is a memory hole, but
+the existence of one should not affect the hotplug capabilities of the memory
+block.
 
 For example, assume 1GiB section size. A device for a memory starting at
 0x100000000 is /sys/device/system/memory/memory4
 (0x100000000 / 1Gib = 4)
 This device covers address range [0x100000000 ... 0x140000000)
 
-Under each section, you can see 4 files.
+Under each section, you can see 4 or 5 files, the end_phys_index file being
+a recent addition and not present on older kernels.
 
-/sys/devices/system/memory/memoryXXX/phys_index
+/sys/devices/system/memory/memoryXXX/start_phys_index
+/sys/devices/system/memory/memoryXXX/end_phys_index
 /sys/devices/system/memory/memoryXXX/phys_device
 /sys/devices/system/memory/memoryXXX/state
 /sys/devices/system/memory/memoryXXX/removable
 
-'phys_index' : read-only and contains section id, same as XXX.
-'state'      : read-write
-               at read:  contains online/offline state of memory.
-               at write: user can specify "online", "offline" command
-'phys_device': read-only: designed to show the name of physical memory device.
-               This is not well implemented now.
-'removable'  : read-only: contains an integer value indicating
-               whether the memory section is removable or not
-               removable.  A value of 1 indicates that the memory
-               section is removable and a value of 0 indicates that
-               it is not removable.
+'phys_index'      : read-only and contains section id of the first section
+		    in the memory block, same as XXX.
+'end_phys_index'  : read-only and contains section id of the last section
+		    in the memory block.
+'state'           : read-write
+                    at read:  contains online/offline state of memory.
+                    at write: user can specify "online", "offline" command
+                    which will be performed on al sections in the block.
+'phys_device'     : read-only: designed to show the name of physical memory
+                    device.  This is not well implemented now.
+'removable'       : read-only: contains an integer value indicating
+                    whether the memory block is removable or not
+                    removable.  A value of 1 indicates that the memory
+                    block is removable and a value of 0 indicates that
+                    it is not removable. A memory block is removable only if
+                    every section in the block is removable.
 
 NOTE:
   These directories/files appear after physical memory hotplug phase.
Index: linux-2.6/drivers/base/memory.c
===================================================================
--- linux-2.6.orig/drivers/base/memory.c	2011-01-05 10:08:16.000000000 -0600
+++ linux-2.6/drivers/base/memory.c	2011-01-05 10:17:37.000000000 -0600
@@ -30,6 +30,14 @@
 static DEFINE_MUTEX(mem_sysfs_mutex);
 
 #define MEMORY_CLASS_NAME	"memory"
+#define MIN_MEMORY_BLOCK_SIZE	(1 << SECTION_SIZE_BITS)
+
+static int sections_per_block;
+
+static inline int base_memory_block_id(int section_nr)
+{
+	return section_nr / sections_per_block;
+}
 
 static struct sysdev_class memory_sysdev_class = {
 	.name = MEMORY_CLASS_NAME,
@@ -84,28 +92,47 @@ EXPORT_SYMBOL(unregister_memory_isolate_
  * register_memory - Setup a sysfs device for a memory block
  */
 static
-int register_memory(struct memory_block *memory, struct mem_section *section)
+int register_memory(struct memory_block *memory)
 {
 	int error;
 
 	memory->sysdev.cls = &memory_sysdev_class;
-	memory->sysdev.id = __section_nr(section);
+	memory->sysdev.id = memory->phys_index / sections_per_block;
 
 	error = sysdev_register(&memory->sysdev);
 	return error;
 }
 
 static void
-unregister_memory(struct memory_block *memory, struct mem_section *section)
+unregister_memory(struct memory_block *memory)
 {
 	BUG_ON(memory->sysdev.cls != &memory_sysdev_class);
-	BUG_ON(memory->sysdev.id != __section_nr(section));
 
 	/* drop the ref. we got in remove_memory_block() */
 	kobject_put(&memory->sysdev.kobj);
 	sysdev_unregister(&memory->sysdev);
 }
 
+unsigned long __weak memory_block_size_bytes(void)
+{
+	return MIN_MEMORY_BLOCK_SIZE;
+}
+
+static unsigned long get_memory_block_size(void)
+{
+	unsigned long block_sz;
+
+	block_sz = memory_block_size_bytes();
+
+	/* Validate blk_sz is a power of 2 and not less than section size */
+	if ((block_sz & (block_sz - 1)) || (block_sz < MIN_MEMORY_BLOCK_SIZE)) {
+		WARN_ON(1);
+		block_sz = MIN_MEMORY_BLOCK_SIZE;
+	}
+
+	return block_sz;
+}
+
 /*
  * use this as the physical section index that this memsection
  * uses.
@@ -116,7 +143,7 @@ static ssize_t show_mem_phys_index(struc
 {
 	struct memory_block *mem =
 		container_of(dev, struct memory_block, sysdev);
-	return sprintf(buf, "%08lx\n", mem->phys_index);
+	return sprintf(buf, "%08lx\n", mem->phys_index / sections_per_block);
 }
 
 /*
@@ -125,13 +152,16 @@ static ssize_t show_mem_phys_index(struc
 static ssize_t show_mem_removable(struct sys_device *dev,
 			struct sysdev_attribute *attr, char *buf)
 {
-	unsigned long start_pfn;
-	int ret;
+	unsigned long i, pfn;
+	int ret = 1;
 	struct memory_block *mem =
 		container_of(dev, struct memory_block, sysdev);
 
-	start_pfn = section_nr_to_pfn(mem->phys_index);
-	ret = is_mem_section_removable(start_pfn, PAGES_PER_SECTION);
+	for (i = 0; i < sections_per_block; i++) {
+		pfn = section_nr_to_pfn(mem->phys_index + i);
+		ret &= is_mem_section_removable(pfn, PAGES_PER_SECTION);
+	}
+
 	return sprintf(buf, "%d\n", ret);
 }
 
@@ -184,17 +214,14 @@ int memory_isolate_notify(unsigned long
  * OK to have direct references to sparsemem variables in here.
  */
 static int
-memory_block_action(struct memory_block *mem, unsigned long action)
+memory_section_action(unsigned long phys_index, unsigned long action)
 {
 	int i;
-	unsigned long psection;
 	unsigned long start_pfn, start_paddr;
 	struct page *first_page;
 	int ret;
-	int old_state = mem->state;
 
-	psection = mem->phys_index;
-	first_page = pfn_to_page(psection << PFN_SECTION_SHIFT);
+	first_page = pfn_to_page(phys_index << PFN_SECTION_SHIFT);
 
 	/*
 	 * The probe routines leave the pages reserved, just
@@ -207,8 +234,8 @@ memory_block_action(struct memory_block
 				continue;
 
 			printk(KERN_WARNING "section number %ld page number %d "
-				"not reserved, was it already online? \n",
-				psection, i);
+				"not reserved, was it already online?\n",
+				phys_index, i);
 			return -EBUSY;
 		}
 	}
@@ -219,18 +246,13 @@ memory_block_action(struct memory_block
 			ret = online_pages(start_pfn, PAGES_PER_SECTION);
 			break;
 		case MEM_OFFLINE:
-			mem->state = MEM_GOING_OFFLINE;
 			start_paddr = page_to_pfn(first_page) << PAGE_SHIFT;
 			ret = remove_memory(start_paddr,
 					    PAGES_PER_SECTION << PAGE_SHIFT);
-			if (ret) {
-				mem->state = old_state;
-				break;
-			}
 			break;
 		default:
-			WARN(1, KERN_WARNING "%s(%p, %ld) unknown action: %ld\n",
-					__func__, mem, action, action);
+			WARN(1, KERN_WARNING "%s(%ld, %ld) unknown action: "
+			     "%ld\n", __func__, phys_index, action, action);
 			ret = -EINVAL;
 	}
 
@@ -240,7 +262,8 @@ memory_block_action(struct memory_block
 static int memory_block_change_state(struct memory_block *mem,
 		unsigned long to_state, unsigned long from_state_req)
 {
-	int ret = 0;
+	int i, ret = 0;
+
 	mutex_lock(&mem->state_mutex);
 
 	if (mem->state != from_state_req) {
@@ -248,8 +271,22 @@ static int memory_block_change_state(str
 		goto out;
 	}
 
-	ret = memory_block_action(mem, to_state);
-	if (!ret)
+	if (to_state == MEM_OFFLINE)
+		mem->state = MEM_GOING_OFFLINE;
+
+	for (i = 0; i < sections_per_block; i++) {
+		ret = memory_section_action(mem->phys_index + i, to_state);
+		if (ret)
+			break;
+	}
+
+	if (ret) {
+		for (i = 0; i < sections_per_block; i++)
+			memory_section_action(mem->phys_index + i,
+					      from_state_req);
+
+		mem->state = from_state_req;
+	} else
 		mem->state = to_state;
 
 out:
@@ -262,20 +299,15 @@ store_mem_state(struct sys_device *dev,
 		struct sysdev_attribute *attr, const char *buf, size_t count)
 {
 	struct memory_block *mem;
-	unsigned int phys_section_nr;
 	int ret = -EINVAL;
 
 	mem = container_of(dev, struct memory_block, sysdev);
-	phys_section_nr = mem->phys_index;
-
-	if (!present_section_nr(phys_section_nr))
-		goto out;
 
 	if (!strncmp(buf, "online", min((int)count, 6)))
 		ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE);
 	else if(!strncmp(buf, "offline", min((int)count, 7)))
 		ret = memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE);
-out:
+
 	if (ret)
 		return ret;
 	return count;
@@ -315,7 +347,7 @@ static ssize_t
 print_block_size(struct sysdev_class *class, struct sysdev_class_attribute *attr,
 		 char *buf)
 {
-	return sprintf(buf, "%lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE);
+	return sprintf(buf, "%lx\n", get_memory_block_size());
 }
 
 static SYSDEV_CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL);
@@ -444,6 +476,7 @@ struct memory_block *find_memory_block_h
 	struct sys_device *sysdev;
 	struct memory_block *mem;
 	char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1];
+	int block_id = base_memory_block_id(__section_nr(section));
 
 	kobj = hint ? &hint->sysdev.kobj : NULL;
 
@@ -451,7 +484,7 @@ struct memory_block *find_memory_block_h
 	 * This only works because we know that section == sysdev->id
 	 * slightly redundant with sysdev_register()
 	 */
-	sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, __section_nr(section));
+	sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, block_id);
 
 	kobj = kset_find_obj_hinted(&memory_sysdev_class.kset, name, kobj);
 	if (!kobj)
@@ -476,26 +509,27 @@ struct memory_block *find_memory_block(s
 	return find_memory_block_hinted(section, NULL);
 }
 
-static int add_memory_block(int nid, struct mem_section *section,
-			unsigned long state, enum mem_add_context context)
+static int init_memory_block(struct memory_block **memory,
+			     struct mem_section *section, unsigned long state)
 {
-	struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+	struct memory_block *mem;
 	unsigned long start_pfn;
+	int scn_nr;
 	int ret = 0;
 
+	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
 	if (!mem)
 		return -ENOMEM;
 
-	mutex_lock(&mem_sysfs_mutex);
-
-	mem->phys_index = __section_nr(section);
+	scn_nr = __section_nr(section);
+	mem->phys_index = base_memory_block_id(scn_nr) * sections_per_block;
 	mem->state = state;
 	mem->section_count++;
 	mutex_init(&mem->state_mutex);
 	start_pfn = section_nr_to_pfn(mem->phys_index);
 	mem->phys_device = arch_get_memory_phys_device(start_pfn);
 
-	ret = register_memory(mem, section);
+	ret = register_memory(mem);
 	if (!ret)
 		ret = mem_create_simple_file(mem, phys_index);
 	if (!ret)
@@ -504,8 +538,29 @@ static int add_memory_block(int nid, str
 		ret = mem_create_simple_file(mem, phys_device);
 	if (!ret)
 		ret = mem_create_simple_file(mem, removable);
+
+	*memory = mem;
+	return ret;
+}
+
+static int add_memory_section(int nid, struct mem_section *section,
+			unsigned long state, enum mem_add_context context)
+{
+	struct memory_block *mem;
+	int ret = 0;
+
+	mutex_lock(&mem_sysfs_mutex);
+
+	mem = find_memory_block(section);
+	if (mem) {
+		mem->section_count++;
+		kobject_put(&mem->sysdev.kobj);
+	} else
+		ret = init_memory_block(&mem, section, state);
+
 	if (!ret) {
-		if (context == HOTPLUG)
+		if (context == HOTPLUG &&
+		    mem->section_count == sections_per_block)
 			ret = register_mem_sect_under_node(mem, nid);
 	}
 
@@ -528,8 +583,10 @@ int remove_memory_block(unsigned long no
 		mem_remove_simple_file(mem, state);
 		mem_remove_simple_file(mem, phys_device);
 		mem_remove_simple_file(mem, removable);
-		unregister_memory(mem, section);
-	}
+		unregister_memory(mem);
+		kfree(mem);
+	} else
+		kobject_put(&mem->sysdev.kobj);
 
 	mutex_unlock(&mem_sysfs_mutex);
 	return 0;
@@ -541,7 +598,7 @@ int remove_memory_block(unsigned long no
  */
 int register_new_memory(int nid, struct mem_section *section)
 {
-	return add_memory_block(nid, section, MEM_OFFLINE, HOTPLUG);
+	return add_memory_section(nid, section, MEM_OFFLINE, HOTPLUG);
 }
 
 int unregister_memory_section(struct mem_section *section)
@@ -560,12 +617,16 @@ int __init memory_dev_init(void)
 	unsigned int i;
 	int ret;
 	int err;
+	unsigned long block_sz;
 
 	memory_sysdev_class.kset.uevent_ops = &memory_uevent_ops;
 	ret = sysdev_class_register(&memory_sysdev_class);
 	if (ret)
 		goto out;
 
+	block_sz = get_memory_block_size();
+	sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE;
+
 	/*
 	 * Create entries for memory sections that were found
 	 * during boot and have been initialized
@@ -573,8 +634,8 @@ int __init memory_dev_init(void)
 	for (i = 0; i < NR_MEM_SECTIONS; i++) {
 		if (!present_section_nr(i))
 			continue;
-		err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE,
-				       BOOT);
+		err = add_memory_section(0, __nr_to_section(i), MEM_ONLINE,
+					 BOOT);
 		if (!ret)
 			ret = err;
 	}

^ permalink raw reply

* [PATCH 2/4] Update phys_index to [start|end]_section_nr
From: Nathan Fontenot @ 2011-01-10 18:13 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-mm, linuxppc-dev, linux-kernel, KAMEZAWA Hiroyuki,
	Robin Holt
In-Reply-To: <4D2B4B38.80102@austin.ibm.com>

Update the 'phys_index' property of a the memory_block struct to be
called start_section_nr, and add a end_section_nr property.  The
data tracked here is the same but the updated naming is more in line
with what is stored here, namely the first and last section number
that the memory block spans.

The names presented to userspace remain the same, phys_index for
start_section_nr and end_phys_index for end_section_nr, to avoid breaking
anything in userspace.

This also updates the node sysfs code to be aware of the new capability for
a memory block to contain multiple memory sections and be aware of the memory
block structure name changes (start_section_nr).  This requires an additional
parameter to unregister_mem_sect_under_nodes so that we know which memory
section of the memory block to unregister.

Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com>
Reviewed-by: Robin Holt <holt@sgi.com>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>

---
 drivers/base/memory.c  |   41 +++++++++++++++++++++++++++++++----------
 drivers/base/node.c    |   12 ++++++++----
 include/linux/memory.h |    3 ++-
 include/linux/node.h   |    6 ++++--
 4 files changed, 45 insertions(+), 17 deletions(-)

Index: linux-2.6/drivers/base/memory.c
===================================================================
--- linux-2.6.orig/drivers/base/memory.c	2011-01-05 10:17:37.000000000 -0600
+++ linux-2.6/drivers/base/memory.c	2011-01-05 10:17:46.000000000 -0600
@@ -97,7 +97,7 @@ int register_memory(struct memory_block
 	int error;
 
 	memory->sysdev.cls = &memory_sysdev_class;
-	memory->sysdev.id = memory->phys_index / sections_per_block;
+	memory->sysdev.id = memory->start_section_nr / sections_per_block;
 
 	error = sysdev_register(&memory->sysdev);
 	return error;
@@ -138,12 +138,26 @@ static unsigned long get_memory_block_si
  * uses.
  */
 
-static ssize_t show_mem_phys_index(struct sys_device *dev,
+static ssize_t show_mem_start_phys_index(struct sys_device *dev,
 			struct sysdev_attribute *attr, char *buf)
 {
 	struct memory_block *mem =
 		container_of(dev, struct memory_block, sysdev);
-	return sprintf(buf, "%08lx\n", mem->phys_index / sections_per_block);
+	unsigned long phys_index;
+
+	phys_index = mem->start_section_nr / sections_per_block;
+	return sprintf(buf, "%08lx\n", phys_index);
+}
+
+static ssize_t show_mem_end_phys_index(struct sys_device *dev,
+			struct sysdev_attribute *attr, char *buf)
+{
+	struct memory_block *mem =
+		container_of(dev, struct memory_block, sysdev);
+	unsigned long phys_index;
+
+	phys_index = mem->end_section_nr / sections_per_block;
+	return sprintf(buf, "%08lx\n", phys_index);
 }
 
 /*
@@ -158,7 +172,7 @@ static ssize_t show_mem_removable(struct
 		container_of(dev, struct memory_block, sysdev);
 
 	for (i = 0; i < sections_per_block; i++) {
-		pfn = section_nr_to_pfn(mem->phys_index + i);
+		pfn = section_nr_to_pfn(mem->start_section_nr + i);
 		ret &= is_mem_section_removable(pfn, PAGES_PER_SECTION);
 	}
 
@@ -275,14 +289,15 @@ static int memory_block_change_state(str
 		mem->state = MEM_GOING_OFFLINE;
 
 	for (i = 0; i < sections_per_block; i++) {
-		ret = memory_section_action(mem->phys_index + i, to_state);
+		ret = memory_section_action(mem->start_section_nr + i,
+					    to_state);
 		if (ret)
 			break;
 	}
 
 	if (ret) {
 		for (i = 0; i < sections_per_block; i++)
-			memory_section_action(mem->phys_index + i,
+			memory_section_action(mem->start_section_nr + i,
 					      from_state_req);
 
 		mem->state = from_state_req;
@@ -330,7 +345,8 @@ static ssize_t show_phys_device(struct s
 	return sprintf(buf, "%d\n", mem->phys_device);
 }
 
-static SYSDEV_ATTR(phys_index, 0444, show_mem_phys_index, NULL);
+static SYSDEV_ATTR(phys_index, 0444, show_mem_start_phys_index, NULL);
+static SYSDEV_ATTR(end_phys_index, 0444, show_mem_end_phys_index, NULL);
 static SYSDEV_ATTR(state, 0644, show_mem_state, store_mem_state);
 static SYSDEV_ATTR(phys_device, 0444, show_phys_device, NULL);
 static SYSDEV_ATTR(removable, 0444, show_mem_removable, NULL);
@@ -522,17 +538,21 @@ static int init_memory_block(struct memo
 		return -ENOMEM;
 
 	scn_nr = __section_nr(section);
-	mem->phys_index = base_memory_block_id(scn_nr) * sections_per_block;
+	mem->start_section_nr =
+			base_memory_block_id(scn_nr) * sections_per_block;
+	mem->end_section_nr = mem->start_section_nr + sections_per_block - 1;
 	mem->state = state;
 	mem->section_count++;
 	mutex_init(&mem->state_mutex);
-	start_pfn = section_nr_to_pfn(mem->phys_index);
+	start_pfn = section_nr_to_pfn(mem->start_section_nr);
 	mem->phys_device = arch_get_memory_phys_device(start_pfn);
 
 	ret = register_memory(mem);
 	if (!ret)
 		ret = mem_create_simple_file(mem, phys_index);
 	if (!ret)
+		ret = mem_create_simple_file(mem, end_phys_index);
+	if (!ret)
 		ret = mem_create_simple_file(mem, state);
 	if (!ret)
 		ret = mem_create_simple_file(mem, phys_device);
@@ -575,11 +595,12 @@ int remove_memory_block(unsigned long no
 
 	mutex_lock(&mem_sysfs_mutex);
 	mem = find_memory_block(section);
+	unregister_mem_sect_under_nodes(mem, __section_nr(section));
 
 	mem->section_count--;
 	if (mem->section_count == 0) {
-		unregister_mem_sect_under_nodes(mem);
 		mem_remove_simple_file(mem, phys_index);
+		mem_remove_simple_file(mem, end_phys_index);
 		mem_remove_simple_file(mem, state);
 		mem_remove_simple_file(mem, phys_device);
 		mem_remove_simple_file(mem, removable);
Index: linux-2.6/drivers/base/node.c
===================================================================
--- linux-2.6.orig/drivers/base/node.c	2011-01-05 10:08:15.000000000 -0600
+++ linux-2.6/drivers/base/node.c	2011-01-05 10:17:46.000000000 -0600
@@ -360,8 +360,10 @@ int register_mem_sect_under_node(struct
 		return -EFAULT;
 	if (!node_online(nid))
 		return 0;
-	sect_start_pfn = section_nr_to_pfn(mem_blk->phys_index);
-	sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1;
+
+	sect_start_pfn = section_nr_to_pfn(mem_blk->start_section_nr);
+	sect_end_pfn = section_nr_to_pfn(mem_blk->end_section_nr);
+	sect_end_pfn += PAGES_PER_SECTION - 1;
 	for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) {
 		int page_nid;
 
@@ -385,7 +387,8 @@ int register_mem_sect_under_node(struct
 }
 
 /* unregister memory section under all nodes that it spans */
-int unregister_mem_sect_under_nodes(struct memory_block *mem_blk)
+int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
+				    unsigned long phys_index)
 {
 	NODEMASK_ALLOC(nodemask_t, unlinked_nodes, GFP_KERNEL);
 	unsigned long pfn, sect_start_pfn, sect_end_pfn;
@@ -397,7 +400,8 @@ int unregister_mem_sect_under_nodes(stru
 	if (!unlinked_nodes)
 		return -ENOMEM;
 	nodes_clear(*unlinked_nodes);
-	sect_start_pfn = section_nr_to_pfn(mem_blk->phys_index);
+
+	sect_start_pfn = section_nr_to_pfn(phys_index);
 	sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1;
 	for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) {
 		int nid;
Index: linux-2.6/include/linux/memory.h
===================================================================
--- linux-2.6.orig/include/linux/memory.h	2011-01-05 10:08:15.000000000 -0600
+++ linux-2.6/include/linux/memory.h	2011-01-05 10:17:46.000000000 -0600
@@ -21,7 +21,8 @@
 #include <linux/mutex.h>
 
 struct memory_block {
-	unsigned long phys_index;
+	unsigned long start_section_nr;
+	unsigned long end_section_nr;
 	unsigned long state;
 	int section_count;
 
Index: linux-2.6/include/linux/node.h
===================================================================
--- linux-2.6.orig/include/linux/node.h	2011-01-05 10:08:15.000000000 -0600
+++ linux-2.6/include/linux/node.h	2011-01-05 10:17:46.000000000 -0600
@@ -39,7 +39,8 @@ extern int register_cpu_under_node(unsig
 extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid);
 extern int register_mem_sect_under_node(struct memory_block *mem_blk,
 						int nid);
-extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk);
+extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
+					   unsigned long phys_index);
 
 #ifdef CONFIG_HUGETLBFS
 extern void register_hugetlbfs_with_node(node_registration_func_t doregister,
@@ -67,7 +68,8 @@ static inline int register_mem_sect_unde
 {
 	return 0;
 }
-static inline int unregister_mem_sect_under_nodes(struct memory_block *mem_blk)
+static inline int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
+						  unsigned long phys_index)
 {
 	return 0;
 }

^ permalink raw reply

* [PATCH 3/4] Define memory_block_size_bytes for powerpc/pseries
From: Nathan Fontenot @ 2011-01-10 18:14 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-mm, linuxppc-dev, linux-kernel, KAMEZAWA Hiroyuki,
	Robin Holt
In-Reply-To: <4D2B4B38.80102@austin.ibm.com>

Define a version of memory_block_size_bytes() for powerpc/pseries such that
a memory block spans an entire lmb.

Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com>
Reviewed-by: Robin Holt <holt@sgi.com>

---
 arch/powerpc/platforms/pseries/hotplug-memory.c |   66 +++++++++++++++++++-----
 1 file changed, 53 insertions(+), 13 deletions(-)

Index: linux-2.6/arch/powerpc/platforms/pseries/hotplug-memory.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/pseries/hotplug-memory.c	2011-01-05 10:08:14.000000000 -0600
+++ linux-2.6/arch/powerpc/platforms/pseries/hotplug-memory.c	2011-01-05 10:17:49.000000000 -0600
@@ -17,6 +17,54 @@
 #include <asm/pSeries_reconfig.h>
 #include <asm/sparsemem.h>
 
+static unsigned long get_memblock_size(void)
+{
+	struct device_node *np;
+	unsigned int memblock_size = 0;
+
+	np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
+	if (np) {
+		const unsigned long *size;
+
+		size = of_get_property(np, "ibm,lmb-size", NULL);
+		memblock_size = size ? *size : 0;
+
+		of_node_put(np);
+	} else {
+		unsigned int memzero_size = 0;
+		const unsigned int *regs;
+
+		np = of_find_node_by_path("/memory@0");
+		if (np) {
+			regs = of_get_property(np, "reg", NULL);
+			memzero_size = regs ? regs[3] : 0;
+			of_node_put(np);
+		}
+
+		if (memzero_size) {
+			/* We now know the size of memory@0, use this to find
+			 * the first memoryblock and get its size.
+			 */
+			char buf[64];
+
+			sprintf(buf, "/memory@%x", memzero_size);
+			np = of_find_node_by_path(buf);
+			if (np) {
+				regs = of_get_property(np, "reg", NULL);
+				memblock_size = regs ? regs[3] : 0;
+				of_node_put(np);
+			}
+		}
+	}
+
+	return memblock_size;
+}
+
+unsigned long memory_block_size_bytes(void)
+{
+	return get_memblock_size();
+}
+
 static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size)
 {
 	unsigned long start, start_pfn;
@@ -127,30 +175,22 @@ static int pseries_add_memory(struct dev
 
 static int pseries_drconf_memory(unsigned long *base, unsigned int action)
 {
-	struct device_node *np;
-	const unsigned long *lmb_size;
+	unsigned long memblock_size;
 	int rc;
 
-	np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
-	if (!np)
+	memblock_size = get_memblock_size();
+	if (!memblock_size)
 		return -EINVAL;
 
-	lmb_size = of_get_property(np, "ibm,lmb-size", NULL);
-	if (!lmb_size) {
-		of_node_put(np);
-		return -EINVAL;
-	}
-
 	if (action == PSERIES_DRCONF_MEM_ADD) {
-		rc = memblock_add(*base, *lmb_size);
+		rc = memblock_add(*base, memblock_size);
 		rc = (rc < 0) ? -EINVAL : 0;
 	} else if (action == PSERIES_DRCONF_MEM_REMOVE) {
-		rc = pseries_remove_memblock(*base, *lmb_size);
+		rc = pseries_remove_memblock(*base, memblock_size);
 	} else {
 		rc = -EINVAL;
 	}
 
-	of_node_put(np);
 	return rc;
 }
 

^ permalink raw reply

* [PATCH 4/4] Define memory_block_size_bytes for x86_64 with CONFIG_X86_UV defined
From: Nathan Fontenot @ 2011-01-10 18:16 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-mm, linuxppc-dev, linux-kernel, KAMEZAWA Hiroyuki,
	Robin Holt
In-Reply-To: <4D2B4B38.80102@austin.ibm.com>

Define a version of memory_block_size_bytes for x86_64 when CONFIG_X86_UV is
set.

Signed-off-by: Robin Holt <holt@sgi.com>
Signed-off-by: Jack Steiner <steiner@sgi.com>
Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com>

---
 arch/x86/mm/init_64.c |   14 ++++++++++++++
 1 file changed, 14 insertions(+)

Index: linux-2.6/arch/x86/mm/init_64.c
===================================================================
--- linux-2.6.orig/arch/x86/mm/init_64.c	2011-01-05 10:08:13.000000000 -0600
+++ linux-2.6/arch/x86/mm/init_64.c	2011-01-05 10:17:51.000000000 -0600
@@ -51,6 +51,7 @@
 #include <asm/numa.h>
 #include <asm/cacheflush.h>
 #include <asm/init.h>
+#include <asm/uv/uv.h>
 
 static int __init parse_direct_gbpages_off(char *arg)
 {
@@ -908,6 +909,19 @@ const char *arch_vma_name(struct vm_area
 	return NULL;
 }
 
+#ifdef CONFIG_X86_UV
+#define MIN_MEMORY_BLOCK_SIZE   (1 << SECTION_SIZE_BITS)
+
+unsigned long memory_block_size_bytes(void)
+{
+	if (is_uv_system()) {
+		printk(KERN_INFO "UV: memory block size 2GB\n");
+		return 2UL * 1024 * 1024 * 1024;
+	}
+	return MIN_MEMORY_BLOCK_SIZE;
+}
+#endif
+
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
 /*
  * Initialise the sparsemem vmemmap using huge-pages at the PMD level.

^ permalink raw reply

* Re: [PATCH 0/4] De-couple sysfs memory directories from memory sections
From: Greg KH @ 2011-01-10 18:44 UTC (permalink / raw)
  To: Nathan Fontenot
  Cc: linux-mm, linuxppc-dev, linux-kernel, KAMEZAWA Hiroyuki,
	Robin Holt
In-Reply-To: <4D2B4B38.80102@austin.ibm.com>

On Mon, Jan 10, 2011 at 12:08:56PM -0600, Nathan Fontenot wrote:
> This is a re-send of the remaining patches that did not make it
> into the last kernel release for de-coupling sysfs memory
> directories from memory sections.  The first three patches of the
> previous set went in, and this is the remaining patches that
> need to be applied.

Well, it's a bit late right now, as we are merging stuff that is already
in our trees, and we are busy with that, so this is likely to be ignored
until after .38-rc1 is out.

So, care to resend this after .38-rc1 is out so people can pay attention
to it?


> The root of this issue is in sysfs directory creation. Every time
> a directory is created a string compare is done against all sibling
> directories to ensure we do not create duplicates.  The list of
> directory nodes in sysfs is kept as an unsorted list which results
> in this being an exponentially longer operation as the number of
> directories are created.

Are you sure this is still an issue?  I thought we solved this last
kernel or so with a simple patch?

thanks,

greg k-h

^ 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