Re: GPMC in device tree

2015-08-05 Thread Ran Shalit
On Wed, Aug 5, 2015 at 6:56 AM, Ran Shalit ransha...@gmail.com wrote:
 On Wed, Aug 5, 2015 at 12:25 AM, Scott Wood scottw...@freescale.com wrote:
 On Wed, 2015-08-05 at 00:22 +0300, Ran Shalit wrote:
 On Tue, Aug 4, 2015 at 11:31 PM, Scott Wood scottw...@freescale.com wrote:
  On Tue, 2015-08-04 at 23:26 +0300, Ran Shalit wrote:
   On Tue, Aug 4, 2015 at 9:54 PM, Scott Wood scottw...@freescale.com
   wrote:
On Tue, 2015-08-04 at 18:29 +0300, Ran Shalit wrote:
 Hello,

 I would please like to ask if describing flash nor used with GPMC,
 whould be done as described in:
 https://www.kernel.org/doc/Documentation/devicetree/bindings/mtd/gpmc-nor.txt
 It is described in the above link as TI's GPMC, so I'm not sure if
 it is relevent for powerpc too.
   
That binding is for TI GPMC.
   
Are you saying you have some PPC chip that has a flash controller
called
GPMC?
   
-Scott
   
  
   Hi Scott,
  
   Thanks, I've worked with TI's chips, so I now understand that I made
   here some confusion...
   It is GPCM , not GPMC, my mistake.
   We already configured it in u-boot, but on doing read/write from
   kernel it doesn not work.
   It seems that for the linux to use the correct driver, we need to
   define the nor in the device tree.
   Is there any example how to define nor GPCM in device tree ? Is it
   possible not to override the existing GPCM configuration ?
 
  Pretty much all of the mpc8xxx/qoriq device trees have GPCM NOR defined.
  See
  Documentation/devicetree/bindings/powerpc/fsl/lbc.txt and examples such as
  arch/powerpc/boot/dts/p4080ds.dts (part of the lbc node is in
  arch/powerpc/boot/dts/fsl/p4080si-post.dtsi).
 
  Linux will not change the GPCM configuration.
 
  -Scott
 

 On more thing, if I may.
 The localbus is also connected to nvram  cpld.
 I've noticed that read/write works well, even though I didn't define
 anything in device tree.
 Is there any reasom to add these devices into device tree, or can we
 use the cpld and nvram without the definition in device tree ?

 I don't know what you're doing in your kernel to access devices that aren't
 in the device tree.  You should add the devices to the device tree, and have
 the kernel use it rather than hardcoded info.

 -Scott

 Hi,

 Yes I understand.
 But It is worse noting that I have no localbus entry in the device tree.
 Yes, The nvram, cpld which are both connected to device tree, seems to
 work without any issues.

 Thanks,
 Ran

I apologyze for the bad english, I meant it worth to note that there
is no localbus entry at all in the device tree.
So I wander how the nvram and cpld worked...
If I may please ask, what should be the compatible for generic
devices such as  nvram/cpld ?
I assume that if they worked without any entry, it means that there is
no need for specific driver.

Regards,
Ran
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: powerpc: Add an inline function to update HID0

2015-08-05 Thread Gautham R Shenoy
Hi Segher,

Thanks for the suggestions. I will rename the function to
update_power8_hid0() and use asm volatile.


On Tue, Aug 04, 2015 at 09:30:57PM -0500, Segher Boessenkool wrote:
 On Tue, Aug 04, 2015 at 08:08:58PM +1000, Michael Ellerman wrote:
   +static inline void update_hid0(unsigned long hid0)
   +{
   + /*
   +  *  The HID0 update should at the very least be preceded by a
   +  *  a SYNC instruction followed by an ISYNC instruction
   +  */
   + mb();
   + mtspr(SPRN_HID0, hid0);
   + isync();
  
  That's going to turn into three separate inline asm blocks, which is maybe a
  bit unfortunate. Have you checked the generated code is what we want, ie. 
  just
  sync, mtspr, isync ?
 
 The mb() is not such a great name anyway: you don't want a memory
 barrier, you want an actual sync instruction (sync 0, hwsync,
 whatever the currently preferred spelling is).
 
 The function name should also say this is for POWER8 (the required
 sequences are different for some other processors; and some others
 might not even _have_ a HID0, or not at 1008).  power8_write_hid0
 or such?
 
 For writing it as one asm, why not just
 
   asm volatile(sync ; mtspr %0,%1 ; isync : : i(SPRN_HID0), r(hid0));
 
 instead of the stringify stuff?
 
 
 Segher
 

--
Thanks and Regards
gautham.

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v3] powerpc: Add an inline function to update POWER8 HID0

2015-08-05 Thread Gautham R. Shenoy
Section 3.7 of Version 1.2 of the Power8 Processor User's Manual
prescribes that updates to HID0 be preceded by a SYNC instruction and
followed by an ISYNC instruction (Page 91).

Create an inline function name update_power8_hid0() which follows this
recipe and invoke it from the static split core path.

Signed-off-by: Gautham R. Shenoy e...@linux.vnet.ibm.com
---
[v1 -- v2: Moved defn of update_hid0 to reg.h from kvm_ppc.h]
[v2 -- v3: Renamed to update_power8_hid0 and used asm volatile]

 arch/powerpc/include/asm/reg.h   | 9 +
 arch/powerpc/platforms/powernv/subcore.c | 4 ++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index af56b5c..1245d99 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -1281,6 +1281,15 @@ struct pt_regs;
 
 extern void ppc_save_regs(struct pt_regs *regs);
 
+static inline void update_power8_hid0(unsigned long hid0)
+{
+   /*
+*  The HID0 update on Power8 should at the very least be
+*  preceded by a a SYNC instruction followed by an ISYNC
+*  instruction
+*/
+   asm volatile(sync; mtspr %0,%1; isync:: i(SPRN_HID0), r(hid0));
+}
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_REG_H */
diff --git a/arch/powerpc/platforms/powernv/subcore.c 
b/arch/powerpc/platforms/powernv/subcore.c
index f60f80a..503a73f 100644
--- a/arch/powerpc/platforms/powernv/subcore.c
+++ b/arch/powerpc/platforms/powernv/subcore.c
@@ -190,7 +190,7 @@ static void unsplit_core(void)
 
hid0 = mfspr(SPRN_HID0);
hid0 = ~HID0_POWER8_DYNLPARDIS;
-   mtspr(SPRN_HID0, hid0);
+   update_power8_hid0(hid0);
update_hid_in_slw(hid0);
 
while (mfspr(SPRN_HID0)  mask)
@@ -227,7 +227,7 @@ static void split_core(int new_mode)
/* Write new mode */
hid0  = mfspr(SPRN_HID0);
hid0 |= HID0_POWER8_DYNLPARDIS | split_parms[i].value;
-   mtspr(SPRN_HID0, hid0);
+   update_power8_hid0(hid0);
update_hid_in_slw(hid0);
 
/* Wait for it to happen */
-- 
1.9.3

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC v4] genalloc:support memory-allocation with bytes-alignment to genalloc

2015-08-05 Thread Zhao Qiang
Bytes alignment is required to manage some special RAM,
so add gen_pool_first_fit_align to genalloc,
meanwhile add gen_pool_alloc_data to pass data to
gen_pool_first_fit_align(modify gen_pool_alloc as a wrapper)

Signed-off-by: Zhao Qiang qiang.z...@freescale.com
---
*v2:
changes:
title has been modified, original patch link: 
http://patchwork.ozlabs.org/patch/493297/

original patch add a func gen_pool_alloc_align, 
then pass alignment to it as an parameter.
after discussing with lauraa and scott, they recommend 
to pass alignment as part of data based on 
commit message for ca279cf1065fb689abea1dc7d8c11787729bb185 which adds data:

As I can't predict all the possible requirements/needs for all allocation
uses cases, I add a free field 'void *data' to pass any needed 
information to the allocation function.  For example 'data' could be used 
to handle a structure where you store the alignment, the expected memory 
bank, the requester device, or any information that could influence the 
allocation algorithm.

*v3:
changes:
title has been modified, original patch link: 
http://patchwork.ozlabs.org/patch/500317/

according to the comments, add gen_pool_alloc_data,
modify gen_pool_alloc as a wrapper, define struct data_align
for gen_pool_first_fit_align algorithm. add parameter 
pointer pool to algorithm.

*v4:
changes:
v3 link: 
http://patchwork.ozlabs.org/patch/500317/
There are comments for v3, according to the comments,
modify the patch for v4. such as modifying annotations,
removing unnecessary chek, removing unnecessary cast and so on.

 include/linux/genalloc.h | 23 +++
 lib/genalloc.c   | 58 +++-
 2 files changed, 72 insertions(+), 9 deletions(-)

diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h
index 1ccaab4..55da07e 100644
--- a/include/linux/genalloc.h
+++ b/include/linux/genalloc.h
@@ -34,6 +34,7 @@
 
 struct device;
 struct device_node;
+struct gen_pool;
 
 /**
  * Allocation callback function type definition
@@ -47,7 +48,7 @@ typedef unsigned long (*genpool_algo_t)(unsigned long *map,
unsigned long size,
unsigned long start,
unsigned int nr,
-   void *data);
+   void *data, struct gen_pool *pool);
 
 /*
  *  General purpose special memory pool descriptor.
@@ -73,6 +74,13 @@ struct gen_pool_chunk {
unsigned long bits[0];  /* bitmap for allocating memory chunk */
 };
 
+/*
+ *  gen_pool data descriptor for gen_pool_first_fit_align.
+ */
+struct genpool_data_align {
+   int align;  /* alignment by bytes for starting address */
+};
+
 extern struct gen_pool *gen_pool_create(int, int);
 extern phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long);
 extern int gen_pool_add_virt(struct gen_pool *, unsigned long, phys_addr_t,
@@ -96,6 +104,7 @@ static inline int gen_pool_add(struct gen_pool *pool, 
unsigned long addr,
 }
 extern void gen_pool_destroy(struct gen_pool *);
 extern unsigned long gen_pool_alloc(struct gen_pool *, size_t);
+extern unsigned long gen_pool_alloc_data(struct gen_pool *, size_t, void 
*data);
 extern void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size,
dma_addr_t *dma);
 extern void gen_pool_free(struct gen_pool *, unsigned long, size_t);
@@ -108,14 +117,20 @@ extern void gen_pool_set_algo(struct gen_pool *pool, 
genpool_algo_t algo,
void *data);
 
 extern unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size,
-   unsigned long start, unsigned int nr, void *data);
+   unsigned long start, unsigned int nr, void *data,
+   struct gen_pool *pool);
+
+extern unsigned long gen_pool_first_fit_align(unsigned long *map,
+   unsigned long size, unsigned long start, unsigned int nr,
+   void *data, struct gen_pool *pool);
 
 extern unsigned long gen_pool_first_fit_order_align(unsigned long *map,
unsigned long size, unsigned long start, unsigned int nr,
-   void *data);
+   void *data, struct gen_pool *pool);
 
 extern unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size,
-   unsigned long start, unsigned int nr, void *data);
+   unsigned long start, unsigned int nr, void *data,
+   struct gen_pool *pool);
 
 extern struct gen_pool *devm_gen_pool_create(struct device *dev,
int min_alloc_order, int nid);
diff --git a/lib/genalloc.c b/lib/genalloc.c
index d214866..fe11a00 100644
--- a/lib/genalloc.c
+++ b/lib/genalloc.c
@@ -269,6 +269,24 @@ EXPORT_SYMBOL(gen_pool_destroy);
  */
 unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)
 {
+   return gen_pool_alloc_data(pool, size, pool-data);
+}
+EXPORT_SYMBOL(gen_pool_alloc);
+
+/**
+ * gen_pool_alloc_data - allocate special memory from the pool

[v4, 2/2] powerpc/mpc85xx: Add FSL QorIQ DPAA FMan support to the SoC device tree(s)

2015-08-05 Thread Igal . Liberman
From: Igal Liberman igal.liber...@freescale.com

Based on prior work by Andy Fleming aflem...@freescale.com

Signed-off-by: Shruti Kanetkar shr...@freescale.com
Signed-off-by: Emil Medve emilian.me...@freescale.com
Signed-off-by: Igal Liberman igal.liber...@freescale.com
---

v3 --- v4:
- No changes in this patch

v2 --- v3:
- Removed P1023 support

v1 --- v2:
- Added T1024 support

 arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi  |9 ++-
 arch/powerpc/boot/dts/fsl/b4860si-post.dtsi |   20 +-
 arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi  |   12 +++-
 arch/powerpc/boot/dts/fsl/b4si-post.dtsi|   31 +-
 arch/powerpc/boot/dts/fsl/p2041si-post.dtsi |   29 -
 arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi  |   10 ++-
 arch/powerpc/boot/dts/fsl/p3041si-post.dtsi |   29 -
 arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi  |   10 ++-
 arch/powerpc/boot/dts/fsl/p4080si-post.dtsi |   48 ++-
 arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi  |   15 -
 arch/powerpc/boot/dts/fsl/p5020si-post.dtsi |   29 -
 arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi  |   10 ++-
 arch/powerpc/boot/dts/fsl/p5040si-post.dtsi |   56 -
 arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi  |   17 +-
 arch/powerpc/boot/dts/fsl/t1023si-post.dtsi |   19 ++
 arch/powerpc/boot/dts/fsl/t102xsi-pre.dtsi  |6 ++
 arch/powerpc/boot/dts/fsl/t1040si-post.dtsi |   31 ++
 arch/powerpc/boot/dts/fsl/t104xsi-pre.dtsi  |9 ++-
 arch/powerpc/boot/dts/fsl/t2081si-post.dtsi |   43 +
 arch/powerpc/boot/dts/fsl/t208xsi-pre.dtsi  |   11 
 arch/powerpc/boot/dts/fsl/t4240si-post.dtsi |   88 ++-
 arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi  |   22 ++-
 22 files changed, 536 insertions(+), 18 deletions(-)

diff --git a/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi 
b/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi
index 9cfeaef..5d54ec7 100644
--- a/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi
@@ -1,7 +1,7 @@
 /*
  * B4420 Silicon/SoC Device Tree Source (pre include)
  *
- * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012 - 2015 Freescale Semiconductor, Inc.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -54,8 +54,13 @@
dma0 = dma0;
dma1 = dma1;
sdhc = sdhc;
-   };
 
+   fman0 = fman0;
+   ethernet0 = enet0;
+   ethernet1 = enet1;
+   ethernet2 = enet2;
+   ethernet3 = enet3;
+   };
 
cpus {
#address-cells = 1;
diff --git a/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi 
b/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi
index 26585d6..3065833 100644
--- a/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi
@@ -1,7 +1,7 @@
 /*
  * B4860 Silicon/SoC Device Tree Source (post include)
  *
- * Copyright 2012 - 2014 Freescale Semiconductor Inc.
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -271,6 +271,24 @@
compatible = fsl,b4860-rcpm, fsl,qoriq-rcpm-2.0;
};
 
+/include/ qoriq-fman3-0-1g-4.dtsi
+/include/ qoriq-fman3-0-1g-5.dtsi
+/include/ qoriq-fman3-0-10g-0.dtsi
+/include/ qoriq-fman3-0-10g-1.dtsi
+   fman@40 {
+   enet4: ethernet@e8000 {
+   };
+
+   enet5: ethernet@ea000 {
+   };
+
+   enet6: ethernet@f {
+   };
+
+   enet7: ethernet@f2000 {
+   };
+   };
+
L2: l2-cache-controller@c2 {
compatible = fsl,b4860-l2-cache-controller;
};
diff --git a/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi 
b/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi
index bc914f2..a738f7c 100644
--- a/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi
@@ -1,7 +1,7 @@
 /*
  * B4860 Silicon/SoC Device Tree Source (pre include)
  *
- * Copyright 2012 Freescale Semiconductor Inc.
+ * Copyright 2012 - 2015 Freescale Semiconductor Inc.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -54,6 +54,16 @@
dma0 = dma0;
dma1 = dma1;
sdhc = sdhc;
+
+   fman0 = fman0;
+   ethernet0 = enet0;
+   ethernet1 = enet1;
+   ethernet2 = enet2;
+   ethernet3 = enet3;
+   ethernet4 = enet4;
+   ethernet5 = enet5;
+   ethernet6 = enet6;
+   ethernet7 = enet7;
};
 
 
diff --git 

Re: [PATCH 1/8] misc: cxl: clean up afu_read_config()

2015-08-05 Thread Michael Neuling
On Mon, 2015-07-27 at 00:18 +0300, Vladimir Zapolskiy wrote:
 The sanity checks for overflow are not needed, because this is done on
 caller side in fs/sysfs/file.c
 
 Signed-off-by: Vladimir Zapolskiy v...@mleia.com
 Cc: linuxppc-dev@lists.ozlabs.org
 Cc: Ian Munsie imun...@au1.ibm.com
 Cc: Michael Neuling mi...@neuling.org

Acked-by: Michael Neuling mi...@neuling.org

 ---
  drivers/misc/cxl/sysfs.c | 7 +--
  1 file changed, 1 insertion(+), 6 deletions(-)
 
 diff --git a/drivers/misc/cxl/sysfs.c b/drivers/misc/cxl/sysfs.c
 index 31f38bc..87cd747 100644
 --- a/drivers/misc/cxl/sysfs.c
 +++ b/drivers/misc/cxl/sysfs.c
 @@ -443,12 +443,7 @@ static ssize_t afu_read_config(struct file *filp, struct 
 kobject *kobj,
   struct afu_config_record *cr = to_cr(kobj);
   struct cxl_afu *afu = to_cxl_afu(container_of(kobj-parent, struct 
 device, kobj));
  
 - u64 i, j, val, size = afu-crs_len;
 -
 - if (off  size)
 - return 0;
 - if (off + count  size)
 - count = size - off;
 + u64 i, j, val;
  
   for (i = 0; i  count;) {
   val = cxl_afu_cr_read64(afu, cr-cr, off  ~0x7);

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH] cxl: Don't ignore add_process_element result when attaching context

2015-08-05 Thread Michael Neuling
On Wed, 2015-07-29 at 14:40 +1000, Daniel Axtens wrote:
 On Wed, 2015-07-29 at 14:25 +1000, Michael Ellerman wrote:
  On Wed, 2015-07-29 at 14:07 +1000, Daniel Axtens wrote:
   Previously, when attaching a context in dedicated mode, we ignored
  
  Previously? You mean currently? Now is before this patch is applied.
 I do mean currently. Apologies for the temporal confusion :)
 
  
   the result of add_process_element, which could potentially fail.
   
   If add_process_element returns and error, pass it back to the caller.
 ^
  
  I can fix.
  
 Many thanks: it's good to know that my spelling mistakes will only be
 immortalised in the list archives rather than in the kernel's git
 history. :p

Not to mention the double negative in the patch subject! Don't
ignore... come on!?!?  :-P

Mikey

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v3] powerpc32: rearrange instructions order in ip_fast_csum()

2015-08-05 Thread Christophe Leroy
On PPC_8xx, lwz has a 2 cycles latency, and branching also takes
2 cycles. On some other powerpc, lwz has 3 cycles.

As the size of the header is minimum 5 words, we can unroll the loop
for the first words to reduce number of branching, and we can re-order
the instructions to limit loading latency.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 v3: Only use lwzu for the last load as lwzu has undocumented
additional latency

 arch/powerpc/lib/checksum_32.S | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/lib/checksum_32.S b/arch/powerpc/lib/checksum_32.S
index 9c48ee0..3ef6e3f 100644
--- a/arch/powerpc/lib/checksum_32.S
+++ b/arch/powerpc/lib/checksum_32.S
@@ -26,14 +26,17 @@
  */
 _GLOBAL(ip_fast_csum)
lwz r0,0(r3)
-   lwzur5,4(r3)
-   addic.  r4,r4,-2
+   lwz r5,4(r3)
+   lwz r6,8(r3)
+   lwzur7,12(r3)
+   addir4,r4,-4
addcr0,r0,r5
mtctr   r4
-   blelr-
-1: lwzur4,4(r3)
-   adder0,r0,r4
+   adder0,r0,r6
+1: adder0,r0,r7
+   lwzur7,4(r3)
bdnz1b
+   adder0,r0,r7
addze   r0,r0   /* add in final carry */
rlwinm  r3,r0,16,0,31   /* fold two halves together */
add r3,r0,r3
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH 1/5] powerpc/pseries: extract of_helpers module

2015-08-05 Thread Andy Shevchenko
On Wed, 2015-08-05 at 00:20 -0500, Segher Boessenkool wrote:
 Hi Andy,
 
 On Tue, Aug 04, 2015 at 05:36:45PM +0300, Andy Shevchenko wrote:
  +struct device_node *pseries_of_derive_parent(const char *path)
  +{
  +   struct device_node *parent = NULL;
  +   char *parent_path = /;
  +   size_t parent_path_len = strrchr(path, '/') - path + 1;
  +
  +   /* reject if path is / */
  +   if (!strcmp(path, /))
  +   return ERR_PTR(-EINVAL);
  +
  +   if (strrchr(path, '/') != path) {
  +   parent_path = kmalloc(parent_path_len, 
  GFP_KERNEL);
 
 If path doesn't contain any slash this will do interesting things;
 you might want to fix that too while you're at it :-)

No problem, though it is in the original code. I would do as a separate
patch on top of the series. Will be okay for you?

 
 
 Segher

-- 
Andy Shevchenko andriy.shevche...@linux.intel.com
Intel Finland Oy
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v2 4/8] xen: Use the correctly the Xen memory terminologies

2015-08-05 Thread Stefano Stabellini
On Tue, 4 Aug 2015, Boris Ostrovsky wrote:
 On 08/04/2015 02:12 PM, Julien Grall wrote:
  /*
 * We detect special mappings in one of two ways:
  @@ -217,9 +232,13 @@ static inline unsigned long bfn_to_local_pfn(unsigned
  long mfn)
  /* VIRT - MACHINE conversion */
#define virt_to_machine(v)(phys_to_machine(XPADDR(__pa(v
  -#define virt_to_pfn(v)  (PFN_DOWN(__pa(v)))
#define virt_to_mfn(v)(pfn_to_mfn(virt_to_pfn(v)))
#define mfn_to_virt(m)(__va(mfn_to_pfn(m)  PAGE_SHIFT))
  +#define virt_to_pfn(v)  (PFN_DOWN(__pa(v)))
 
 This looks like unnecessary change.
 
 
  diff --git a/drivers/video/fbdev/xen-fbfront.c
  b/drivers/video/fbdev/xen-fbfront.c
  index 09dc447..25e3cce 100644
  --- a/drivers/video/fbdev/xen-fbfront.c
  +++ b/drivers/video/fbdev/xen-fbfront.c
  @@ -539,7 +539,7 @@ static int xenfb_remove(struct xenbus_device *dev)
  static unsigned long vmalloc_to_mfn(void *address)
{
  -   return pfn_to_mfn(vmalloc_to_pfn(address));
  +   return pfn_to_gfn(vmalloc_to_pfn(address));
}
 
 Are you sure? This will return vmalloc_to_pfn(address)).

I think that is OK: there is no behavioural change here.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v2 4/8] xen: Use the correctly the Xen memory terminologies

2015-08-05 Thread Stefano Stabellini
On Tue, 4 Aug 2015, Julien Grall wrote:
 Based on include/xen/mm.h [1], Linux is mistakenly using MFN when GFN
 is meant, I suspect this is because the first support for Xen was for
 PV. This resulted in some misimplementation of helpers on ARM and
 confused developers about the expected behavior.
 
 For instance, with pfn_to_mfn, we expect to get an MFN based on the name.
 Although, if we look at the implementation on x86, it's returning a GFN.
 
 For clarity and avoid new confusion, replace any reference to mfn with
 gfn in any helpers used by PV drivers. The x86 code will still keep some
 reference of pfn_to_mfn but exclusively for PV (a BUG_ON has been added
 to ensure this). No changes as been made in the hypercall field, even
 though they may be invalid, in order to keep the same as the defintion
 in xen repo.
 
 Take also the opportunity to simplify simple construction such
 as pfn_to_mfn(page_to_pfn(page)) into page_to_gfn. More complex clean up
 will come in follow-up patches.
 
 [1] 
 http://xenbits.xen.org/gitweb/?p=xen.git;a=commitdiff;h=e758ed14f390342513405dd766e874934573e6cb
 
 Signed-off-by: Julien Grall julien.gr...@citrix.com
 Cc: Stefano Stabellini stefano.stabell...@eu.citrix.com
 Cc: Russell King li...@arm.linux.org.uk
 Cc: Konrad Rzeszutek Wilk konrad.w...@oracle.com
 Cc: Boris Ostrovsky boris.ostrov...@oracle.com
 Cc: David Vrabel david.vra...@citrix.com
 Cc: Thomas Gleixner t...@linutronix.de
 Cc: Ingo Molnar mi...@redhat.com
 Cc: H. Peter Anvin h...@zytor.com
 Cc: x...@kernel.org
 Cc: Roger Pau Monné roger@citrix.com
 Cc: Dmitry Torokhov dmitry.torok...@gmail.com
 Cc: Ian Campbell ian.campb...@citrix.com
 Cc: Wei Liu wei.l...@citrix.com
 Cc: Juergen Gross jgr...@suse.com
 Cc: James E.J. Bottomley jbottom...@odin.com
 Cc: Greg Kroah-Hartman gre...@linuxfoundation.org
 Cc: Jiri Slaby jsl...@suse.com
 Cc: Jean-Christophe Plagniol-Villard plagn...@jcrosoft.com
 Cc: Tomi Valkeinen tomi.valkei...@ti.com
 Cc: linux-in...@vger.kernel.org
 Cc: net...@vger.kernel.org
 Cc: linux-s...@vger.kernel.org
 Cc: linuxppc-dev@lists.ozlabs.org
 Cc: linux-fb...@vger.kernel.org
 Cc: linux-arm-ker...@lists.infradead.org

Aside from the x86 bits:

Reviewed-by: Stefano Stabellini stefano.stabell...@eu.citrix.com


 Note that I've re-introduced mfn_to_pfn  co only for x86 PV code.
 The helpers contain a BUG_ON to ensure that it's never called for
 auto-translated guests. I did as best as my can to determine whether
 mfn or gfn helpers should be used. Although, I haven't tried to boot
 it.
 
 It may be possible to do further cleanup in the mmu.c where I found
 some check to auto-translated. I'm not sure why given that the pvmmu
 callback are only used for non-auto translated guest.
 
 Finally, given those changes, I didn't retain the Reviewed-by/Acked-by.
 
 Changes in v2:
 - Give directly the URL to the commit rather than the commit ID
 - xenstored_local_init: keep the cast to void *
 - Typoes
 - Keep pfn_to_mfn for x86 and PV-only. The *mfn* helpers are
 used in arch/x86/xen for enlighten.c, mmu.c, p2m.c, setup.c,
 smp.c and mm.c
 ---
  arch/arm/include/asm/xen/page.h | 13 +++--
  arch/x86/include/asm/xen/page.h | 33 
 ++---
  arch/x86/xen/smp.c  |  2 +-
  drivers/block/xen-blkfront.c|  6 +++---
  drivers/input/misc/xen-kbdfront.c   |  4 ++--
  drivers/net/xen-netback/netback.c   |  4 ++--
  drivers/net/xen-netfront.c  |  8 
  drivers/scsi/xen-scsifront.c|  8 +++-
  drivers/tty/hvc/hvc_xen.c   |  5 +++--
  drivers/video/fbdev/xen-fbfront.c   |  4 ++--
  drivers/xen/balloon.c   |  2 +-
  drivers/xen/events/events_base.c|  2 +-
  drivers/xen/events/events_fifo.c|  4 ++--
  drivers/xen/gntalloc.c  |  3 ++-
  drivers/xen/manage.c|  2 +-
  drivers/xen/tmem.c  |  4 ++--
  drivers/xen/xenbus/xenbus_client.c  |  2 +-
  drivers/xen/xenbus/xenbus_dev_backend.c |  2 +-
  drivers/xen/xenbus/xenbus_probe.c   |  8 +++-
  include/xen/page.h  |  4 ++--
  20 files changed, 69 insertions(+), 51 deletions(-)
 
 diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
 index 087d86e..51e5bf1 100644
 --- a/arch/arm/include/asm/xen/page.h
 +++ b/arch/arm/include/asm/xen/page.h
 @@ -34,14 +34,15 @@ typedef struct xpaddr {
  unsigned long __pfn_to_mfn(unsigned long pfn);
  extern struct rb_root phys_to_mach;
  
 -static inline unsigned long pfn_to_mfn(unsigned long pfn)
 +/* Pseudo-physical - Guest conversion */
 +static inline unsigned long pfn_to_gfn(unsigned long pfn)
  {
   return pfn;
  }
  
 -static inline unsigned long mfn_to_pfn(unsigned long mfn)
 +static inline unsigned long gfn_to_pfn(unsigned long gfn)
  {
 - return mfn;
 + return gfn;

Re: [PATCH 2/3] PowerPC/mpc85xx: Add hotplug support on E5500 and E500MC cores

2015-08-05 Thread Chenhui Zhao



On Tue, Aug 4, 2015 at 5:18 AM, Scott Wood scottw...@freescale.com 
wrote:
[Added linuxppc-dev@lists.ozlabs.org.  Besides that list being 
required for
review of PPC patches, it feeds the patchwork that I use to track and 
apply

patches.]

On Mon, 2015-08-03 at 19:52 +0800, Chenhui Zhao wrote:

 On Sat, Aug 1, 2015 at 8:14 AM, Scott Wood scottw...@freescale.com
 wrote:
  On Fri, 2015-07-31 at 17:20 +0800,  b29983@freescale.comwrote:
From: Tang Yuantian yuantian.t...@freescale.com
  
Freescale E500MC and E5500 core-based platforms, like P4080, 
T1040,

support disabling/enabling CPU dynamically.
This patch adds this feature on those platforms.
  
Signed-off-by: Chenhui Zhao chenhui.z...@freescale.com
Signed-off-by: Tang Yuantian yuantian.t...@feescale.com




 +{
+ int i;
+
+ for (i = 0; i  5; i++) {
+ if (generic_check_cpu_dead(cpu)) {
+ qoriq_pm_ops-cpu_die(cpu);
+#ifdef CONFIG_PPC64
+ paca[cpu].cpu_start = 0;
+#endif
+ return;
+ }
+ udelay(10);
+ }
+ pr_err(%s: CPU%d didn't die...\n, __func__, cpu);
+}
 
  Only 500ms timeout, versus 10sec in generic_cpu_die()?

 The process is fast. Maybe 10 second is too large.


Is it fast 100% of the time?  What if the CPU you intend to die is in 
a long
critical section?  What harm is there to having a longer timeout, 
similar to

what other platforms use?


Will change the max timeout to 10 seconds.





 
 #endif
  
 static inline void flush_spin_table(void *spin_table)
@@ -246,11 +267,7 @@ static int smp_85xx_kick_cpu(int nr)
  spin_table = phys_to_virt(*cpu_rel_addr);
  
  local_irq_save(flags);
-#ifdef CONFIG_PPC32
 #ifdef CONFIG_HOTPLUG_CPU
- /* Corresponding to generic_set_cpu_dead() */
- generic_set_cpu_up(nr);
-
  if (system_state == SYSTEM_RUNNING) {
  /*
   * To keep it compatible with old boot program 
which

   uses
@@ -263,6 +280,7 @@ static int smp_85xx_kick_cpu(int nr)
  out_be32(spin_table-addr_l, 0);
  flush_spin_table(spin_table);
  
+ qoriq_pm_ops-cpu_up(nr);
 
  Again, is it possible to get here without a valid qoriq_pm_ops 
(i.e.

  is there
  anything stopping the user from trying to initiate CPU hotplug)?
 
  -Scott

 For every platform running this code, should has a valid 
qoriq_pm_ops.

 If not valid, it's a bug.


How do you prevent this code from running when there is no valid 
qoriq_pm_ops?


-Scott



Will check if qoriq_pm_ops is valid.

-Chenhui



___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v2 4/8] xen: Use the correctly the Xen memory terminologies

2015-08-05 Thread Julien Grall
Hi Boris,

On 05/08/15 00:16, Boris Ostrovsky wrote:
 On 08/04/2015 02:12 PM, Julien Grall wrote:
 /*
* We detect special mappings in one of two ways:
 @@ -217,9 +232,13 @@ static inline unsigned long
 bfn_to_local_pfn(unsigned long mfn)
 /* VIRT - MACHINE conversion */
   #define virt_to_machine(v)(phys_to_machine(XPADDR(__pa(v
 -#define virt_to_pfn(v)  (PFN_DOWN(__pa(v)))
   #define virt_to_mfn(v)(pfn_to_mfn(virt_to_pfn(v)))
   #define mfn_to_virt(m)(__va(mfn_to_pfn(m)  PAGE_SHIFT))
 +#define virt_to_pfn(v)  (PFN_DOWN(__pa(v)))
 
 This looks like unnecessary change.

Right, I made the mistake when I re-introduced virt_to_mfn in this
version. It was dropped in the previous one.

 diff --git a/drivers/video/fbdev/xen-fbfront.c
 b/drivers/video/fbdev/xen-fbfront.c
 index 09dc447..25e3cce 100644
 --- a/drivers/video/fbdev/xen-fbfront.c
 +++ b/drivers/video/fbdev/xen-fbfront.c
 @@ -539,7 +539,7 @@ static int xenfb_remove(struct xenbus_device *dev)
 static unsigned long vmalloc_to_mfn(void *address)
   {
 -return pfn_to_mfn(vmalloc_to_pfn(address));
 +return pfn_to_gfn(vmalloc_to_pfn(address));
   }
 
 Are you sure? This will return vmalloc_to_pfn(address)).

I guess you mean vmalloc_to_mfn will return vmalloc_to_pfn?

If so, it will be only the case on auto-translated case (because pfn ==
gfn). In the case of PV, the mfn will be returned.

Although, this function is misnamed. It's fixed in a follow-up patch
(see #6) because it's required more renaming than this function. I
didn't want to add such changes within this patch.

Regards,

-- 
Julien Grall
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v2 4/8] xen: Use the correctly the Xen memory terminologies

2015-08-05 Thread Boris Ostrovsky

On 08/05/2015 06:51 AM, Julien Grall wrote:



diff --git a/drivers/video/fbdev/xen-fbfront.c
b/drivers/video/fbdev/xen-fbfront.c
index 09dc447..25e3cce 100644
--- a/drivers/video/fbdev/xen-fbfront.c
+++ b/drivers/video/fbdev/xen-fbfront.c
@@ -539,7 +539,7 @@ static int xenfb_remove(struct xenbus_device *dev)
 static unsigned long vmalloc_to_mfn(void *address)
   {
-return pfn_to_mfn(vmalloc_to_pfn(address));
+return pfn_to_gfn(vmalloc_to_pfn(address));
   }

Are you sure? This will return vmalloc_to_pfn(address)).

I guess you mean vmalloc_to_mfn will return vmalloc_to_pfn?

If so, it will be only the case on auto-translated case (because pfn ==
gfn). In the case of PV, the mfn will be returned.


How will mfn be returned on PV when pfn_to_gfn() is an identity function?

static inline unsigned long pfn_to_gfn(unsigned long pfn)
 {
 return pfn;
 }


-boris



Although, this function is misnamed. It's fixed in a follow-up patch
(see #6) because it's required more renaming than this function. I
didn't want to add such changes within this patch.

Regards,



___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [Xen-devel] [PATCH v2 4/8] xen: Use the correctly the Xen memory terminologies

2015-08-05 Thread Julien Grall
On 05/08/15 13:19, Boris Ostrovsky wrote:
 On 08/05/2015 06:51 AM, Julien Grall wrote:

 diff --git a/drivers/video/fbdev/xen-fbfront.c
 b/drivers/video/fbdev/xen-fbfront.c
 index 09dc447..25e3cce 100644
 --- a/drivers/video/fbdev/xen-fbfront.c
 +++ b/drivers/video/fbdev/xen-fbfront.c
 @@ -539,7 +539,7 @@ static int xenfb_remove(struct xenbus_device *dev)
  static unsigned long vmalloc_to_mfn(void *address)
{
 -return pfn_to_mfn(vmalloc_to_pfn(address));
 +return pfn_to_gfn(vmalloc_to_pfn(address));
}
 Are you sure? This will return vmalloc_to_pfn(address)).
 I guess you mean vmalloc_to_mfn will return vmalloc_to_pfn?

 If so, it will be only the case on auto-translated case (because pfn ==
 gfn). In the case of PV, the mfn will be returned.
 
 How will mfn be returned on PV when pfn_to_gfn() is an identity function?
 
 static inline unsigned long pfn_to_gfn(unsigned long pfn)
  {
  return pfn;
  }

The identity function is only for ARM guest which are always
auto-translated (arch/arm/include/asm/xen/page.h).

The x86 version contains a check if the guest is auto-translated or not
(arch/x86/include/asm/xen/page.):

static inline unsigned long pfn_to_gfn(unsigned long pfn)
{
if (xen_feature(XENFEAT_auto_translated_physmap))
return pfn;
else
return pfn_to_mfn(pfn);
}

Regards,

-- 
Julien Grall
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [Xen-devel] [PATCH v2 4/8] xen: Use the correctly the Xen memory terminologies

2015-08-05 Thread Boris Ostrovsky

On 08/05/2015 08:33 AM, Julien Grall wrote:

On 05/08/15 13:19, Boris Ostrovsky wrote:

On 08/05/2015 06:51 AM, Julien Grall wrote:

diff --git a/drivers/video/fbdev/xen-fbfront.c
b/drivers/video/fbdev/xen-fbfront.c
index 09dc447..25e3cce 100644
--- a/drivers/video/fbdev/xen-fbfront.c
+++ b/drivers/video/fbdev/xen-fbfront.c
@@ -539,7 +539,7 @@ static int xenfb_remove(struct xenbus_device *dev)
  static unsigned long vmalloc_to_mfn(void *address)
{
-return pfn_to_mfn(vmalloc_to_pfn(address));
+return pfn_to_gfn(vmalloc_to_pfn(address));
}

Are you sure? This will return vmalloc_to_pfn(address)).

I guess you mean vmalloc_to_mfn will return vmalloc_to_pfn?

If so, it will be only the case on auto-translated case (because pfn ==
gfn). In the case of PV, the mfn will be returned.

How will mfn be returned on PV when pfn_to_gfn() is an identity function?

static inline unsigned long pfn_to_gfn(unsigned long pfn)
  {
  return pfn;
  }

The identity function is only for ARM guest which are always
auto-translated (arch/arm/include/asm/xen/page.h).

The x86 version contains a check if the guest is auto-translated or not
(arch/x86/include/asm/xen/page.):

static inline unsigned long pfn_to_gfn(unsigned long pfn)
{
 if (xen_feature(XENFEAT_auto_translated_physmap))
 return pfn;
 else
 return pfn_to_mfn(pfn);
}


Of course --- I was looking at the top of the patch and didn't realize 
it was ARM changes. Sorry for the noise.


-boris
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[v4, 0/9] Freescale DPAA FMan

2015-08-05 Thread igal.liberman
From: Igal Liberman igal.liber...@freescale.com

The Freescale Data Path Acceleration Architecture (DPAA)
is a set of hardware components on specific QorIQ multicore processors.
This architecture provides the infrastructure to support simplified
sharing of networking interfaces and accelerators by multiple CPU cores
and the accelerators.

One of the DPAA accelerators is the Frame Manager (FMan) which contains a
series of hardware blocks: ports, Ethernet MACs, a multi user RAM (MURAM)
and Storage Profile (SP).

This patch set introduce the FMan drivers. Each driver configures
and initializes the corresponding FMan hardware module (described above).
The MAC driver offers support for three different types of
MACs (eTSEC, TGEC, MEMAC).

The driver structure and a hint on file naming:
--
|   FMan driver/MAC driver   |  fm_drv*, mac* files
--
| FMan | Port | MAC | MURAM | SP |  fm_* files
--
|   FLib  | fman_*.c, fsl_fman_.*h files
--

The first 3 patches present the FMan Foundation Libraries (FLIBs).
The FLIBs provide basic internal API for the FMan hardware
configuration and control.
Header files are located in fman/flib directory.
Source files are located in each module directory.

The upper layer of the FMan driver makes use of the basic API which is
provided by the Flibs.

The remaining patches present the required FMan hardware module drivers.

v3 -- v4:
- Remove device_initcall call in driver registration (redundant)
- Remove hot/cold labels
- Minor update in FMan Clock read from device-tree
- Update fixed-link support
- Addressed feedback from Stephen Hemminger
- Remove bogus blank line

v2 -- v3:
- Addressed feedback from Scott:
- Remove typedefs
- Remove unnecessary memory barriers
- Remove unnecessary casting
- Remove KConfig options
- Remove early_params
- Remove Hungarian notation
- Remove __packed__  attribute and padding from structures
- Remove unlikely attribute (where it's not needed)
- Use proper error codes and remove unnecessary prints
- Use proper values for sleep routines
- Replace complex Macros with functions
- Improve device tree processing code
- Use symbolic defines
- Add time-out in busy-wait loops
- Removed exit code (loadable module support will be added 
later)
- Fixed fixed-link issue raised by Joakim Tjernlund

v1 -- v2:
- Addressed feedback from Paul Bolle:
- General feedback of FMan Driver layer
- Remove Errata defines
- Aligned comments to Kernel Doc
- Remove Loadable Module support (not yet supported)
- Removed not needed KConfig dependencies 
- Addressed feedback from Scott Wood
- Use Kernel ioread/iowrite services
- Squash FLIB source and header patches together


This submission is based on the prior Freescale DPAA FMan V3,RFC submission.
Several issues addresses in this submission:
- Reduced MAC layering and complexity
- Reduced code base
- T1024/T2080 10G best effort support


Igal Liberman (9):
  fsl/fman: Add the FMan FLIB
  fsl/fman: Add the FMan port FLIB
  fsl/fman: Add the FMan MAC FLIB
  fsl/fman: Add FMan MURAM support
  fsl/fman: Add Frame Manager support
  fsl/fman: Add FMan MAC support
  fsl/fman: Add FMan SP support
  fsl/fman: Add FMan Port Support
  fsl/fman: Add FMan MAC driver

 drivers/net/ethernet/freescale/Kconfig |1 +
 drivers/net/ethernet/freescale/Makefile|2 +
 drivers/net/ethernet/freescale/fman/Kconfig|8 +
 drivers/net/ethernet/freescale/fman/Makefile   |   12 +
 .../net/ethernet/freescale/fman/flib/fsl_enet.h|  135 ++
 .../net/ethernet/freescale/fman/flib/fsl_fman.h|  590 +
 .../ethernet/freescale/fman/flib/fsl_fman_dtsec.h  |  809 
 .../freescale/fman/flib/fsl_fman_dtsec_mii_acc.h   |   89 ++
 .../ethernet/freescale/fman/flib/fsl_fman_memac.h  |  429 ++
 .../freescale/fman/flib/fsl_fman_memac_mii_acc.h   |   72 ++
 .../ethernet/freescale/fman/flib/fsl_fman_port.h   |  409 ++
 .../net/ethernet/freescale/fman/flib/fsl_fman_sp.h |   53 +
 .../ethernet/freescale/fman/flib/fsl_fman_tgec.h   |  393 ++
 drivers/net/ethernet/freescale/fman/fm.c   | 1366 
 drivers/net/ethernet/freescale/fman/fm.h   |  279 
 drivers/net/ethernet/freescale/fman/fm_common.h|  178 +++
 drivers/net/ethernet/freescale/fman/fm_drv.c   |  621 +
 drivers/net/ethernet/freescale/fman/fm_drv.h   |  111 ++
 

[v4, 1/9] fsl/fman: Add the FMan FLIB

2015-08-05 Thread igal.liberman
From: Igal Liberman igal.liber...@freescale.com

The FMan FLib provides the basic API used by the FMan drivers to
configure and control the FMan hardware.

Signed-off-by: Igal Liberman igal.liber...@freescale.com
---
 drivers/net/ethernet/freescale/Kconfig |1 +
 drivers/net/ethernet/freescale/Makefile|2 +
 drivers/net/ethernet/freescale/fman/Kconfig|7 +
 drivers/net/ethernet/freescale/fman/Makefile   |5 +
 .../net/ethernet/freescale/fman/flib/fsl_fman.h|  590 +
 drivers/net/ethernet/freescale/fman/fman.c |  911 
 6 files changed, 1516 insertions(+)
 create mode 100644 drivers/net/ethernet/freescale/fman/Kconfig
 create mode 100644 drivers/net/ethernet/freescale/fman/Makefile
 create mode 100644 drivers/net/ethernet/freescale/fman/flib/fsl_fman.h
 create mode 100644 drivers/net/ethernet/freescale/fman/fman.c

diff --git a/drivers/net/ethernet/freescale/Kconfig 
b/drivers/net/ethernet/freescale/Kconfig
index ff76d4e..f3f89cc 100644
--- a/drivers/net/ethernet/freescale/Kconfig
+++ b/drivers/net/ethernet/freescale/Kconfig
@@ -53,6 +53,7 @@ config FEC_MPC52xx_MDIO
  If compiled as module, it will be called fec_mpc52xx_phy.
 
 source drivers/net/ethernet/freescale/fs_enet/Kconfig
+source drivers/net/ethernet/freescale/fman/Kconfig
 
 config FSL_PQ_MDIO
tristate Freescale PQ MDIO
diff --git a/drivers/net/ethernet/freescale/Makefile 
b/drivers/net/ethernet/freescale/Makefile
index 71debd1..4097c58 100644
--- a/drivers/net/ethernet/freescale/Makefile
+++ b/drivers/net/ethernet/freescale/Makefile
@@ -17,3 +17,5 @@ gianfar_driver-objs := gianfar.o \
gianfar_ethtool.o
 obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o
 ucc_geth_driver-objs := ucc_geth.o ucc_geth_ethtool.o
+
+obj-$(CONFIG_FSL_FMAN) += fman/
diff --git a/drivers/net/ethernet/freescale/fman/Kconfig 
b/drivers/net/ethernet/freescale/fman/Kconfig
new file mode 100644
index 000..8aeae29
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/Kconfig
@@ -0,0 +1,7 @@
+config FSL_FMAN
+   bool FMan support
+   depends on FSL_SOC || COMPILE_TEST
+   default n
+   help
+   Freescale Data-Path Acceleration Architecture Frame Manager
+   (FMan) support
diff --git a/drivers/net/ethernet/freescale/fman/Makefile 
b/drivers/net/ethernet/freescale/fman/Makefile
new file mode 100644
index 000..2799c6f
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/Makefile
@@ -0,0 +1,5 @@
+subdir-ccflags-y += -I$(srctree)/drivers/net/ethernet/freescale/fman/flib
+
+obj-y  += fsl_fman.o
+
+fsl_fman-objs  := fman.o
diff --git a/drivers/net/ethernet/freescale/fman/flib/fsl_fman.h 
b/drivers/net/ethernet/freescale/fman/flib/fsl_fman.h
new file mode 100644
index 000..7bd5ca6
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/flib/fsl_fman.h
@@ -0,0 +1,590 @@
+/*
+ * Copyright 2008 - 2015 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ *  names of its contributors may be used to endorse or promote products
+ *  derived from this software without specific prior written permission.
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License (GPL) as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __FSL_FMAN_H
+#define __FSL_FMAN_H
+
+#include linux/delay.h
+
+struct fman_revision_info {
+   u8 major_rev;   /* Major revision */
+   u8 minor_rev;   /* Minor revision */
+};
+
+/* sizes */

[v4, 2/9] fsl/fman: Add the FMan port FLIB

2015-08-05 Thread igal.liberman
From: Igal Liberman igal.liber...@freescale.com

The FMan Port FLib provides basic API used by the drivers to
configure and control the FMan Port hardware.

Signed-off-by: Igal Liberman igal.liber...@freescale.com
---
 drivers/net/ethernet/freescale/fman/Makefile   |2 +
 .../ethernet/freescale/fman/flib/fsl_fman_port.h   |  409 
 .../net/ethernet/freescale/fman/flib/fsl_fman_sp.h |   53 ++
 drivers/net/ethernet/freescale/fman/port/Makefile  |3 +
 .../net/ethernet/freescale/fman/port/fman_port.c   |  510 
 5 files changed, 977 insertions(+)
 create mode 100644 drivers/net/ethernet/freescale/fman/flib/fsl_fman_port.h
 create mode 100644 drivers/net/ethernet/freescale/fman/flib/fsl_fman_sp.h
 create mode 100644 drivers/net/ethernet/freescale/fman/port/Makefile
 create mode 100644 drivers/net/ethernet/freescale/fman/port/fman_port.c

diff --git a/drivers/net/ethernet/freescale/fman/Makefile 
b/drivers/net/ethernet/freescale/fman/Makefile
index 2799c6f..50a4de2 100644
--- a/drivers/net/ethernet/freescale/fman/Makefile
+++ b/drivers/net/ethernet/freescale/fman/Makefile
@@ -3,3 +3,5 @@ subdir-ccflags-y += 
-I$(srctree)/drivers/net/ethernet/freescale/fman/flib
 obj-y  += fsl_fman.o
 
 fsl_fman-objs  := fman.o
+
+obj-y  += port/
diff --git a/drivers/net/ethernet/freescale/fman/flib/fsl_fman_port.h 
b/drivers/net/ethernet/freescale/fman/flib/fsl_fman_port.h
new file mode 100644
index 000..6de0719
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/flib/fsl_fman_port.h
@@ -0,0 +1,409 @@
+/*
+ * Copyright 2008 - 2015 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ *  names of its contributors may be used to endorse or promote products
+ *  derived from this software without specific prior written permission.
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License (GPL) as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __FSL_FMAN_PORT_H
+#define __FSL_FMAN_PORT_H
+
+#include linux/io.h
+
+#include fsl_fman_sp.h
+
+/* Registers bit fields */
+
+/* BMI defines */
+#define BMI_EBD_EN 0x8000
+
+#define BMI_PORT_CFG_EN0x8000
+#define BMI_PORT_CFG_FDOVR 0x0200
+
+#define BMI_PORT_STATUS_BSY0x8000
+
+#define BMI_DMA_ATTR_SWP_SHIFT FMAN_SP_DMA_ATTR_SWP_SHIFT
+#define BMI_DMA_ATTR_IC_STASH_ON   0x1000
+#define BMI_DMA_ATTR_HDR_STASH_ON  0x0400
+#define BMI_DMA_ATTR_SG_STASH_ON   0x0100
+#define BMI_DMA_ATTR_WRITE_OPTIMIZEFMAN_SP_DMA_ATTR_WRITE_OPTIMIZE
+
+#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT16
+#define BMI_RX_FIFO_THRESHOLD_ETHE 0x8000
+
+#define BMI_FRAME_END_CS_IGNORE_SHIFT  24
+#define BMI_FRAME_END_CS_IGNORE_MASK   0x001f
+
+#define BMI_RX_FRAME_END_CUT_SHIFT 16
+#define BMI_RX_FRAME_END_CUT_MASK  0x001f
+
+#define BMI_IC_TO_EXT_SHIFTFMAN_SP_IC_TO_EXT_SHIFT
+#define BMI_IC_TO_EXT_MASK 0x001f
+#define BMI_IC_FROM_INT_SHIFT  FMAN_SP_IC_FROM_INT_SHIFT
+#define BMI_IC_FROM_INT_MASK   0x000f
+#define BMI_IC_SIZE_MASK   0x001f
+
+#define BMI_INT_BUF_MARG_SHIFT 28
+#define BMI_INT_BUF_MARG_MASK  0x000f
+#define BMI_EXT_BUF_MARG_START_SHIFT   FMAN_SP_EXT_BUF_MARG_START_SHIFT
+#define 

[PATCH v2 0/2] powerpc32: Optimise csum_partial()

2015-08-05 Thread Christophe Leroy
The purpose of this patchset is to optimise csum_partial() on powerpc32.
In the first part, we remove some unneccessary instructions
In the second part, we partially unloop the main loop

Christophe Leroy (2):
  Optimise a few instructions in csum_partial()
  Optimise csum_partial() loop

 arch/powerpc/lib/checksum_32.S | 53 +-
 1 file changed, 32 insertions(+), 21 deletions(-)

-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 1/2] powerpc32: optimise a few instructions in csum_partial()

2015-08-05 Thread Christophe Leroy
r5 does contain the value to be updated, so lets use r5 all way long
for that. It makes the code more readable.

To avoid confusion, it is better to use adde instead of addc

The first addition is useless. Its only purpose is to clear carry.
As r4 is a signed int that is always positive, this can be done by
using srawi instead of srwi

Let's also remove the comment about dcbz having no overhead as it
is not correct on all powerpc, at least on MPC8xx

In the last part, in our situation, the remaining quantity of bytes
to be proceeded is between 0 and 3. Therefore, we can base that part
on the value of bit 31 and bit 30 of r4 instead of anding r4 with 3
then proceding on comparisons and substractions.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 arch/powerpc/lib/checksum_32.S | 37 +
 1 file changed, 17 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/lib/checksum_32.S b/arch/powerpc/lib/checksum_32.S
index 7b95a68..2e4879c 100644
--- a/arch/powerpc/lib/checksum_32.S
+++ b/arch/powerpc/lib/checksum_32.S
@@ -64,35 +64,32 @@ _GLOBAL(csum_tcpudp_magic)
  * csum_partial(buff, len, sum)
  */
 _GLOBAL(csum_partial)
-   addic   r0,r5,0
subir3,r3,4
-   srwi.   r6,r4,2
+   srawi.  r6,r4,2 /* Divide len by 4 and also clear carry */
beq 3f  /* if we're doing  4 bytes */
-   andi.   r5,r3,2 /* Align buffer to longword boundary */
+   andi.   r0,r3,2 /* Align buffer to longword boundary */
beq+1f
-   lhz r5,4(r3)/* do 2 bytes to get aligned */
-   addir3,r3,2
+   lhz r0,4(r3)/* do 2 bytes to get aligned */
subir4,r4,2
-   addcr0,r0,r5
+   addir3,r3,2
srwi.   r6,r4,2 /* # words to do */
+   adder5,r5,r0
beq 3f
 1: mtctr   r6
-2: lwzur5,4(r3)/* the bdnz has zero overhead, so it should */
-   adder0,r0,r5/* be unnecessary to unroll this loop */
+2: lwzur0,4(r3)
+   adder5,r5,r0
bdnz2b
-   andi.   r4,r4,3
-3: cmpwi   0,r4,2
-   blt+4f
-   lhz r5,4(r3)
+3: andi.   r0,r4,2
+   beq+4f
+   lhz r0,4(r3)
addir3,r3,2
-   subir4,r4,2
-   adder0,r0,r5
-4: cmpwi   0,r4,1
-   bne+5f
-   lbz r5,4(r3)
-   slwir5,r5,8 /* Upper byte of word */
-   adder0,r0,r5
-5: addze   r3,r0   /* add in final carry */
+   adder5,r5,r0
+4: andi.   r0,r4,1
+   beq+5f
+   lbz r0,4(r3)
+   slwir0,r0,8 /* Upper byte of word */
+   adder5,r5,r0
+5: addze   r3,r5   /* add in final carry */
blr
 
 /*
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[v4, 4/9] fsl/fman: Add FMan MURAM support

2015-08-05 Thread igal.liberman
From: Igal Liberman igal.liber...@freescale.com

Add Frame Manager Multi-User RAM support.

Signed-off-by: Igal Liberman igal.liber...@freescale.com
---
 drivers/net/ethernet/freescale/fman/Kconfig|1 +
 drivers/net/ethernet/freescale/fman/Makefile   |6 +-
 drivers/net/ethernet/freescale/fman/fm_muram.c |  115 
 .../net/ethernet/freescale/fman/inc/fm_muram_ext.h |  102 +
 4 files changed, 222 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/freescale/fman/fm_muram.c
 create mode 100644 drivers/net/ethernet/freescale/fman/inc/fm_muram_ext.h

diff --git a/drivers/net/ethernet/freescale/fman/Kconfig 
b/drivers/net/ethernet/freescale/fman/Kconfig
index 8aeae29..66b7296 100644
--- a/drivers/net/ethernet/freescale/fman/Kconfig
+++ b/drivers/net/ethernet/freescale/fman/Kconfig
@@ -1,6 +1,7 @@
 config FSL_FMAN
bool FMan support
depends on FSL_SOC || COMPILE_TEST
+   select GENERIC_ALLOCATOR
default n
help
Freescale Data-Path Acceleration Architecture Frame Manager
diff --git a/drivers/net/ethernet/freescale/fman/Makefile 
b/drivers/net/ethernet/freescale/fman/Makefile
index 1841b03..55c91bd 100644
--- a/drivers/net/ethernet/freescale/fman/Makefile
+++ b/drivers/net/ethernet/freescale/fman/Makefile
@@ -1,8 +1,10 @@
-subdir-ccflags-y += -I$(srctree)/drivers/net/ethernet/freescale/fman/flib
+subdir-ccflags-y += -I$(srctree)/drivers/net/ethernet/freescale/fman/flib \
+
-I$(srctree)/drivers/net/ethernet/freescale/fman/inc \
+
-I$(srctree)/drivers/net/ethernet/freescale/fman
 
 obj-y  += fsl_fman.o
 
-fsl_fman-objs  := fman.o
+fsl_fman-objs  := fman.o fm_muram.o
 
 obj-y  += port/
 obj-y  += mac/
diff --git a/drivers/net/ethernet/freescale/fman/fm_muram.c 
b/drivers/net/ethernet/freescale/fman/fm_muram.c
new file mode 100644
index 000..9d74bd9
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/fm_muram.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2008-2015 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ *   names of its contributors may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License (GPL) as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include fm_muram_ext.h
+
+#include linux/io.h
+#include linux/string.h
+#include linux/slab.h
+#include linux/genalloc.h
+
+struct muram_info {
+   struct gen_pool *pool;
+   void __iomem *vbase;
+   size_t size;
+   phys_addr_t pbase;
+};
+
+struct muram_info *fm_muram_init(phys_addr_t base, size_t size)
+{
+   struct muram_info *muram;
+   void __iomem *vaddr;
+   int ret;
+
+   muram = kzalloc(sizeof(*muram), GFP_KERNEL);
+   if (!muram)
+   return NULL;
+
+   muram-pool = gen_pool_create(ilog2(64), -1);
+   if (!muram-pool) {
+   pr_err(%s(): MURAM pool create failed\n, __func__);
+   return NULL;
+   }
+
+   vaddr = ioremap(base, size);
+   if (!vaddr) {
+   pr_err(%s(): MURAM ioremap failed\n, __func__);
+   return NULL;
+   }
+
+   ret = gen_pool_add_virt(muram-pool, (unsigned long)vaddr,
+   base, size, -1);
+   if (ret  0) {
+   pr_err(%s(): MURAM pool add failed\n, __func__);
+   

[PATCH v2 2/2] powerpc32: optimise csum_partial() loop

2015-08-05 Thread Christophe Leroy
On the 8xx, load latency is 2 cycles and taking branches also takes
2 cycles. So let's unroll the loop.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 v2: Only use lwzu for the last load as lwzu has undocumented
additional latency

 arch/powerpc/lib/checksum_32.S | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/lib/checksum_32.S b/arch/powerpc/lib/checksum_32.S
index 2e4879c..9c48ee0 100644
--- a/arch/powerpc/lib/checksum_32.S
+++ b/arch/powerpc/lib/checksum_32.S
@@ -75,10 +75,24 @@ _GLOBAL(csum_partial)
srwi.   r6,r4,2 /* # words to do */
adder5,r5,r0
beq 3f
-1: mtctr   r6
+1: andi.   r6,r6,3 /* Prepare to handle words 4 by 4 */
+   beq 21f
+   mtctr   r6
 2: lwzur0,4(r3)
adder5,r5,r0
bdnz2b
+21:srwi.   r6,r4,4 /* # blocks of 4 words to do */
+   beq 3f
+   mtctr   r6
+22:lwz r0,4(r3)
+   lwz r6,8(r3)
+   lwz r7,12(r3)
+   lwzur8,16(r3)
+   adder5,r5,r0
+   adder5,r5,r6
+   adder5,r5,r7
+   adder5,r5,r8
+   bdnz22b
 3: andi.   r0,r4,2
beq+4f
lhz r0,4(r3)
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[v4, 6/9] fsl/fman: Add FMan MAC support

2015-08-05 Thread igal.liberman
From: Igal Liberman igal.liber...@freescale.com

Add Frame Manger MAC Driver support.
This patch adds The FMan MAC configuration, initialization and
runtime control routines.
This patch contains support for these types of MACs:
tGEC, dTSEC and mEMAC

Signed-off-by: Igal Liberman igal.liber...@freescale.com
---
 .../ethernet/freescale/fman/flib/fsl_fman_memac.h  |1 +
 drivers/net/ethernet/freescale/fman/fm.c   |   41 +
 drivers/net/ethernet/freescale/fman/fm.h   |3 +
 drivers/net/ethernet/freescale/fman/fm_common.h|   29 +
 .../ethernet/freescale/fman/inc/crc_mac_addr_ext.h |  314 ++
 drivers/net/ethernet/freescale/fman/mac/Makefile   |4 +-
 drivers/net/ethernet/freescale/fman/mac/fm_dtsec.c | 1012 
 drivers/net/ethernet/freescale/fman/mac/fm_dtsec.h |  207 
 drivers/net/ethernet/freescale/fman/mac/fm_mac.h   |  259 +
 drivers/net/ethernet/freescale/fman/mac/fm_memac.c |  700 ++
 drivers/net/ethernet/freescale/fman/mac/fm_memac.h |  122 +++
 drivers/net/ethernet/freescale/fman/mac/fm_tgec.c  |  552 +++
 drivers/net/ethernet/freescale/fman/mac/fm_tgec.h  |  124 +++
 13 files changed, 3367 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ethernet/freescale/fman/inc/crc_mac_addr_ext.h
 create mode 100644 drivers/net/ethernet/freescale/fman/mac/fm_dtsec.c
 create mode 100644 drivers/net/ethernet/freescale/fman/mac/fm_dtsec.h
 create mode 100644 drivers/net/ethernet/freescale/fman/mac/fm_mac.h
 create mode 100644 drivers/net/ethernet/freescale/fman/mac/fm_memac.c
 create mode 100644 drivers/net/ethernet/freescale/fman/mac/fm_memac.h
 create mode 100644 drivers/net/ethernet/freescale/fman/mac/fm_tgec.c
 create mode 100644 drivers/net/ethernet/freescale/fman/mac/fm_tgec.h

diff --git a/drivers/net/ethernet/freescale/fman/flib/fsl_fman_memac.h 
b/drivers/net/ethernet/freescale/fman/flib/fsl_fman_memac.h
index f8641d4..ebf7989 100644
--- a/drivers/net/ethernet/freescale/fman/flib/fsl_fman_memac.h
+++ b/drivers/net/ethernet/freescale/fman/flib/fsl_fman_memac.h
@@ -373,6 +373,7 @@ struct memac_cfg {
bool tx_pbl_fwd;
bool debug_mode;
bool wake_on_lan;
+   bool fixed_link;
u16 max_frame_length;
u16 pause_quanta;
u32 tx_ipg_length;
diff --git a/drivers/net/ethernet/freescale/fman/fm.c 
b/drivers/net/ethernet/freescale/fman/fm.c
index 7e5fa53..450ee6b 100644
--- a/drivers/net/ethernet/freescale/fman/fm.c
+++ b/drivers/net/ethernet/freescale/fman/fm.c
@@ -587,6 +587,47 @@ u8 fm_get_id(struct fm_t *fm)
return fm-fm_state-fm_id;
 }
 
+int fm_reset_mac(struct fm_t *fm, u8 mac_id)
+{
+   int err;
+   struct fman_fpm_regs __iomem *fpm_rg = fm-fpm_regs;
+
+   if (fm-fm_state-rev_info.major_rev = 6) {
+   pr_warn(FMan MAC reset!\n);
+   return -EINVAL;
+   }
+   if (!fm-base_addr) {
+   pr_warn('base_address' is required!\n);
+   return -EINVAL;
+   }
+   err = fman_reset_mac(fpm_rg, mac_id);
+
+   if (err == -EINVAL) {
+   pr_warn(Illegal MAC Id\n);
+   return -EINVAL;
+   } else if (err == EINVAL) {
+   return -EINVAL;
+   }
+   return 0;
+}
+
+int fm_set_mac_max_frame(struct fm_t *fm, enum fm_mac_type type,
+u8 mac_id, u16 mtu)
+{
+   /* if port is already initialized, check that MaxFrameLength is smaller
+* or equal to the port's max
+*/
+   if ((!fm-fm_state-port_mfl[mac_id]) ||
+   (fm-fm_state-port_mfl[mac_id] 
+   (mtu = fm-fm_state-port_mfl[mac_id]))) {
+   fm-fm_state-mac_mfl[mac_id] = mtu;
+   } else {
+   pr_warn(MAC max_frame_length is larger than Port 
max_frame_length\n);
+   return -EINVAL;
+   }
+   return 0;
+}
+
 u16 fm_get_clock_freq(struct fm_t *fm)
 {
return fm-fm_state-fm_clk_freq;
diff --git a/drivers/net/ethernet/freescale/fman/fm.h 
b/drivers/net/ethernet/freescale/fman/fm.h
index d7eca90..c205357 100644
--- a/drivers/net/ethernet/freescale/fman/fm.h
+++ b/drivers/net/ethernet/freescale/fman/fm.h
@@ -164,6 +164,7 @@ struct fm_iram_regs_t {
 
 struct fm_state_struct_t {
u8 fm_id;
+   enum fm_port_type ports_types[FM_MAX_NUM_OF_HW_PORT_IDS];
u16 fm_clk_freq;
struct fm_revision_info_t rev_info;
bool enabled_time_stamp;
@@ -183,6 +184,8 @@ struct fm_state_struct_t {
u32 extra_fifo_pool_size;
u8 extra_tasks_pool_size;
u8 extra_open_dmas_pool_size;
+   u16 port_mfl[FM_MAX_NUM_OF_MACS];
+   u16 mac_mfl[FM_MAX_NUM_OF_MACS];
 };
 
 struct fm_intg_t {
diff --git a/drivers/net/ethernet/freescale/fman/fm_common.h 
b/drivers/net/ethernet/freescale/fman/fm_common.h
index 1cde270..abe89a7 100644
--- a/drivers/net/ethernet/freescale/fman/fm_common.h
+++ b/drivers/net/ethernet/freescale/fman/fm_common.h
@@ -86,6 +86,26 @@ enum fm_inter_module_event 

[v4, 7/9] fsl/fman: Add FMan SP support

2015-08-05 Thread igal.liberman
From: Igal Liberman igal.liber...@freescale.com

Add Storage Profiles support.
The Storage Profiles contain parameters that are used by the FMan in
order to store frames being received on the Rx ports, or to
determine the parameters that affect writing the Internal Context
in the frame margin on Tx.

Signed-off-by: Igal Liberman igal.liber...@freescale.com
---
 drivers/net/ethernet/freescale/fman/Makefile   |2 +
 drivers/net/ethernet/freescale/fman/fm_sp_common.h |  105 ++
 drivers/net/ethernet/freescale/fman/sp/Makefile|3 +
 drivers/net/ethernet/freescale/fman/sp/fm_sp.c |  371 
 4 files changed, 481 insertions(+)
 create mode 100644 drivers/net/ethernet/freescale/fman/fm_sp_common.h
 create mode 100644 drivers/net/ethernet/freescale/fman/sp/Makefile
 create mode 100644 drivers/net/ethernet/freescale/fman/sp/fm_sp.c

diff --git a/drivers/net/ethernet/freescale/fman/Makefile 
b/drivers/net/ethernet/freescale/fman/Makefile
index f61d3a6..c6c3e24 100644
--- a/drivers/net/ethernet/freescale/fman/Makefile
+++ b/drivers/net/ethernet/freescale/fman/Makefile
@@ -8,3 +8,5 @@ fsl_fman-objs   := fman.o fm_muram.o fm.o fm_drv.o
 
 obj-y  += port/
 obj-y  += mac/
+obj-y  += sp/
+
diff --git a/drivers/net/ethernet/freescale/fman/fm_sp_common.h 
b/drivers/net/ethernet/freescale/fman/fm_sp_common.h
new file mode 100644
index 000..56bd749
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/fm_sp_common.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2008-2015 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ *   names of its contributors may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License (GPL) as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* FM SP  ... */
+#ifndef __FM_SP_COMMON_H
+#define __FM_SP_COMMON_H
+
+#include fm_ext.h
+#include fsl_fman.h
+
+#define ILLEGAL_BASE(~0)
+
+/* defaults */
+#define DEFAULT_FM_SP_BUFFER_PREFIX_CONTENT_PRIV_DATA_SIZE  0
+#define DEFAULT_FM_SP_BUFFER_PREFIX_CONTENT_PRIV_PASS_PRS_RESULT false
+#define DEFAULT_FM_SP_BUFFER_PREFIX_CONTEXT_PASS_TIME_STAMP false
+#define DEFAULT_FM_SP_BUFFER_PREFIX_CONTEXT_DATA_ALIGN 64
+
+/* structure for defining internal context copying */
+struct fm_sp_int_context_data_copy_t {
+   /*  Offset in External buffer to which internal
+*  context is copied to (Rx) or taken from (Tx, Op).
+*/
+   u16 ext_buf_offset;
+   /* Offset within internal context to copy from
+* (Rx) or to copy to (Tx, Op).
+*/
+   u8 int_context_offset;
+   /* Internal offset size to be copied */
+   u16 size;
+};
+
+/*  struct for defining external buffer margins */
+struct fm_sp_buf_margins_t {
+   /* Number of bytes to be left at the beginning
+* of the external buffer (must be divisible by 16)
+*/
+   u16 start_margins;
+   /* number of bytes to be left at the end
+* of the external buffer(must be divisible by 16)
+*/
+   u16 end_margins;
+};
+
+struct fm_sp_buffer_offsets_t {
+   u32 data_offset;
+   u32 prs_result_offset;
+   u32 time_stamp_offset;
+   u32 hash_result_offset;
+};
+
+int fm_sp_build_buffer_structure(struct fm_sp_int_context_data_copy_t
+*fm_port_int_context_data_copy,
+struct fm_buffer_prefix_content_t
+ 

[v4, 9/9] fsl/fman: Add FMan MAC driver

2015-08-05 Thread igal.liberman
From: Igal Liberman igal.liber...@freescale.com

This patch adds the Ethernet MAC driver support.

Signed-off-by: Igal Liberman igal.liber...@freescale.com
Signed-off-by: Madalin Bucur madalin.bu...@freescale.com
---
 drivers/net/ethernet/freescale/fman/inc/mac.h |  135 
 drivers/net/ethernet/freescale/fman/mac/Makefile  |3 +-
 drivers/net/ethernet/freescale/fman/mac/mac-api.c |  688 +
 drivers/net/ethernet/freescale/fman/mac/mac.c |  445 +
 4 files changed, 1270 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ethernet/freescale/fman/inc/mac.h
 create mode 100644 drivers/net/ethernet/freescale/fman/mac/mac-api.c
 create mode 100644 drivers/net/ethernet/freescale/fman/mac/mac.c

diff --git a/drivers/net/ethernet/freescale/fman/inc/mac.h 
b/drivers/net/ethernet/freescale/fman/inc/mac.h
new file mode 100644
index 000..f86d0bc
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/inc/mac.h
@@ -0,0 +1,135 @@
+/* Copyright 2008-2015 Freescale Semiconductor, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ *  names of its contributors may be used to endorse or promote products
+ *  derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License (GPL) as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MAC_H
+#define __MAC_H
+
+#include linux/device.h  /* struct device, BUS_ID_SIZE */
+#include linux/if_ether.h/* ETH_ALEN */
+#include linux/phy.h /* phy_interface_t, struct phy_device */
+#include linux/list.h
+
+#include enet_ext.h
+
+#include fsl_fman_drv.h  /* struct port_device */
+#include fm_port_ext.h
+
+struct fm_mac_dev;
+enum fm_mac_exceptions;
+
+enum {DTSEC, XGMAC, MEMAC};
+
+struct mac_device {
+   struct device   *dev;
+   void*priv;
+   u8   cell_index;
+   struct resource *res;
+   void __iomem*vaddr;
+   u8   addr[ETH_ALEN];
+   bool promisc;
+
+   struct fm   *fm_dev;
+   struct fm_port_drv_t*port_dev[2];
+
+   phy_interface_t  phy_if;
+   u32  if_support;
+   bool link;
+   bool fixed_link;
+   u16  speed;
+   u16  max_speed;
+   struct device_node  *phy_node;
+   struct device_node  *tbi_node;
+   struct phy_device   *phy_dev;
+   void*fm;
+   /* List of multicast addresses */
+   struct list_head mc_addr_list;
+   struct platform_device  *eth_dev;
+
+   bool autoneg_pause;
+   bool rx_pause_req;
+   bool tx_pause_req;
+   bool rx_pause_active;
+   bool tx_pause_active;
+
+   int (*init_phy)(struct net_device *net_dev, struct mac_device *mac_dev);
+   int (*init)(struct mac_device *mac_dev);
+   int (*start)(struct mac_device *mac_dev);
+   int (*stop)(struct mac_device *mac_dev);
+   int (*set_promisc)(struct fm_mac_dev *fm_mac_dev, bool enable);
+   int (*change_addr)(struct fm_mac_dev *fm_mac_dev,
+  enet_addr_t *p_enet_addr);
+   int (*set_multi)(struct net_device *net_dev,
+struct mac_device *mac_dev);
+   int (*set_rx_pause)(struct fm_mac_dev *fm_mac_dev, bool en);
+   int (*set_tx_pause)(struct fm_mac_dev *fm_mac_dev, u8 priority,
+ 

[v4, 8/9] fsl/fman: Add FMan Port Support

2015-08-05 Thread igal.liberman
From: Igal Liberman igal.liber...@freescale.com

This patch adds The FMan Port configuration, initialization and
runtime control routines.

Signed-off-by: Igal Liberman igal.liber...@freescale.com
---
 drivers/net/ethernet/freescale/fman/Makefile   |2 +-
 drivers/net/ethernet/freescale/fman/fm.c   |  251 -
 drivers/net/ethernet/freescale/fman/fm_common.h|   35 +
 drivers/net/ethernet/freescale/fman/fm_drv.c   |   72 +-
 drivers/net/ethernet/freescale/fman/fm_drv.h   |2 +
 drivers/net/ethernet/freescale/fman/fm_port_drv.c  |  372 +++
 .../net/ethernet/freescale/fman/inc/fm_port_ext.h  |  340 ++
 .../net/ethernet/freescale/fman/inc/fsl_fman_drv.h |  104 ++
 drivers/net/ethernet/freescale/fman/port/Makefile  |2 +-
 drivers/net/ethernet/freescale/fman/port/fm_port.c | 1081 
 drivers/net/ethernet/freescale/fman/port/fm_port.h |  502 +
 11 files changed, 2759 insertions(+), 4 deletions(-)
 create mode 100644 drivers/net/ethernet/freescale/fman/fm_port_drv.c
 create mode 100644 drivers/net/ethernet/freescale/fman/inc/fm_port_ext.h
 create mode 100644 drivers/net/ethernet/freescale/fman/port/fm_port.c
 create mode 100644 drivers/net/ethernet/freescale/fman/port/fm_port.h

diff --git a/drivers/net/ethernet/freescale/fman/Makefile 
b/drivers/net/ethernet/freescale/fman/Makefile
index c6c3e24..8d637e2 100644
--- a/drivers/net/ethernet/freescale/fman/Makefile
+++ b/drivers/net/ethernet/freescale/fman/Makefile
@@ -4,7 +4,7 @@ subdir-ccflags-y += 
-I$(srctree)/drivers/net/ethernet/freescale/fman/flib \
 
 obj-y  += fsl_fman.o
 
-fsl_fman-objs  := fman.o fm_muram.o fm.o fm_drv.o
+fsl_fman-objs  := fman.o fm_muram.o fm.o fm_drv.o fm_port_drv.o
 
 obj-y  += port/
 obj-y  += mac/
diff --git a/drivers/net/ethernet/freescale/fman/fm.c 
b/drivers/net/ethernet/freescale/fman/fm.c
index 450ee6b..a8ecf0b 100644
--- a/drivers/net/ethernet/freescale/fman/fm.c
+++ b/drivers/net/ethernet/freescale/fman/fm.c
@@ -376,11 +376,29 @@ static void qmi_err_event(struct fm_t *fm)
 
 static void dma_err_event(struct fm_t *fm)
 {
-   u32 status;
+   u32 status, com_id;
+   u8 tnum, port_id, relative_port_id;
+   u16 liodn;
struct fman_dma_regs __iomem *dma_rg = fm-dma_regs;
 
status = fman_get_dma_err_event(dma_rg);
 
+   if (status  DMA_STATUS_BUS_ERR) {
+   com_id = fman_get_dma_com_id(dma_rg);
+   port_id = (u8)(((com_id  DMA_TRANSFER_PORTID_MASK) 
+  DMA_TRANSFER_PORTID_SHIFT));
+   relative_port_id =
+   hw_port_id_to_sw_port_id(fm-fm_state-rev_info.major_rev,
+port_id);
+   tnum = (u8)((com_id  DMA_TRANSFER_TNUM_MASK) 
+   DMA_TRANSFER_TNUM_SHIFT);
+   liodn = (u16)(com_id  DMA_TRANSFER_LIODN_MASK);
+   WARN_ON(fm-fm_state-ports_types[port_id] ==
+   FM_PORT_TYPE_DUMMY);
+   fm-bus_error_cb(fm-dev_id, fm-fm_state-ports_types[port_id],
+relative_port_id,
+fman_get_dma_addr(dma_rg), tnum, liodn);
+   }
if (status  DMA_STATUS_FM_SPDAT_ECC)
fm-exception_cb(fm-dev_id, FM_EX_DMA_SINGLE_PORT_ECC);
if (status  DMA_STATUS_READ_ECC)
@@ -587,6 +605,233 @@ u8 fm_get_id(struct fm_t *fm)
return fm-fm_state-fm_id;
 }
 
+int fm_get_set_port_params(struct fm_t *fm,
+  struct fm_inter_module_port_init_params_t
+  *port_params)
+{
+   int err;
+   unsigned long int_flags;
+   u8 port_id = port_params-port_id, mac_id;
+   struct fman_rg fman_rg;
+
+   fman_rg.bmi_rg = fm-bmi_regs;
+   fman_rg.qmi_rg = fm-qmi_regs;
+   fman_rg.fpm_rg = fm-fpm_regs;
+   fman_rg.dma_rg = fm-dma_regs;
+
+   spin_lock_irqsave(fm-spinlock, int_flags);
+
+   fm-fm_state-ports_types[port_id] = port_params-port_type;
+
+   err = fm_set_num_of_tasks(fm, port_params-port_id,
+ port_params-num_of_tasks,
+ port_params-num_of_extra_tasks);
+   if (err) {
+   spin_unlock_irqrestore(fm-spinlock, int_flags);
+   return err;
+   }
+
+   /* TX Ports */
+   if (port_params-port_type != FM_PORT_TYPE_RX) {
+   u32 enq_th;
+   u32 deq_th;
+
+   /* update qmi ENQ/DEQ threshold */
+   fm-fm_state-accumulated_num_of_deq_tnums +=
+   port_params-deq_pipeline_depth;
+   enq_th = fman_get_qmi_enq_th(fman_rg.qmi_rg);
+   /* if enq_th is too big, we reduce it to the max value
+* that is still 0
+*/
+   if (enq_th = (fm-intg-qmi_max_num_of_tnums -
+   fm-fm_state-accumulated_num_of_deq_tnums)) {
+   enq_th =
+

[v4, 5/9] fsl/fman: Add Frame Manager support

2015-08-05 Thread igal.liberman
From: Igal Liberman igal.liber...@freescale.com

Add Frame Manger Driver support.
This patch adds The FMan configuration, initialization and
runtime control routines.

Signed-off-by: Igal Liberman igal.liber...@freescale.com
---
 drivers/net/ethernet/freescale/fman/Makefile   |2 +-
 drivers/net/ethernet/freescale/fman/fm.c   | 1076 
 drivers/net/ethernet/freescale/fman/fm.h   |  276 +
 drivers/net/ethernet/freescale/fman/fm_common.h|  114 +++
 drivers/net/ethernet/freescale/fman/fm_drv.c   |  551 ++
 drivers/net/ethernet/freescale/fman/fm_drv.h   |  109 ++
 drivers/net/ethernet/freescale/fman/inc/enet_ext.h |  199 
 drivers/net/ethernet/freescale/fman/inc/fm_ext.h   |  446 
 .../net/ethernet/freescale/fman/inc/fsl_fman_drv.h |   99 ++
 9 files changed, 2871 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ethernet/freescale/fman/fm.c
 create mode 100644 drivers/net/ethernet/freescale/fman/fm.h
 create mode 100644 drivers/net/ethernet/freescale/fman/fm_common.h
 create mode 100644 drivers/net/ethernet/freescale/fman/fm_drv.c
 create mode 100644 drivers/net/ethernet/freescale/fman/fm_drv.h
 create mode 100644 drivers/net/ethernet/freescale/fman/inc/enet_ext.h
 create mode 100644 drivers/net/ethernet/freescale/fman/inc/fm_ext.h
 create mode 100644 drivers/net/ethernet/freescale/fman/inc/fsl_fman_drv.h

diff --git a/drivers/net/ethernet/freescale/fman/Makefile 
b/drivers/net/ethernet/freescale/fman/Makefile
index 55c91bd..f61d3a6 100644
--- a/drivers/net/ethernet/freescale/fman/Makefile
+++ b/drivers/net/ethernet/freescale/fman/Makefile
@@ -4,7 +4,7 @@ subdir-ccflags-y += 
-I$(srctree)/drivers/net/ethernet/freescale/fman/flib \
 
 obj-y  += fsl_fman.o
 
-fsl_fman-objs  := fman.o fm_muram.o
+fsl_fman-objs  := fman.o fm_muram.o fm.o fm_drv.o
 
 obj-y  += port/
 obj-y  += mac/
diff --git a/drivers/net/ethernet/freescale/fman/fm.c 
b/drivers/net/ethernet/freescale/fman/fm.c
new file mode 100644
index 000..7e5fa53
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/fm.c
@@ -0,0 +1,1076 @@
+/*
+ * Copyright 2008-2015 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ *   names of its contributors may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License (GPL) as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME :  fmt
+
+#include fm_common.h
+#include fm.h
+#include fm_muram_ext.h
+#include asm/mpc85xx.h
+#include fsl_fman.h
+
+#include linux/string.h
+#include linux/slab.h
+
+static struct fm_intg_t *fill_intg_params(u8 major, u8 minor)
+{
+   struct fm_intg_t *intg;
+
+   intg = kzalloc(sizeof(*intg), GFP_KERNEL);
+   if (!intg)
+   return NULL;
+
+   /* P1023 - Major 4
+* P4080 - Major 2
+* P2041/P3041/P5020/P5040 - Major 3
+* Tx/Bx - Major 6
+*/
+
+   switch (major) {
+   case FM_IP_BLOCK_P2_P3_P5:
+   intg-fm_muram_size = 160 * 1024;
+   intg-fm_iram_size  = 64 * 1024;
+   intg-fm_num_of_ctrl= 2;
+
+   intg-dma_thresh_max_commq  = 31;
+   intg-dma_thresh_max_buf= 127;
+
+   intg-qmi_max_num_of_tnums  = 64;
+   intg-qmi_def_tnums_thresh  = 48;
+
+   

Re: GPMC in device tree

2015-08-05 Thread Ran Shalit
On Wed, Aug 5, 2015 at 9:11 AM, Ran Shalit ransha...@gmail.com wrote:
 On Wed, Aug 5, 2015 at 6:56 AM, Ran Shalit ransha...@gmail.com wrote:
 On Wed, Aug 5, 2015 at 12:25 AM, Scott Wood scottw...@freescale.com wrote:
 On Wed, 2015-08-05 at 00:22 +0300, Ran Shalit wrote:
 On Tue, Aug 4, 2015 at 11:31 PM, Scott Wood scottw...@freescale.com 
 wrote:
  On Tue, 2015-08-04 at 23:26 +0300, Ran Shalit wrote:
   On Tue, Aug 4, 2015 at 9:54 PM, Scott Wood scottw...@freescale.com
   wrote:
On Tue, 2015-08-04 at 18:29 +0300, Ran Shalit wrote:
 Hello,

 I would please like to ask if describing flash nor used with GPMC,
 whould be done as described in:
 https://www.kernel.org/doc/Documentation/devicetree/bindings/mtd/gpmc-nor.txt
 It is described in the above link as TI's GPMC, so I'm not sure 
 if
 it is relevent for powerpc too.
   
That binding is for TI GPMC.
   
Are you saying you have some PPC chip that has a flash controller
called
GPMC?
   
-Scott
   
  
   Hi Scott,
  
   Thanks, I've worked with TI's chips, so I now understand that I made
   here some confusion...
   It is GPCM , not GPMC, my mistake.
   We already configured it in u-boot, but on doing read/write from
   kernel it doesn not work.
   It seems that for the linux to use the correct driver, we need to
   define the nor in the device tree.
   Is there any example how to define nor GPCM in device tree ? Is it
   possible not to override the existing GPCM configuration ?
 
  Pretty much all of the mpc8xxx/qoriq device trees have GPCM NOR defined.
  See
  Documentation/devicetree/bindings/powerpc/fsl/lbc.txt and examples such 
  as
  arch/powerpc/boot/dts/p4080ds.dts (part of the lbc node is in
  arch/powerpc/boot/dts/fsl/p4080si-post.dtsi).
 
  Linux will not change the GPCM configuration.
 
  -Scott
 

 On more thing, if I may.
 The localbus is also connected to nvram  cpld.
 I've noticed that read/write works well, even though I didn't define
 anything in device tree.
 Is there any reasom to add these devices into device tree, or can we
 use the cpld and nvram without the definition in device tree ?

 I don't know what you're doing in your kernel to access devices that aren't
 in the device tree.  You should add the devices to the device tree, and have
 the kernel use it rather than hardcoded info.

 -Scott

 Hi,

 Yes I understand.
 But It is worse noting that I have no localbus entry in the device tree.
 Yes, The nvram, cpld which are both connected to device tree, seems to
 work without any issues.

 Thanks,
 Ran

 I apologyze for the bad english, I meant it worth to note that there
 is no localbus entry at all in the device tree.
 So I wander how the nvram and cpld worked...
 If I may please ask, what should be the compatible for generic
 devices such as  nvram/cpld ?
 I assume that if they worked without any entry, it means that there is
 no need for specific driver.

 Regards,
 Ran

Hi,

After studing the localbus configuration as should be configured in
device tree for powerpc, I think I have come with the following
configuration, (not yet tested on board):


localbus@e0005000 {
#address-cells = 2;
#size-cells = 1;
compatible = fsl,mpc8349-localbus, simple-bus;
 reg = 0xe0005000 0x1000;
 interrupts = 77 0x8;
 interrupt-parent = ipic;


/* NOR and NAND Flashes */
   ranges = 0x0 0x0 0xff80 0x0080 /* 8MB NOR Flash */
 0x1 0x0 0xF800 0x0800  /* User flash (same
nor, in burst mode) 128M */
 0x2 0x0 0xf7e0 0x0020;/*NVRAM/CPLD C2 is
selected in CPLD , */
/*nvram 0xf7e0 1MB */
/*cpld  0xf7f0 1M  (- different address!)*/
nor@0,0 {
#address-cells = 1;
#size-cells = 1;
compatible = cfi-flash;
reg = 0x0 0x0 0x100;
#bank-width = 1;
device-width = 4;

};
};

I have some isssue I'm not sure about, and wanted a second opinion:

1. I have not added entry for NVRAM/CPLD (8 bit width interfaces) ,
but only specifies it in ranges , I assume it is not required becuase
it is probably can be treated as simple ram. Is this assumption
correct ?

2. The NVRAM/CPLD  is using CS2 , which is configured for 2 MB space.
The 2 MB is divided to two 1 MB slices. 1 MB is dedicated for NVRAM
(though the NVRAM is only 128 KB) and 1 MB is dedicated for CPLD. The
division of CS2 into two regions is done in CPLD.
0xf7e0 - for NVRAM , 0x0010
0xf7f0 - for CPLD ,  0x0010

Is it correct to be configured as one range as done above  (0x2 0x0
0xf7e0 0x0020)  ?

Thank you very much,
Ran
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 1/6][RESEND] ASoC: fsl_ssi: enable IPG clock during AC'97 reg access

2015-08-05 Thread Maciej S. Szmigiero
IPG clock have to be enabled during AC'97 CODEC register
access in fsl_ssi driver.

Signed-off-by: Maciej Szmigiero m...@maciej.szmigiero.name
---
This is a resend without changes, to keep the whole series
together.

 sound/soc/fsl/fsl_ssi.c |   19 +++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 484ff20..8185edc 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -1127,10 +1127,17 @@ static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, 
unsigned short reg,
struct regmap *regs = fsl_ac97_data-regs;
unsigned int lreg;
unsigned int lval;
+   int ret;
 
if (reg  0x7f)
return;
 
+   ret = clk_prepare_enable(fsl_ac97_data-clk);
+   if (ret) {
+   pr_err(ac97 write clk_prepare_enable failed: %d\n,
+   ret);
+   return;
+   }
 
lreg = reg   12;
regmap_write(regs, CCSR_SSI_SACADD, lreg);
@@ -1141,6 +1148,8 @@ static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, 
unsigned short reg,
regmap_update_bits(regs, CCSR_SSI_SACNT, CCSR_SSI_SACNT_RDWR_MASK,
CCSR_SSI_SACNT_WR);
udelay(100);
+
+   clk_disable_unprepare(fsl_ac97_data-clk);
 }
 
 static unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97,
@@ -1151,6 +1160,14 @@ static unsigned short fsl_ssi_ac97_read(struct snd_ac97 
*ac97,
unsigned short val = -1;
u32 reg_val;
unsigned int lreg;
+   int ret;
+
+   ret = clk_prepare_enable(fsl_ac97_data-clk);
+   if (ret) {
+   pr_err(ac97 read clk_prepare_enable failed: %d\n,
+   ret);
+   return -1;
+   }
 
lreg = (reg  0x7f)   12;
regmap_write(regs, CCSR_SSI_SACADD, lreg);
@@ -1162,6 +1179,8 @@ static unsigned short fsl_ssi_ac97_read(struct snd_ac97 
*ac97,
regmap_read(regs, CCSR_SSI_SACDAT, reg_val);
val = (reg_val  4)  0x;
 
+   clk_disable_unprepare(fsl_ac97_data-clk);
+
return val;
 }
 

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 2/6][RESEND] ASoC: fsl_ssi: AC'97 DAI driver needs probe method too

2015-08-05 Thread Maciej S. Szmigiero
AC'97 DAI driver struct need the same probe method as
I2S one to setup DMA params in fsl_ssi driver.

Signed-off-by: Maciej Szmigiero m...@maciej.szmigiero.name
---
This is a resend without changes, to keep the whole series
together.

 sound/soc/fsl/fsl_ssi.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 8185edc..a83b900 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -1101,6 +1101,7 @@ static const struct snd_soc_component_driver 
fsl_ssi_component = {
 
 static struct snd_soc_dai_driver fsl_ssi_ac97_dai = {
.bus_control = true,
+   .probe = fsl_ssi_dai_probe,
.playback = {
.stream_name = AC97 Playback,
.channels_min = 2,

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 3/6][RESEND] ASoC: fsl_ssi: enable AC'97 asymmetric rates

2015-08-05 Thread Maciej S. Szmigiero
AC'97 bus can support asymmetric playback/capture rates
so enable them in this case in fsl_ssi driver.

Signed-off-by: Maciej Szmigiero m...@maciej.szmigiero.name
---
This is a resend without changes, to keep the whole series
together.

 sound/soc/fsl/fsl_ssi.c |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index a83b900..7f4f0b9 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -1377,7 +1377,9 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 
/* Are the RX and the TX clocks locked? */
if (!of_find_property(np, fsl,ssi-asynchronous, NULL)) {
-   ssi_private-cpu_dai_drv.symmetric_rates = 1;
+   if (!fsl_ssi_is_ac97(ssi_private))
+   ssi_private-cpu_dai_drv.symmetric_rates = 1;
+
ssi_private-cpu_dai_drv.symmetric_channels = 1;
ssi_private-cpu_dai_drv.symmetric_samplebits = 1;
}

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 5/6][RESEND] ASoC: fsl_ssi: instantiate AC'97 CODEC

2015-08-05 Thread Maciej S. Szmigiero
Instantiate AC'97 CODEC in fsl_ssi driver AC'97 mode.

Signed-off-by: Maciej Szmigiero m...@maciej.szmigiero.name
---
This is a resend without changes, to keep the whole series
together.

 sound/soc/fsl/fsl_ssi.c |   21 +
 1 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 154bcf6..8e5ff5e 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -1460,6 +1460,27 @@ done:
_fsl_ssi_set_dai_fmt(pdev-dev, ssi_private,
 ssi_private-dai_fmt);
 
+   if (fsl_ssi_is_ac97(ssi_private)) {
+   u32 ssi_idx;
+
+   ret = of_property_read_u32(np, cell-index, ssi_idx);
+   if (ret) {
+   dev_err(pdev-dev, cannot get SSI index property\n);
+   goto error_sound_card;
+   }
+
+   ssi_private-pdev =
+   platform_device_register_data(NULL,
+   ac97-codec, ssi_idx, NULL, 0);
+   if (IS_ERR(ssi_private-pdev)) {
+   ret = PTR_ERR(ssi_private-pdev);
+   dev_err(pdev-dev,
+   failed to register AC97 codec platform: %d\n,
+   ret);
+   goto error_sound_card;
+   }
+   }
+
return 0;
 
 error_sound_card:

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 6/6 v2][RESEND] ASoC: fsl_ssi: adjust set DAI format in AC'97 mode

2015-08-05 Thread Maciej S. Szmigiero
Adjust set DAI format function in fsl_ssi driver
so it doesn't fail and clears RXDIR in AC'97 mode.

Signed-off-by: Maciej Szmigiero m...@maciej.szmigiero.name
---
Changes from v1: fix indentation to be consistent with rest
of the driver.

 sound/soc/fsl/fsl_ssi.c |8 +---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 8e5ff5e..1ba63bd 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -900,14 +900,16 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev,
scr = ~CCSR_SSI_SCR_SYS_CLK_EN;
break;
default:
-   return -EINVAL;
+   if (!fsl_ssi_is_ac97(ssi_private))
+   return -EINVAL;
}
 
stcr |= strcr;
srcr |= strcr;
 
-   if (ssi_private-cpu_dai_drv.symmetric_rates) {
-   /* Need to clear RXDIR when using SYNC mode */
+   if (ssi_private-cpu_dai_drv.symmetric_rates
+   || fsl_ssi_is_ac97(ssi_private)) {
+   /* Need to clear RXDIR when using SYNC or AC97 mode */
srcr = ~CCSR_SSI_SRCR_RXDIR;
scr |= CCSR_SSI_SCR_SYN;
}

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 4/6][RESEND] ASoC: fsl_ssi: add AC'97 ops setting check and cleanup

2015-08-05 Thread Maciej S. Szmigiero
Check whether setting AC'97 ops succeeded and clean them
on removal so the fsl_ssi driver can be reloaded.

Signed-off-by: Maciej Szmigiero m...@maciej.szmigiero.name
---
This is a resend without changes, to keep the whole series
together.

 sound/soc/fsl/fsl_ssi.c |9 -
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 7f4f0b9..154bcf6 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -1340,7 +1340,11 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 
fsl_ac97_data = ssi_private;
 
-   snd_soc_set_ac97_ops_of_reset(fsl_ssi_ac97_ops, pdev);
+   ret = snd_soc_set_ac97_ops_of_reset(fsl_ssi_ac97_ops, pdev);
+   if (ret) {
+   dev_err(pdev-dev, could not set AC'97 ops\n);
+   return ret;
+   }
} else {
/* Initialize this copy of the CPU DAI driver structure */
memcpy(ssi_private-cpu_dai_drv, fsl_ssi_dai_template,
@@ -1480,6 +1484,9 @@ static int fsl_ssi_remove(struct platform_device *pdev)
if (ssi_private-soc-imx)
fsl_ssi_imx_clean(pdev, ssi_private);
 
+   if (fsl_ssi_is_ac97(ssi_private))
+   snd_soc_set_ac97_ops(NULL);
+
return 0;
 }
 

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[v2 0/9] dpaa_eth: Add the Freescale DPAA Ethernet driver

2015-08-05 Thread Madalin Bucur
This patch series adds the Ethernet driver for the Freescale
QorIQ Data Path Acceleration Architecture (DPAA).

This version includes changes following the feedback received
on previous versions from Eric Dumazet, Bob Cochran, Joe Perches,
Paul Bolle, Joakim Tjernlund, Scott Wood, David Miller - thanks!

Together with the driver a managed version of alloc_percpu
is provided that simplifies the release of percpu memory.

The Freescale DPAA architecture consists in a series of hardware
blocks that support the Ethernet connectivity. The Ethernet driver
depends upon the following drivers that are currently in the Linux
kernel or in review:
 - Peripheral Access Memory Unit (PAMU)
drivers/iommu/fsl_*
 - Frame Manager (FMan)
drivers/net/ethernet/freescale/fman
 - Queue Manager (QMan), Buffer Manager (BMan)
drivers/soc/fsl/qbman

The latest FMan driver patches were submitted by Igal Liberman:
https://patchwork.ozlabs.org/project/netdev/list/?submitter=64715state=*q=[v4,

The latest Q/BMan drivers were submitted by Roy Pledge:
https://patchwork.ozlabs.org/project/linuxppc-dev/list/?submitter=66331state=*

Changes from v1:
 - bpool level Kconfig options removed
 - print format using pr_fmt, cleaned up prints
 - __hot/__cold removed
 - gratuitous unlikely() removed
 - code style aligned, consistent spacing for declarations
 - comment formatting

The complete patch set based on the v4.2-rc5 kernel can be found
in the public git http://git.freescale.com/git/cgit.cgi/ppc/upstream/linux.git
under the tag ldup_public_git_20150805:
http://git.freescale.com/git/cgit.cgi/ppc/upstream/linux.git/log/?h=ldup_public_git_20150805

There is one patch that needs to be applied to u-boot to align it
to the latest device tree binding document specification used by
the FMan driver. The patch is under the ldup_public_git_20150410
tag in the public git at:
http://git.freescale.com/git/cgit.cgi/ppc/upstream/u-boot.git/log/?h=ldup_public_git_20150410

Madalin Bucur (9):
  devres: add devm_alloc_percpu()
  dpaa_eth: add support for DPAA Ethernet
  dpaa_eth: add support for S/G frames
  dpaa_eth: add driver's Tx queue selection mechanism
  dpaa_eth: add ethtool functionality
  dpaa_eth: add sysfs exports
  dpaa_eth: add debugfs counters
  dpaa_eth: add debugfs entries
  dpaa_eth: add trace points

 Documentation/driver-model/devres.txt  |4 +
 drivers/base/devres.c  |   64 +
 drivers/net/ethernet/freescale/Kconfig |2 +
 drivers/net/ethernet/freescale/Makefile|1 +
 drivers/net/ethernet/freescale/dpaa/Kconfig|   63 +
 drivers/net/ethernet/freescale/dpaa/Makefile   |   17 +
 drivers/net/ethernet/freescale/dpaa/dpaa_debugfs.c |  272 
 drivers/net/ethernet/freescale/dpaa/dpaa_debugfs.h |   43 +
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c |  860 +
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h |  489 +++
 .../net/ethernet/freescale/dpaa/dpaa_eth_common.c  | 1358 
 .../net/ethernet/freescale/dpaa/dpaa_eth_common.h  |  129 ++
 drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c  |  704 ++
 .../net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c   |  167 +++
 .../net/ethernet/freescale/dpaa/dpaa_eth_trace.h   |  141 ++
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c |  230 
 include/linux/device.h |   19 +
 17 files changed, 4563 insertions(+)
 create mode 100644 drivers/net/ethernet/freescale/dpaa/Kconfig
 create mode 100644 drivers/net/ethernet/freescale/dpaa/Makefile
 create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_debugfs.c
 create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_debugfs.h
 create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
 create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
 create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c
 create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h
 create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c
 create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c
 create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth_trace.h
 create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c

-- 
1.7.11.7

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[v2 1/9] devres: add devm_alloc_percpu()

2015-08-05 Thread Madalin Bucur
Introduce managed counterparts for alloc_percpu() and free_percpu().
Add devm_alloc_percpu() and devm_free_percpu() into the managed
interfaces list.

Signed-off-by: Madalin Bucur madalin.bu...@freescale.com
---
 Documentation/driver-model/devres.txt |  4 +++
 drivers/base/devres.c | 64 +++
 include/linux/device.h| 19 +++
 3 files changed, 87 insertions(+)

diff --git a/Documentation/driver-model/devres.txt 
b/Documentation/driver-model/devres.txt
index 831a536..595fd1b 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -312,6 +312,10 @@ MEM
   devm_kvasprintf()
   devm_kzalloc()
 
+PER-CPU MEM
+  devm_alloc_percpu()
+  devm_free_percpu()
+
 PCI
   pcim_enable_device() : after success, all PCI ops become managed
   pcim_pin_device(): keep PCI device enabled after release
diff --git a/drivers/base/devres.c b/drivers/base/devres.c
index c8a53d1..deb2ea0 100644
--- a/drivers/base/devres.c
+++ b/drivers/base/devres.c
@@ -10,6 +10,7 @@
 #include linux/device.h
 #include linux/module.h
 #include linux/slab.h
+#include linux/percpu.h
 
 #include base.h
 
@@ -984,3 +985,66 @@ void devm_free_pages(struct device *dev, unsigned long 
addr)
   devres));
 }
 EXPORT_SYMBOL_GPL(devm_free_pages);
+
+static void devm_percpu_release(struct device *dev, void *pdata)
+{
+   void __percpu *p;
+
+   p = *(void __percpu **)pdata;
+   free_percpu(p);
+}
+
+static int devm_percpu_match(struct device *dev, void *data, void *p)
+{
+   struct devres *devr = container_of(data, struct devres, data);
+
+   return *(void **)devr-data == p;
+}
+
+/**
+ * __devm_alloc_percpu - Resource-managed alloc_percpu
+ * @dev: Device to allocate per-cpu memory for
+ * @size: Size of per-cpu memory to allocate
+ * @align: Alignement of per-cpu memory to allocate
+ *
+ * Managed alloc_percpu. Per-cpu memory allocated with this function is
+ * automatically freed on driver detach.
+ *
+ * RETURNS:
+ * Pointer to allocated memory on success, NULL on failure.
+ */
+void __percpu *__devm_alloc_percpu(struct device *dev, size_t size,
+   size_t align)
+{
+   void *p;
+   void __percpu *pcpu;
+
+   pcpu = __alloc_percpu(size, align);
+   if (!pcpu)
+   return NULL;
+
+   p = devres_alloc(devm_percpu_release, sizeof(void *), GFP_KERNEL);
+   if (!p)
+   return NULL;
+
+   *(void __percpu **)p = pcpu;
+
+   devres_add(dev, p);
+
+   return pcpu;
+}
+EXPORT_SYMBOL_GPL(__devm_alloc_percpu);
+
+/**
+ * devm_free_percpu - Resource-managed free_percpu
+ * @dev: Device this memory belongs to
+ * @pdata: Per-cpu memory to free
+ *
+ * Free memory allocated with devm_alloc_percpu().
+ */
+void devm_free_percpu(struct device *dev, void __percpu *pdata)
+{
+   WARN_ON(devres_destroy(dev, devm_percpu_release, devm_percpu_match,
+  (void *)pdata));
+}
+EXPORT_SYMBOL_GPL(devm_free_percpu);
diff --git a/include/linux/device.h b/include/linux/device.h
index a2b4ea7..126c25b 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -673,6 +673,25 @@ void __iomem *devm_ioremap_resource(struct device *dev, 
struct resource *res);
 int devm_add_action(struct device *dev, void (*action)(void *), void *data);
 void devm_remove_action(struct device *dev, void (*action)(void *), void 
*data);
 
+/**
+ * devm_alloc_percpu - Resource-managed alloc_percpu
+ * @dev: Device to allocate per-cpu memory for
+ * @type: Type to allocate per-cpu memory for
+ *
+ * Managed alloc_percpu. Per-cpu memory allocated with this function is
+ * automatically freed on driver detach.
+ *
+ * RETURNS:
+ * Pointer to allocated memory on success, NULL on failure.
+ */
+#define devm_alloc_percpu(dev, type)  \
+   (typeof(type) __percpu *)__devm_alloc_percpu(dev, sizeof(type), \
+__alignof__(type))
+
+void __percpu *__devm_alloc_percpu(struct device *dev, size_t size,
+  size_t align);
+void devm_free_percpu(struct device *dev, void __percpu *pdata);
+
 struct device_dma_parameters {
/*
 * a low level driver may set these to teach IOMMU code about
-- 
1.7.11.7

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[v2 3/9] dpaa_eth: add support for S/G frames

2015-08-05 Thread Madalin Bucur
Add support for Scater/Gather (S/G) frames. The FMan can place
the frame content into multiple buffers and provide a S/G Table
(SGT) into one first buffer with references to the others.

Signed-off-by: Madalin Bucur madalin.bu...@freescale.com
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c |   6 +
 .../net/ethernet/freescale/dpaa/dpaa_eth_common.c  |  47 ++-
 .../net/ethernet/freescale/dpaa/dpaa_eth_common.h  |   2 +
 drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c  | 335 +++--
 4 files changed, 370 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 9e83bd1..53c37cd 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -460,6 +460,12 @@ static int dpa_private_netdev_init(struct net_device 
*net_dev)
net_dev-hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_LLTX);
 
+   /* Advertise S/G and HIGHDMA support for private interfaces */
+   net_dev-hw_features |= NETIF_F_SG | NETIF_F_HIGHDMA;
+   /* Recent kernels enable GSO automatically, if
+* we declare NETIF_F_SG. For conformity, we'll
+* still declare GSO explicitly.
+*/
net_dev-features |= NETIF_F_GSO;
 
return dpa_netdev_init(net_dev, mac_addr, tx_timeout);
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c
index 10f08f7..7e4b9bd 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c
@@ -1122,6 +1122,35 @@ void dpaa_eth_init_ports(struct mac_device *mac_dev,
  port_fqs-rx_defq, buf_layout[RX]);
 }
 
+void dpa_release_sgt(struct qm_sg_entry *sgt)
+{
+   struct dpa_bp *dpa_bp;
+   struct bm_buffer bmb[DPA_BUFF_RELEASE_MAX];
+   u8 i = 0, j;
+
+   memset(bmb, 0, sizeof(bmb));
+
+   do {
+   dpa_bp = dpa_bpid2pool(sgt[i].bpid);
+   DPA_ERR_ON(!dpa_bp);
+
+   j = 0;
+   do {
+   DPA_ERR_ON(sgt[i].extension);
+
+   bmb[j].hi = sgt[i].addr_hi;
+   bmb[j].lo = sgt[i].addr_lo;
+
+   j++; i++;
+   } while (j  ARRAY_SIZE(bmb) 
+   !sgt[i - 1].final 
+   sgt[i - 1].bpid == sgt[i].bpid);
+
+   while (bman_release(dpa_bp-pool, bmb, j, 0))
+   cpu_relax();
+   } while (!sgt[i - 1].final);
+}
+
 void __attribute__((nonnull))
 dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd)
 {
@@ -1137,7 +1166,23 @@ dpa_fd_release(const struct net_device *net_dev, const 
struct qm_fd *fd)
dpa_bp = dpa_bpid2pool(fd-bpid);
DPA_ERR_ON(!dpa_bp);
 
-   DPA_ERR_ON(fd-format == qm_fd_sg);
+   if (fd-format == qm_fd_sg) {
+   vaddr = phys_to_virt(fd-addr);
+   sgt = vaddr + dpa_fd_offset(fd);
+
+   dma_unmap_single(dpa_bp-dev, qm_fd_addr(fd), dpa_bp-size,
+DMA_BIDIRECTIONAL);
+
+   dpa_release_sgt(sgt);
+
+   addr = dma_map_single(dpa_bp-dev, vaddr, dpa_bp-size,
+ DMA_BIDIRECTIONAL);
+   if (dma_mapping_error(dpa_bp-dev, addr)) {
+   dev_err(dpa_bp-dev, DMA mapping failed);
+   return;
+   }
+   bm_buffer_set64(bmb, addr);
+   }
 
while (bman_release(dpa_bp-pool, bmb, 1, 0))
cpu_relax();
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h
index 93fcf82..bd88dda 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h
@@ -52,6 +52,7 @@
fm_set_##type##_port_params(port, param); \
 }
 
+#define DPA_SGT_MAX_ENTRIES 16 /* maximum number of entries in SG Table */
 #define DPA_BUFF_RELEASE_MAX 8 /* maximum number of buffers released at once */
 
 /* used in napi related functions */
@@ -109,6 +110,7 @@ void dpaa_eth_init_ports(struct mac_device *mac_dev,
 struct fm_port_fqs *port_fqs,
 struct dpa_buffer_layout_s *buf_layout,
 struct device *dev);
+void dpa_release_sgt(struct qm_sg_entry *sgt);
 void __attribute__((nonnull))
 dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd);
 int dpa_enable_tx_csum(struct dpa_priv_s *priv,
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c
index 15713a6..6050448 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c
@@ -53,6 +53,31 @@
   

[v2 2/9] dpaa_eth: add support for DPAA Ethernet

2015-08-05 Thread Madalin Bucur
This introduces the Freescale Data Path Acceleration Architecture
(DPAA) Ethernet driver (dpaa_eth) that builds upon the DPAA QMan,
BMan, PAMU and FMan drivers to deliver Ethernet connectivity on
the Freescale DPAA QorIQ platforms.

Signed-off-by: Madalin Bucur madalin.bu...@freescale.com
---
 drivers/net/ethernet/freescale/Kconfig |2 +
 drivers/net/ethernet/freescale/Makefile|1 +
 drivers/net/ethernet/freescale/dpaa/Kconfig|   46 +
 drivers/net/ethernet/freescale/dpaa/Makefile   |   13 +
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c |  814 +
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h |  442 +++
 .../net/ethernet/freescale/dpaa/dpaa_eth_common.c  | 1248 
 .../net/ethernet/freescale/dpaa/dpaa_eth_common.h  |  118 ++
 drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c  |  406 +++
 9 files changed, 3090 insertions(+)
 create mode 100644 drivers/net/ethernet/freescale/dpaa/Kconfig
 create mode 100644 drivers/net/ethernet/freescale/dpaa/Makefile
 create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
 create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
 create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c
 create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h
 create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c

diff --git a/drivers/net/ethernet/freescale/Kconfig 
b/drivers/net/ethernet/freescale/Kconfig
index f3f89cc..92198be 100644
--- a/drivers/net/ethernet/freescale/Kconfig
+++ b/drivers/net/ethernet/freescale/Kconfig
@@ -92,4 +92,6 @@ config GIANFAR
  and MPC86xx family of chips, the eTSEC on LS1021A and the FEC
  on the 8540.
 
+source drivers/net/ethernet/freescale/dpaa/Kconfig
+
 endif # NET_VENDOR_FREESCALE
diff --git a/drivers/net/ethernet/freescale/Makefile 
b/drivers/net/ethernet/freescale/Makefile
index 4097c58..ae13dc5 100644
--- a/drivers/net/ethernet/freescale/Makefile
+++ b/drivers/net/ethernet/freescale/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_FS_ENET) += fs_enet/
 obj-$(CONFIG_FSL_PQ_MDIO) += fsl_pq_mdio.o
 obj-$(CONFIG_FSL_XGMAC_MDIO) += xgmac_mdio.o
 obj-$(CONFIG_GIANFAR) += gianfar_driver.o
+obj-$(CONFIG_FSL_DPAA_ETH) += dpaa/
 obj-$(CONFIG_PTP_1588_CLOCK_GIANFAR) += gianfar_ptp.o
 gianfar_driver-objs := gianfar.o \
gianfar_ethtool.o
diff --git a/drivers/net/ethernet/freescale/dpaa/Kconfig 
b/drivers/net/ethernet/freescale/dpaa/Kconfig
new file mode 100644
index 000..1f3a203
--- /dev/null
+++ b/drivers/net/ethernet/freescale/dpaa/Kconfig
@@ -0,0 +1,46 @@
+menuconfig FSL_DPAA_ETH
+   tristate DPAA Ethernet
+   depends on FSL_SOC  FSL_BMAN  FSL_QMAN  FSL_FMAN
+   select PHYLIB
+   select FSL_FMAN_MAC
+   ---help---
+ Data Path Acceleration Architecture Ethernet driver,
+ supporting the Freescale QorIQ chips.
+ Depends on Freescale Buffer Manager and Queue Manager
+ driver and Frame Manager Driver.
+
+if FSL_DPAA_ETH
+
+config FSL_DPAA_CS_THRESHOLD_1G
+   hex Egress congestion threshold on 1G ports
+   range 0x1000 0x1000
+   default 0x0600
+   ---help---
+ The size in bytes of the egress Congestion State notification 
threshold on 1G ports.
+ The 1G dTSECs can quite easily be flooded by cores doing Tx in a 
tight loop
+ (e.g. by sending UDP datagrams at while(1) speed),
+ and the larger the frame size, the more acute the problem.
+ So we have to find a balance between these factors:
+  - avoiding the device staying congested for a prolonged time 
(risking
+ the netdev watchdog to fire - see also the tx_timeout module 
param);
+   - affecting performance of protocols such as TCP, which 
otherwise
+behave well under the congestion notification mechanism;
+  - preventing the Tx cores from tightly-looping (as if the 
congestion
+threshold was too low to be effective);
+  - running out of memory if the CS threshold is set too high.
+
+config FSL_DPAA_CS_THRESHOLD_10G
+   hex Egress congestion threshold on 10G ports
+   range 0x1000 0x2000
+   default 0x1000
+   ---help ---
+ The size in bytes of the egress Congestion State notification 
threshold on 10G ports.
+
+config FSL_DPAA_INGRESS_CS_THRESHOLD
+   hex Ingress congestion threshold on FMan ports
+   default 0x1000
+   ---help---
+ The size in bytes of the ingress tail-drop threshold on FMan ports.
+ Traffic piling up above this value will be rejected by QMan and 
discarded by FMan.
+
+endif # FSL_DPAA_ETH
diff --git a/drivers/net/ethernet/freescale/dpaa/Makefile 
b/drivers/net/ethernet/freescale/dpaa/Makefile
new file mode 100644
index 000..cf126dd
--- /dev/null
+++ b/drivers/net/ethernet/freescale/dpaa/Makefile
@@ -0,0 +1,13 @@
+#
+# Makefile for the 

[v2 4/9] dpaa_eth: add driver's Tx queue selection mechanism

2015-08-05 Thread Madalin Bucur
Allow the selection of the transmission queue based on the CPU id.

Signed-off-by: Madalin Bucur madalin.bu...@freescale.com
---
 drivers/net/ethernet/freescale/dpaa/Kconfig   | 10 ++
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c|  3 +++
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h|  6 ++
 drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c |  8 
 drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h |  4 
 5 files changed, 31 insertions(+)

diff --git a/drivers/net/ethernet/freescale/dpaa/Kconfig 
b/drivers/net/ethernet/freescale/dpaa/Kconfig
index 1f3a203..6147403 100644
--- a/drivers/net/ethernet/freescale/dpaa/Kconfig
+++ b/drivers/net/ethernet/freescale/dpaa/Kconfig
@@ -11,6 +11,16 @@ menuconfig FSL_DPAA_ETH
 
 if FSL_DPAA_ETH
 
+config FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
+   bool Use driver's Tx queue selection mechanism
+   default y
+   ---help---
+ The DPAA-Ethernet driver defines a ndo_select_queue() callback for 
optimal selection
+ of the egress FQ. That will override the XPS support for this 
netdevice.
+ If for whatever reason you want to be in control of the egress 
FQ-to-CPU selection and mapping,
+ or simply don't want to use the driver's ndo_select_queue() callback, 
then unselect this
+ and use the standard XPS support instead.
+
 config FSL_DPAA_CS_THRESHOLD_1G
hex Egress congestion threshold on 1G ports
range 0x1000 0x1000
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 53c37cd..264945c 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -387,6 +387,9 @@ static const struct net_device_ops dpa_private_ops = {
.ndo_get_stats64 = dpa_get_stats64,
.ndo_set_mac_address = dpa_set_mac_address,
.ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
+   .ndo_select_queue = dpa_select_queue,
+#endif
.ndo_change_mtu = dpa_change_mtu,
.ndo_set_rx_mode = dpa_set_rx_mode,
.ndo_init = dpa_ndo_init,
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
index d337dcc..55c1106 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
@@ -430,9 +430,15 @@ static inline void _dpa_assign_wq(struct dpa_fq *fq)
}
 }
 
+#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
+/* Use in lieu of skb_get_queue_mapping() */
+#define dpa_get_queue_mapping(skb) \
+   raw_smp_processor_id()
+#else
 /* Use the queue selected by XPS */
 #define dpa_get_queue_mapping(skb) \
skb_get_queue_mapping(skb)
+#endif
 
 static inline void _dpa_bp_free_pf(void *addr)
 {
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c
index 7e4b9bd..1258683 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c
@@ -586,6 +586,14 @@ bool dpa_bpid2pool_use(int bpid)
return false;
 }
 
+#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
+u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb,
+void *accel_priv, select_queue_fallback_t fallback)
+{
+   return dpa_get_queue_mapping(skb);
+}
+#endif
+
 struct dpa_fq *dpa_fq_alloc(struct device *dev,
const struct fqid_cell *fqids,
struct list_head *list,
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h
index bd88dda..4581bfc 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h
@@ -88,6 +88,10 @@ struct dpa_bp *dpa_bpid2pool(int bpid);
 void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp);
 bool dpa_bpid2pool_use(int bpid);
 void dpa_bp_drain(struct dpa_bp *bp);
+#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
+u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb,
+void *accel_priv, select_queue_fallback_t fallback);
+#endif
 struct dpa_fq *dpa_fq_alloc(struct device *dev,
const struct fqid_cell *fqids,
struct list_head *list,
-- 
1.7.11.7

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[v2 6/9] dpaa_eth: add sysfs exports

2015-08-05 Thread Madalin Bucur
Export Frame Queue and Buffer Pool IDs through sysfs.

Signed-off-by: Madalin Bucur madalin.bu...@freescale.com
---
 drivers/net/ethernet/freescale/dpaa/Makefile   |   2 +-
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c |   2 +
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h |   3 +
 .../net/ethernet/freescale/dpaa/dpaa_eth_common.c  |   2 +
 .../net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c   | 167 +
 5 files changed, 175 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c

diff --git a/drivers/net/ethernet/freescale/dpaa/Makefile 
b/drivers/net/ethernet/freescale/dpaa/Makefile
index e137146..3a276d5 100644
--- a/drivers/net/ethernet/freescale/dpaa/Makefile
+++ b/drivers/net/ethernet/freescale/dpaa/Makefile
@@ -10,4 +10,4 @@ ccflags-y += -I$(FMAN)/flib
 
 obj-$(CONFIG_FSL_DPAA_ETH) += fsl_dpa.o
 
-fsl_dpa-objs += dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o dpaa_ethtool.o
+fsl_dpa-objs += dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o dpaa_ethtool.o 
dpaa_eth_sysfs.o
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 264945c..a1183f4 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -739,6 +739,8 @@ dpaa_eth_priv_probe(struct platform_device *pdev)
if (err  0)
goto netdev_init_failed;
 
+   dpaa_eth_sysfs_init(net_dev-dev);
+
pr_info(Probed interface %s\n, net_dev-name);
 
return 0;
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
index 55c1106..2a0ecf3 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
@@ -344,6 +344,9 @@ static inline u16 dpa_get_headroom(struct 
dpa_buffer_layout_s *bl)
return bl-data_align ? ALIGN(headroom, bl-data_align) : headroom;
 }
 
+void dpaa_eth_sysfs_remove(struct device *dev);
+void dpaa_eth_sysfs_init(struct device *dev);
+
 void dpa_private_napi_del(struct net_device *net_dev);
 
 static inline void clear_fd(struct qm_fd *fd)
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c
index ca6831a..1e43fe5 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c
@@ -279,6 +279,8 @@ int dpa_remove(struct platform_device *pdev)
 
priv = netdev_priv(net_dev);
 
+   dpaa_eth_sysfs_remove(dev);
+
dev_set_drvdata(dev, NULL);
unregister_netdev(net_dev);
 
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c
new file mode 100644
index 000..a6c71b1
--- /dev/null
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c
@@ -0,0 +1,167 @@
+/* Copyright 2008-2015 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ *  names of its contributors may be used to endorse or promote products
+ *  derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License (GPL) as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include linux/init.h
+#include linux/module.h
+#include linux/kthread.h
+#include linux/io.h
+#include linux/of_net.h
+#include dpaa_eth.h
+#include mac.h
+
+static ssize_t dpaa_eth_show_addr(struct device *dev,
+ 

[v2 8/9] dpaa_eth: add debugfs entries

2015-08-05 Thread Madalin Bucur
Export per CPU counters through debugfs.

Signed-off-by: Madalin Bucur madalin.bu...@freescale.com
---
 drivers/net/ethernet/freescale/dpaa/Kconfig|   7 +
 drivers/net/ethernet/freescale/dpaa/Makefile   |   3 +
 drivers/net/ethernet/freescale/dpaa/dpaa_debugfs.c | 272 +
 drivers/net/ethernet/freescale/dpaa/dpaa_debugfs.h |  43 
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c |  11 +
 .../net/ethernet/freescale/dpaa/dpaa_eth_common.c  |  17 ++
 6 files changed, 353 insertions(+)
 create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_debugfs.c
 create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_debugfs.h

diff --git a/drivers/net/ethernet/freescale/dpaa/Kconfig 
b/drivers/net/ethernet/freescale/dpaa/Kconfig
index 6147403..98c6328 100644
--- a/drivers/net/ethernet/freescale/dpaa/Kconfig
+++ b/drivers/net/ethernet/freescale/dpaa/Kconfig
@@ -53,4 +53,11 @@ config FSL_DPAA_INGRESS_CS_THRESHOLD
  The size in bytes of the ingress tail-drop threshold on FMan ports.
  Traffic piling up above this value will be rejected by QMan and 
discarded by FMan.
 
+config FSL_DPAA_ETH_DEBUGFS
+   bool DPAA Ethernet debugfs interface
+   depends on DEBUG_FS
+   default y
+   ---help---
+ This option compiles debugfs code for the DPAA Ethernet driver.
+
 endif # FSL_DPAA_ETH
diff --git a/drivers/net/ethernet/freescale/dpaa/Makefile 
b/drivers/net/ethernet/freescale/dpaa/Makefile
index 3a276d5..3427de4 100644
--- a/drivers/net/ethernet/freescale/dpaa/Makefile
+++ b/drivers/net/ethernet/freescale/dpaa/Makefile
@@ -11,3 +11,6 @@ ccflags-y += -I$(FMAN)/flib
 obj-$(CONFIG_FSL_DPAA_ETH) += fsl_dpa.o
 
 fsl_dpa-objs += dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o dpaa_ethtool.o 
dpaa_eth_sysfs.o
+ifeq ($(CONFIG_FSL_DPAA_ETH_DEBUGFS),y)
+fsl_dpa-objs += dpaa_debugfs.o
+endif
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_debugfs.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_debugfs.c
new file mode 100644
index 000..bd426f0
--- /dev/null
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_debugfs.c
@@ -0,0 +1,272 @@
+/* Copyright 2008 - 2015 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ *  names of its contributors may be used to endorse or promote products
+ *  derived from this software without specific prior written permission.
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License (GPL) as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME :  fmt
+
+#include linux/module.h
+#include soc/fsl/qman.h
+#include linux/debugfs.h
+#include asm/debug.h
+#include dpaa_debugfs.h
+#include dpaa_eth.h
+
+#define DPA_DEBUGFS_DESCRIPTION FSL DPAA Ethernet debugfs entries
+#define DPA_ETH_DEBUGFS_ROOT fsl_dpa
+
+static int dpa_debugfs_open(struct inode *inode, struct file *file);
+
+static struct dentry *dpa_debugfs_root;
+static const struct file_operations dpa_debugfs_fops = {
+   .open   = dpa_debugfs_open,
+   .read   = seq_read,
+   .llseek = seq_lseek,
+   .release= single_release,
+};
+
+static int dpa_debugfs_show(struct seq_file *file, void *offset)
+{
+   int i;
+   struct dpa_priv_s *priv;
+   struct dpa_percpu_priv_s *percpu_priv, total;
+   struct dpa_bp *dpa_bp;
+   unsigned int dpa_bp_count = 0;
+   unsigned int count_total = 0;
+   struct qm_mcr_querycgr query_cgr;
+
+   BUG_ON(!offset);
+
+   priv = netdev_priv((struct net_device *)file-private);
+
+   

[v2 5/9] dpaa_eth: add ethtool functionality

2015-08-05 Thread Madalin Bucur
Add support for basic ethtool operations.

Signed-off-by: Madalin Bucur madalin.bu...@freescale.com
---
 drivers/net/ethernet/freescale/dpaa/Makefile   |   2 +-
 .../net/ethernet/freescale/dpaa/dpaa_eth_common.c  |   2 +
 .../net/ethernet/freescale/dpaa/dpaa_eth_common.h  |   3 +
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 230 +
 4 files changed, 236 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c

diff --git a/drivers/net/ethernet/freescale/dpaa/Makefile 
b/drivers/net/ethernet/freescale/dpaa/Makefile
index cf126dd..e137146 100644
--- a/drivers/net/ethernet/freescale/dpaa/Makefile
+++ b/drivers/net/ethernet/freescale/dpaa/Makefile
@@ -10,4 +10,4 @@ ccflags-y += -I$(FMAN)/flib
 
 obj-$(CONFIG_FSL_DPAA_ETH) += fsl_dpa.o
 
-fsl_dpa-objs += dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o
+fsl_dpa-objs += dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o dpaa_ethtool.o
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c
index 1258683..ca6831a 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c
@@ -81,6 +81,8 @@ int dpa_netdev_init(struct net_device *net_dev,
memcpy(net_dev-perm_addr, mac_addr, net_dev-addr_len);
memcpy(net_dev-dev_addr, mac_addr, net_dev-addr_len);
 
+   net_dev-ethtool_ops = dpa_ethtool_ops;
+
net_dev-needed_headroom = priv-tx_headroom;
net_dev-watchdog_timeo = msecs_to_jiffies(tx_timeout);
 
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h
index 4581bfc..a940561 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h
@@ -58,6 +58,9 @@
 /* used in napi related functions */
 extern u16 qman_portal_max;
 
+/* from dpa_ethtool.c */
+extern const struct ethtool_ops dpa_ethtool_ops;
+
 int dpa_netdev_init(struct net_device *net_dev,
const u8 *mac_addr,
u16 tx_timeout);
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
new file mode 100644
index 000..069fcf1
--- /dev/null
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
@@ -0,0 +1,230 @@
+/* Copyright 2008-2015 Freescale Semiconductor, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ *  names of its contributors may be used to endorse or promote products
+ *  derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License (GPL) as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME :  fmt
+
+#include linux/string.h
+
+#include dpaa_eth.h
+#include mac.h
+#include dpaa_eth_common.h
+
+static int dpa_get_settings(struct net_device *net_dev,
+   struct ethtool_cmd *et_cmd)
+{
+   int err;
+   struct dpa_priv_s *priv;
+
+   priv = netdev_priv(net_dev);
+
+   if (!priv-mac_dev-phy_dev) {
+   netdev_dbg(net_dev, phy device not initialized\n);
+   return 0;
+   }
+
+   err = phy_ethtool_gset(priv-mac_dev-phy_dev, et_cmd);
+
+   return err;
+}
+
+static int dpa_set_settings(struct net_device *net_dev,
+   struct ethtool_cmd *et_cmd)
+{
+   int err;
+   struct dpa_priv_s *priv;
+
+   priv = 

[v2 7/9] dpaa_eth: add debugfs counters

2015-08-05 Thread Madalin Bucur
Add a series of counters to be exported through debugfs:
- add detailed counters for reception errors;
- add detailed counters for QMan enqueue reject events;
- count the number of fragmented skbs received from the stack;
- count all frames received on the Tx confirmation path;
- add congestion group statistics;
- count the number of interrupts for each CPU.

Signed-off-by: Madalin Bucur madalin.bu...@freescale.com
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 12 +++
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h | 34 ++
 .../net/ethernet/freescale/dpaa/dpaa_eth_common.c  | 40 --
 .../net/ethernet/freescale/dpaa/dpaa_eth_common.h  |  2 ++
 drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c  |  1 +
 5 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index a1183f4..008562b 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -98,6 +98,15 @@ static void _dpa_rx_error(struct net_device *net_dev,
 
percpu_priv-stats.rx_errors++;
 
+   if (fd-status  FM_PORT_FRM_ERR_DMA)
+   percpu_priv-rx_errors.dme++;
+   if (fd-status  FM_PORT_FRM_ERR_PHYSICAL)
+   percpu_priv-rx_errors.fpe++;
+   if (fd-status  FM_PORT_FRM_ERR_SIZE)
+   percpu_priv-rx_errors.fse++;
+   if (fd-status  FM_PORT_FRM_ERR_PRS_HDR_ERR)
+   percpu_priv-rx_errors.phe++;
+
dpa_fd_release(net_dev, fd);
 }
 
@@ -161,6 +170,8 @@ static void _dpa_tx_conf(struct net_device *net_dev,
percpu_priv-stats.tx_errors++;
}
 
+   percpu_priv-tx_confirm++;
+
skb = _dpa_cleanup_tx_fd(priv, fd);
 
dev_kfree_skb(skb);
@@ -296,6 +307,7 @@ static void priv_ern(struct qman_portal *portal,
 
percpu_priv-stats.tx_dropped++;
percpu_priv-stats.tx_fifo_errors++;
+   count_ern(percpu_priv, msg);
 
/* If we intended this buffer to go into the pool
 * when the FM was done, we need to put it in
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
index 2a0ecf3..c66140e 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
@@ -194,6 +194,25 @@ struct dpa_bp {
void (*free_buf_cb)(void *addr);
 };
 
+struct dpa_rx_errors {
+   u64 dme;/* DMA Error */
+   u64 fpe;/* Frame Physical Error */
+   u64 fse;/* Frame Size Error */
+   u64 phe;/* Header Error */
+};
+
+/* Counters for QMan ERN frames - one counter per rejection code */
+struct dpa_ern_cnt {
+   u64 cg_tdrop;   /* Congestion group taildrop */
+   u64 wred;   /* WRED congestion */
+   u64 err_cond;   /* Error condition */
+   u64 early_window;   /* Order restoration, frame too early */
+   u64 late_window;/* Order restoration, frame too late */
+   u64 fq_tdrop;   /* FQ taildrop */
+   u64 fq_retired; /* FQ is retired */
+   u64 orp_zero;   /* ORP disabled */
+};
+
 struct dpa_napi_portal {
struct napi_struct napi;
struct qman_portal *p;
@@ -202,7 +221,13 @@ struct dpa_napi_portal {
 struct dpa_percpu_priv_s {
struct net_device *net_dev;
struct dpa_napi_portal *np;
+   u64 in_interrupt;
+   u64 tx_confirm;
+   /* fragmented (non-linear) skbuffs received from the stack */
+   u64 tx_frag_skbuffs;
struct rtnl_link_stats64 stats;
+   struct dpa_rx_errors rx_errors;
+   struct dpa_ern_cnt ern_cnt;
 };
 
 struct dpa_priv_s {
@@ -233,6 +258,14 @@ struct dpa_priv_s {
 * (and the same) congestion group.
 */
struct qman_cgr cgr;
+   /* If congested, when it began. Used for performance stats. */
+   u32 congestion_start_jiffies;
+   /* Number of jiffies the Tx port was congested. */
+   u32 congested_jiffies;
+   /* Counter for the number of times the CGR
+* entered congestion state
+*/
+   u32 cgr_congested_count;
} cgr_data;
/* Use a per-port CGR for ingress traffic. */
bool use_ingress_cgr;
@@ -294,6 +327,7 @@ static inline int dpaa_eth_napi_schedule(struct 
dpa_percpu_priv_s *percpu_priv,
 
np-p = portal;
napi_schedule(np-napi);
+   percpu_priv-in_interrupt++;
return 1;
}
}
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c
index 1e43fe5..459132b 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c
+++ 

[v2 9/9] dpaa_eth: add trace points

2015-08-05 Thread Madalin Bucur
Add trace points on the hot processing path.

Signed-off-by: Ruxandra Ioana Radulescu ruxandra.radule...@freescale.com
---
 drivers/net/ethernet/freescale/dpaa/Makefile   |   1 +
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c |  12 ++
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h |   4 +
 .../net/ethernet/freescale/dpaa/dpaa_eth_trace.h   | 141 +
 4 files changed, 158 insertions(+)
 create mode 100644 drivers/net/ethernet/freescale/dpaa/dpaa_eth_trace.h

diff --git a/drivers/net/ethernet/freescale/dpaa/Makefile 
b/drivers/net/ethernet/freescale/dpaa/Makefile
index 3427de4..bf7248a 100644
--- a/drivers/net/ethernet/freescale/dpaa/Makefile
+++ b/drivers/net/ethernet/freescale/dpaa/Makefile
@@ -11,6 +11,7 @@ ccflags-y += -I$(FMAN)/flib
 obj-$(CONFIG_FSL_DPAA_ETH) += fsl_dpa.o
 
 fsl_dpa-objs += dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o dpaa_ethtool.o 
dpaa_eth_sysfs.o
+CFLAGS_dpaa_eth.o := -I$(src)
 ifeq ($(CONFIG_FSL_DPAA_ETH_DEBUGFS),y)
 fsl_dpa-objs += dpaa_debugfs.o
 endif
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index ea25bf1..7f2413b 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -61,6 +61,12 @@
 #include dpaa_debugfs.h
 #endif /* CONFIG_FSL_DPAA_ETH_DEBUGFS */
 
+/* CREATE_TRACE_POINTS only needs to be defined once. Other dpa files
+ * using trace events only need to #include trace/events/sched.h
+ */
+#define CREATE_TRACE_POINTS
+#include dpaa_eth_trace.h
+
 #define DPA_NAPI_WEIGHT64
 
 /* Valid checksum indication */
@@ -226,6 +232,9 @@ priv_rx_default_dqrr(struct qman_portal *portal,
priv = netdev_priv(net_dev);
dpa_bp = priv-dpa_bp;
 
+   /* Trace the Rx fd */
+   trace_dpa_rx_fd(net_dev, fq, dq-fd);
+
/* IRQ handler, non-migratable; safe to use raw_cpu_ptr here */
percpu_priv = raw_cpu_ptr(priv-percpu_priv);
count_ptr = raw_cpu_ptr(dpa_bp-percpu_count);
@@ -282,6 +291,9 @@ priv_tx_conf_default_dqrr(struct qman_portal *portal,
net_dev = ((struct dpa_fq *)fq)-net_dev;
priv = netdev_priv(net_dev);
 
+   /* Trace the fd */
+   trace_dpa_tx_conf_fd(net_dev, fq, dq-fd);
+
/* Non-migratable context, safe to use raw_cpu_ptr */
percpu_priv = raw_cpu_ptr(priv-percpu_priv);
 
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
index c66140e..4ac917a 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
@@ -36,6 +36,7 @@
 
 #include fm_ext.h
 #include mac.h
+#include dpaa_eth_trace.h
 
 extern int dpa_rx_extra_headroom;
 extern int dpa_max_frm;
@@ -417,6 +418,9 @@ static inline int dpa_xmit(struct dpa_priv_s *priv,
_dpa_get_tx_conf_queue(priv, egress_fq)
);
 
+   /* Trace this Tx fd */
+   trace_dpa_tx_fd(priv-net_dev, egress_fq, fd);
+
for (i = 0; i  10; i++) {
err = qman_enqueue(egress_fq, fd, 0);
if (err != -EBUSY)
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_trace.h 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_trace.h
new file mode 100644
index 000..3b67477
--- /dev/null
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_trace.h
@@ -0,0 +1,141 @@
+/* Copyright 2013-2015 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ *  names of its contributors may be used to endorse or promote products
+ *  derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License (GPL) as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 

Re: [PATCH v2 4/8] xen: Use the correctly the Xen memory terminologies

2015-08-05 Thread Dmitry Torokhov
On Wed, Aug 05, 2015 at 11:08:55AM +0100, Stefano Stabellini wrote:
 On Tue, 4 Aug 2015, Julien Grall wrote:
  Based on include/xen/mm.h [1], Linux is mistakenly using MFN when GFN
  is meant, I suspect this is because the first support for Xen was for
  PV. This resulted in some misimplementation of helpers on ARM and
  confused developers about the expected behavior.
  
  For instance, with pfn_to_mfn, we expect to get an MFN based on the name.
  Although, if we look at the implementation on x86, it's returning a GFN.
  
  For clarity and avoid new confusion, replace any reference to mfn with
  gfn in any helpers used by PV drivers. The x86 code will still keep some
  reference of pfn_to_mfn but exclusively for PV (a BUG_ON has been added
  to ensure this). No changes as been made in the hypercall field, even
  though they may be invalid, in order to keep the same as the defintion
  in xen repo.
  
  Take also the opportunity to simplify simple construction such
  as pfn_to_mfn(page_to_pfn(page)) into page_to_gfn. More complex clean up
  will come in follow-up patches.
  
  [1] 
  http://xenbits.xen.org/gitweb/?p=xen.git;a=commitdiff;h=e758ed14f390342513405dd766e874934573e6cb
  
  Signed-off-by: Julien Grall julien.gr...@citrix.com
  Cc: Stefano Stabellini stefano.stabell...@eu.citrix.com
  Cc: Russell King li...@arm.linux.org.uk
  Cc: Konrad Rzeszutek Wilk konrad.w...@oracle.com
  Cc: Boris Ostrovsky boris.ostrov...@oracle.com
  Cc: David Vrabel david.vra...@citrix.com
  Cc: Thomas Gleixner t...@linutronix.de
  Cc: Ingo Molnar mi...@redhat.com
  Cc: H. Peter Anvin h...@zytor.com
  Cc: x...@kernel.org
  Cc: Roger Pau Monné roger@citrix.com
  Cc: Dmitry Torokhov dmitry.torok...@gmail.com
  Cc: Ian Campbell ian.campb...@citrix.com
  Cc: Wei Liu wei.l...@citrix.com
  Cc: Juergen Gross jgr...@suse.com
  Cc: James E.J. Bottomley jbottom...@odin.com
  Cc: Greg Kroah-Hartman gre...@linuxfoundation.org
  Cc: Jiri Slaby jsl...@suse.com
  Cc: Jean-Christophe Plagniol-Villard plagn...@jcrosoft.com
  Cc: Tomi Valkeinen tomi.valkei...@ti.com
  Cc: linux-in...@vger.kernel.org
  Cc: net...@vger.kernel.org
  Cc: linux-s...@vger.kernel.org
  Cc: linuxppc-dev@lists.ozlabs.org
  Cc: linux-fb...@vger.kernel.org
  Cc: linux-arm-ker...@lists.infradead.org
 
 Aside from the x86 bits:
 
 Reviewed-by: Stefano Stabellini stefano.stabell...@eu.citrix.com

Not really important, but just in case anyone waits for my ack on input
bits:

Acked-by: Dmitry Torokhov dmitry.torok...@gmail.com

Thanks.

-- 
Dmitry
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v2 4/8] xen: Use the correctly the Xen memory terminologies

2015-08-05 Thread Wei Liu
On Tue, Aug 04, 2015 at 07:12:48PM +0100, Julien Grall wrote:
[...]
 diff --git a/drivers/net/xen-netback/netback.c 
 b/drivers/net/xen-netback/netback.c
 index 7d50711..3b7b7c3 100644
 --- a/drivers/net/xen-netback/netback.c
 +++ b/drivers/net/xen-netback/netback.c
 @@ -314,7 +314,7 @@ static void xenvif_gop_frag_copy(struct xenvif_queue 
 *queue, struct sk_buff *skb
   } else {
   copy_gop-source.domid = DOMID_SELF;
   copy_gop-source.u.gmfn =
 - virt_to_mfn(page_address(page));
 + virt_to_gfn(page_address(page));
   }
   copy_gop-source.offset = offset;
  
 @@ -1284,7 +1284,7 @@ static void xenvif_tx_build_gops(struct xenvif_queue 
 *queue,
   queue-tx_copy_ops[*copy_ops].source.offset = txreq.offset;
  
   queue-tx_copy_ops[*copy_ops].dest.u.gmfn =
 - virt_to_mfn(skb-data);
 + virt_to_gfn(skb-data);
   queue-tx_copy_ops[*copy_ops].dest.domid = DOMID_SELF;
   queue-tx_copy_ops[*copy_ops].dest.offset =
   offset_in_page(skb-data);

Acked-by: Wei Liu wei.l...@citrix.com
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH 1/5] powerpc/pseries: extract of_helpers module

2015-08-05 Thread Segher Boessenkool
On Wed, Aug 05, 2015 at 12:32:55PM +0300, Andy Shevchenko wrote:
  If path doesn't contain any slash this will do interesting things;
  you might want to fix that too while you're at it :-)
 
 No problem, though it is in the original code. I would do as a separate
 patch on top of the series. Will be okay for you?

Of course -- you're fixing other problems here as well (memory leak
or what was it), that's why I asked.


Segher
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH V2] QorIQ/TMU: add thermal management support based on TMU

2015-08-05 Thread Eduardo Valentin
On Thu, Jul 30, 2015 at 08:13:09AM +, Hongtao Jia wrote:
 - Any specific reason why not using OF thermal?
 - No, actually.
 
 I'd like to use OF thermal after some clarification.
 
 Regarding to cooling-maps. For some cases there should be more than one cpus
 as cooling device and they are independent.
 1. Let's say 4. So we need to provide 4 maps like map0-map3. Right?

That would depend on the amount of sensors you have. Do you have one
sensor per cpu? if the answer is yes, then you probably want to have
four different map entries, yes, but one on each thermal zone of each
cpu temperature sensor. if the answer is no, then you would need to have
all the maps in the same thermal zone.

 2. cooling-max-level may vary depend on switch settings or firmware. Is that
OK if I do not provide cooling-min-level and cooling-max-level 
 property?

That is already achievable by using the cooling-device property of a
cooling map.

Please have a look in the example section of the
Documentation/devicetree/bindings/thermal/thermal.txt

Let me know if you need further clarification.


BR,

Eduardo Valentin


 Thanks.
 -Hongtao
 
 
  -Original Message-
  From: Eduardo Valentin [mailto:edubez...@gmail.com]
  Sent: Thursday, July 30, 2015 2:56 PM
  To: Jia Hongtao-B38951
  Cc: linux...@vger.kernel.org; linuxppc-dev@lists.ozlabs.org; Wood Scott-
  B07421
  Subject: Re: [PATCH V2] QorIQ/TMU: add thermal management support based
  on TMU
  
  On Wed, Jul 29, 2015 at 02:19:39PM +0800, Jia Hongtao wrote:
   It supports one critical trip point and one passive trip point.
   The cpufreq is used as the cooling device to throttle CPUs when the
   passive trip is crossed.
  
   Signed-off-by: Jia Hongtao hongtao@freescale.com
   ---
   This patch based on:
   http://patchwork.ozlabs.org/patch/482987/
  
   Changes for V2:
   * Add tmu-range parse.
   * Use default trend hook.
   * Using latest thermal_zone_bind_cooling_device API.
   * Add calibration check during initialization.
   * Disable/enalbe device when suspend/resume.
  
drivers/thermal/Kconfig |  11 ++
drivers/thermal/Makefile|   1 +
drivers/thermal/qoriq_thermal.c | 406
   
3 files changed, 418 insertions(+)
create mode 100644 drivers/thermal/qoriq_thermal.c
  
   diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index
   118938e..a200745 100644
   --- a/drivers/thermal/Kconfig
   +++ b/drivers/thermal/Kconfig
   @@ -180,6 +180,17 @@ config IMX_THERMAL
   cpufreq is used as the cooling device to throttle CPUs when the
   passive trip is crossed.
  
   +config QORIQ_THERMAL
   + tristate Freescale QorIQ Thermal Monitoring Unit
   + depends on CPU_THERMAL
   + depends on OF
   + default n
   + help
   +   Enable thermal management based on Freescale QorIQ Thermal
  Monitoring
   +   Unit (TMU). It supports one critical trip point and one passive
  trip
   +   point. The cpufreq is used as the cooling device to throttle CPUs
  when
   +   the passive trip is crossed.
   +
config SPEAR_THERMAL
 bool SPEAr thermal sensor driver
 depends on PLAT_SPEAR
   diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index
   535dfee..8c25859 100644
   --- a/drivers/thermal/Makefile
   +++ b/drivers/thermal/Makefile
   @@ -33,6 +33,7 @@ obj-$(CONFIG_DOVE_THERMAL)  += dove_thermal.o
obj-$(CONFIG_DB8500_THERMAL) += db8500_thermal.o
obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o
obj-$(CONFIG_IMX_THERMAL)+= imx_thermal.o
   +obj-$(CONFIG_QORIQ_THERMAL)  += qoriq_thermal.o
obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o
obj-$(CONFIG_INTEL_POWERCLAMP)   += intel_powerclamp.o
obj-$(CONFIG_X86_PKG_TEMP_THERMAL)   += x86_pkg_temp_thermal.o
   diff --git a/drivers/thermal/qoriq_thermal.c
   b/drivers/thermal/qoriq_thermal.c new file mode 100644 index
   000..0694f42
   --- /dev/null
   +++ b/drivers/thermal/qoriq_thermal.c
   @@ -0,0 +1,406 @@
   +/*
   + * Copyright 2015 Freescale Semiconductor, Inc.
   + *
   + * This program is free software; you can redistribute it and/or
   +modify it
   + * under the terms and conditions of the GNU General Public License,
   + * version 2, as published by the Free Software Foundation.
   + *
   + * This program is distributed in the hope it will be useful, but
   +WITHOUT
   + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   +or
   + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
   +License for
   + * more details.
   + *
   + */
   +
   +/*
   + * Based on Freescale QorIQ Thermal Monitoring Unit (TMU)  */
   +#include linux/cpufreq.h #include linux/cpu_cooling.h #include
   +linux/module.h #include linux/platform_device.h #include
   +linux/err.h #include linux/io.h #include linux/of.h #include
   +linux/of_address.h #include linux/thermal.h
   +
   +#define SITES_MAX16
   +
   

Re: [PATCH v2 2/2] powerpc32: optimise csum_partial() loop

2015-08-05 Thread Scott Wood
On Wed, 2015-08-05 at 19:30 -0500, Segher Boessenkool wrote:
 On Wed, Aug 05, 2015 at 03:29:35PM +0200, Christophe Leroy wrote:
  On the 8xx, load latency is 2 cycles and taking branches also takes
  2 cycles. So let's unroll the loop.
 
 This is not true for most other 32-bit PowerPC; this patch makes
 performance worse on e.g. 6xx/7xx/7xxx.  Let's not!

Chips with a load latency greater than 2 cycles should also benefit from the 
unrolling.  Have you benchmarked this somewhere and seen it reduce 
performance?  Do you know of any 32-bit PPC chips with a load latency less 
than 2 cycles?

-Scott

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v6 10/42] powerpc/powernv: pnv_ioda_setup_dma() configure one PE only

2015-08-05 Thread Gavin Shan
The original implementation of pnv_ioda_setup_dma() iterates the
list of PEs and configures the DMA32 space for them one by one.
The function was designed to be called during PHB fixup time.
When configuring PE's DMA32 space in pcibios_setup_bridge(), in
order to support PCI hotplug, we have to have the function PE
oriented.

This renames pnv_ioda_setup_dma() to pnv_ioda1_setup_dma() and
adds one more argument struct pnv_ioda_pe *pe to it. The caller,
pnv_pci_ioda_setup_DMA(), gets PE from the list and passes to it
or pnv_pci_ioda2_setup_dma_pe(). The patch shouldn't cause behavioral
changes.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/pci-ioda.c | 75 +++
 1 file changed, 36 insertions(+), 39 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 8456f37..cd22002 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -2443,52 +2443,29 @@ static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb 
*phb,
pnv_ioda_setup_bus_dma(pe, pe-pbus);
 }
 
-static void pnv_ioda_setup_dma(struct pnv_phb *phb)
+static unsigned int pnv_ioda1_setup_dma(struct pnv_phb *phb,
+   struct pnv_ioda_pe *pe,
+   unsigned int base)
 {
struct pci_controller *hose = phb-hose;
-   struct pnv_ioda_pe *pe;
-   unsigned int dma_weight;
+   unsigned int dma_weight, segs;
 
/* Calculate the PHB's DMA weight */
dma_weight = pnv_ioda_phb_dma_weight(phb);
pr_info(PCI%04x has %ld DMA32 segments, total weight %d\n,
hose-global_number, phb-ioda.dma32_segcount, dma_weight);
 
-   pnv_pci_ioda_setup_opal_tce_kill(phb);
-
-   /* Walk our PE list and configure their DMA segments, hand them
-* out one base segment plus any residual segments based on
-* weight
-*/
-   list_for_each_entry(pe, phb-ioda.pe_dma_list, dma_link) {
-   if (!pe-dma32_weight)
-   continue;
-
-   /*
-* For IODA2 compliant PHB3, we needn't care about the weight.
-* The all available 32-bits DMA space will be assigned to
-* the specific PE.
-*/
-   if (phb-type == PNV_PHB_IODA1) {
-   unsigned int segs, base = 0;
-
-   if (pe-dma32_weight 
-   dma_weight / phb-ioda.dma32_segcount)
-   segs = 1;
-   else
-   segs = (pe-dma32_weight *
-   phb-ioda.dma32_segcount) / dma_weight;
-
-   pe_info(pe, DMA32 weight %d, assigned %d segments\n,
-   pe-dma32_weight, segs);
-   pnv_pci_ioda_setup_dma_pe(phb, pe, base, segs);
+   if (pe-dma32_weight 
+   dma_weight / phb-ioda.dma32_segcount)
+   segs = 1;
+   else
+   segs = (pe-dma32_weight *
+   phb-ioda.dma32_segcount) / dma_weight;
+   pe_info(pe, DMA weight %d, assigned %d segments\n,
+   pe-dma32_weight, segs);
+   pnv_pci_ioda_setup_dma_pe(phb, pe, base, segs);
 
-   base += segs;
-   } else {
-   pe_info(pe, Assign DMA32 space\n);
-   pnv_pci_ioda2_setup_dma_pe(phb, pe);
-   }
-   }
+   return segs;
 }
 
 #ifdef CONFIG_PCI_MSI
@@ -2955,12 +2932,32 @@ static void pnv_pci_ioda_setup_DMA(void)
 {
struct pci_controller *hose, *tmp;
struct pnv_phb *phb;
+   struct pnv_ioda_pe *pe;
+   unsigned int base;
 
list_for_each_entry_safe(hose, tmp, hose_list, list_node) {
-   pnv_ioda_setup_dma(hose-private_data);
+   phb = hose-private_data;
+   pnv_pci_ioda_setup_opal_tce_kill(phb);
+
+   base = 0;
+   list_for_each_entry(pe, phb-ioda.pe_dma_list, dma_link) {
+   if (!pe-dma32_weight)
+   continue;
+
+   switch (phb-type) {
+   case PNV_PHB_IODA1:
+   base += pnv_ioda1_setup_dma(phb, pe, base);
+   break;
+   case PNV_PHB_IODA2:
+   pnv_pci_ioda2_setup_dma_pe(phb, pe);
+   break;
+   default:
+   pr_warn(%s: No DMA for PHB type %d\n,
+   __func__, phb-type);
+   }
+   }
 
/* Mark the PHB initialization done */
-   phb = hose-private_data;
phb-initialized = 1;
}
 }
-- 
2.1.0


[PATCH v6 38/42] drivers/of: Unflatten subordinate nodes after specified level

2015-08-05 Thread Gavin Shan
unflatten_dt_node() is called recursively to unflatten FDT nodes
with the assumption that FDT blob has only one root node, which
isn't true when the FDT blob represents device sub-tree. This
improves the function to supporting device sub-tree that have
multiple nodes in the first level:

   * Rename original unflatten_dt_node() to __unflatten_dt_node().
   * Wrapper unflatten_dt_node() calls __unflatten_dt_node() with
 adjusted current node depth to 1 to avoid underflow.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 drivers/of/fdt.c | 53 -
 1 file changed, 40 insertions(+), 13 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 0749656..a18a2ce 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -161,7 +161,7 @@ static void *unflatten_dt_alloc(void **mem, unsigned long 
size,
 }
 
 /**
- * unflatten_dt_node - Alloc and populate a device_node from the flat tree
+ * __unflatten_dt_node - Alloc and populate a device_node from the flat tree
  * @blob: The parent device tree blob
  * @mem: Memory chunk to use for allocating device nodes and properties
  * @poffset: pointer to node in flat tree
@@ -171,20 +171,20 @@ static void *unflatten_dt_alloc(void **mem, unsigned long 
size,
  * @dryrun: If true, do not allocate device nodes but still calculate needed
  * memory size
  */
-static void * unflatten_dt_node(const void *blob,
+static void *__unflatten_dt_node(const void *blob,
void *mem,
int *poffset,
struct device_node *dad,
struct device_node **nodepp,
unsigned long fpsize,
-   bool dryrun)
+   bool dryrun,
+   int *depth)
 {
const __be32 *p;
struct device_node *np;
struct property *pp, **prev_pp = NULL;
const char *pathp;
unsigned int l, allocl;
-   static int depth = 0;
int old_depth;
int offset;
int has_name = 0;
@@ -337,13 +337,25 @@ static void * unflatten_dt_node(const void *blob,
np-type = NULL;
}
 
-   old_depth = depth;
-   *poffset = fdt_next_node(blob, *poffset, depth);
-   if (depth  0)
-   depth = 0;
-   while (*poffset  0  depth  old_depth)
-   mem = unflatten_dt_node(blob, mem, poffset, np, NULL,
-   fpsize, dryrun);
+   /* Multiple nodes might be in the first depth level if
+* the device tree is sub-tree. All nodes in current
+* or deeper depth are unflattened after it returns.
+*/
+   old_depth = *depth;
+   *poffset = fdt_next_node(blob, *poffset, depth);
+   while (*poffset  0) {
+   if (*depth  old_depth)
+   break;
+
+   if (*depth == old_depth)
+   mem = __unflatten_dt_node(blob, mem, poffset,
+ dad, NULL, fpsize,
+ dryrun, depth);
+   else if (*depth  old_depth)
+   mem = __unflatten_dt_node(blob, mem, poffset,
+ np, NULL, fpsize,
+ dryrun, depth);
+   }
 
if (*poffset  0  *poffset != -FDT_ERR_NOTFOUND)
pr_err(unflatten: error %d processing FDT\n, *poffset);
@@ -369,6 +381,20 @@ static void * unflatten_dt_node(const void *blob,
return mem;
 }
 
+static void *unflatten_dt_node(const void *blob,
+  void *mem,
+  int *poffset,
+  struct device_node *dad,
+  struct device_node **nodepp,
+  bool dryrun)
+{
+   int depth = 1;
+
+   return __unflatten_dt_node(blob, mem, poffset,
+  dad, nodepp, 0,
+  dryrun, depth);
+}
+
 /**
  * __unflatten_device_tree - create tree of device_nodes from flat blob
  *
@@ -408,7 +434,8 @@ static void __unflatten_device_tree(const void *blob,
 
/* First pass, scan for size */
start = 0;
-   size = (unsigned long)unflatten_dt_node(blob, NULL, start, NULL, NULL, 
0, true);
+   size = (unsigned long)unflatten_dt_node(blob, NULL, start,
+   NULL, NULL, true);
size = ALIGN(size, 4);
 
pr_debug(  size is %lx, allocating...\n, size);
@@ -423,7 +450,7 @@ static void __unflatten_device_tree(const void *blob,
 
/* Second pass, do actual unflattening */
start = 0;
-   unflatten_dt_node(blob, mem, start, NULL, mynodes, 0, false);
+   unflatten_dt_node(blob, mem, start, NULL, mynodes, false);
if 

[PATCH v6 19/42] powerpc/powernv: Reserve PE# for root bus

2015-08-05 Thread Gavin Shan
pcibios_setup_bridge() is normally called to update PCI bridge
windows. It allocates PE for PCI buses. However it is not called
on a root bus which does not have an upstream bridge.

This reserves PE# for a root bus in advance. This will be used in
the subsequent patch to do setup.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/pci-ioda.c | 30 +-
 arch/powerpc/platforms/powernv/pci.h  |  1 +
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 1c950e8..8aa6ab8 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -236,6 +236,13 @@ static int pnv_ioda1_init_m64(struct pnv_phb *phb)
pr_warn(  Cannot strip M64 segment for reserved PE#%d\n,
phb-ioda.reserved_pe_idx);
 
+   /* Strip off the M64 segment corresponding to the PE#
+* for PCI root bus, which is last supported PE# or
+* (reserved PE# - 1).
+*/
+   if (phb-ioda.root_pe_idx != IODA_INVALID_PE)
+   r-end -= phb-ioda.m64_segsize;
+
return 0;
 
 fail:
@@ -293,6 +300,13 @@ static int pnv_ioda2_init_m64(struct pnv_phb *phb)
pr_warn(  Cannot strip M64 segment for reserved PE#%d\n,
phb-ioda.reserved_pe_idx);
 
+   /* Strip off the M64 segment corresponding to the PE#
+* for PCI root bus, which is last supported PE# or
+* (reserved PE# - 1).
+*/
+   if (phb-ioda.root_pe_idx != IODA_INVALID_PE)
+   r-end -= phb-ioda.m64_segsize;
+
return 0;
 
 fail:
@@ -3237,7 +3251,21 @@ static void __init pnv_pci_init_ioda_phb(struct 
device_node *np,
aux = memblock_virt_alloc(size, 0);
phb-ioda.pe_alloc = aux;
phb-ioda.pe_array = aux + pemap_off;
-   set_bit(phb-ioda.reserved_pe_idx, phb-ioda.pe_alloc);
+
+   /* Choose number of PE for root bus, which shouldn't consume
+* any M64 resource. So we avoid picking low-end PE#, which
+* is usually bound with M64 resources closely.
+*/
+   pnv_ioda_reserve_pe(phb, phb-ioda.reserved_pe_idx);
+   if (phb-ioda.reserved_pe_idx == 0) {
+   phb-ioda.root_pe_idx = phb-ioda.total_pe_num - 1;
+   pnv_ioda_reserve_pe(phb, phb-ioda.root_pe_idx);
+   } else if (phb-ioda.reserved_pe_idx == (phb-ioda.total_pe_num - 1)) {
+   phb-ioda.root_pe_idx = phb-ioda.reserved_pe_idx - 1;
+   pnv_ioda_reserve_pe(phb, phb-ioda.root_pe_idx);
+   } else {
+   phb-ioda.root_pe_idx = IODA_INVALID_PE;
+   }
 
INIT_LIST_HEAD(phb-ioda.pe_dma_list);
INIT_LIST_HEAD(phb-ioda.pe_list);
diff --git a/arch/powerpc/platforms/powernv/pci.h 
b/arch/powerpc/platforms/powernv/pci.h
index fc899cd..e93a489 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -135,6 +135,7 @@ struct pnv_phb {
struct {
/* Global bridge info */
unsigned inttotal_pe_num;
+   unsigned introot_pe_idx;
unsigned intreserved_pe_idx;
 
/* 32-bit MMIO window */
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v6 39/42] drivers/of: Allow to specify root node in of_fdt_unflatten_tree()

2015-08-05 Thread Gavin Shan
This introduces one more argument to of_fdt_unflatten_tree()
to specify the root node for the FDT blob, which is going to be
unflattened. In the result, the function can be used to unflatten
FDT blob, which represents device sub-tree in PowerNV hotplug
driver.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 drivers/of/fdt.c   | 13 -
 drivers/of/unittest.c  |  2 +-
 include/linux/of_fdt.h |  1 +
 3 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index a18a2ce..074870a 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -388,10 +388,11 @@ static void *unflatten_dt_node(const void *blob,
   struct device_node **nodepp,
   bool dryrun)
 {
+   unsigned long fpsize = dad ? strlen(of_node_full_name(dad)) : 0;
int depth = 1;
 
return __unflatten_dt_node(blob, mem, poffset,
-  dad, nodepp, 0,
+  dad, nodepp, fpsize,
   dryrun, depth);
 }
 
@@ -408,6 +409,7 @@ static void *unflatten_dt_node(const void *blob,
  * for the resulting tree
  */
 static void __unflatten_device_tree(const void *blob,
+struct device_node *dad,
 struct device_node **mynodes,
 void * (*dt_alloc)(u64 size, u64 align))
 {
@@ -435,7 +437,7 @@ static void __unflatten_device_tree(const void *blob,
/* First pass, scan for size */
start = 0;
size = (unsigned long)unflatten_dt_node(blob, NULL, start,
-   NULL, NULL, true);
+   dad, NULL, true);
size = ALIGN(size, 4);
 
pr_debug(  size is %lx, allocating...\n, size);
@@ -450,7 +452,7 @@ static void __unflatten_device_tree(const void *blob,
 
/* Second pass, do actual unflattening */
start = 0;
-   unflatten_dt_node(blob, mem, start, NULL, mynodes, false);
+   unflatten_dt_node(blob, mem, start, dad, mynodes, false);
if (be32_to_cpup(mem + size) != 0xdeadbeef)
pr_warning(End of tree marker overwritten: %08x\n,
   be32_to_cpup(mem + size));
@@ -472,9 +474,10 @@ static void *kernel_tree_alloc(u64 size, u64 align)
  * can be used.
  */
 void of_fdt_unflatten_tree(const unsigned long *blob,
+   struct device_node *dad,
struct device_node **mynodes)
 {
-   __unflatten_device_tree(blob, mynodes, kernel_tree_alloc);
+   __unflatten_device_tree(blob, dad, mynodes, kernel_tree_alloc);
 }
 EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree);
 
@@ -1125,7 +1128,7 @@ bool __init early_init_dt_scan(void *params)
  */
 void __init unflatten_device_tree(void)
 {
-   __unflatten_device_tree(initial_boot_params, of_root,
+   __unflatten_device_tree(initial_boot_params, NULL, of_root,
early_init_dt_alloc_memory_arch);
 
/* Get pointer to /chosen and /aliases nodes for use everywhere */
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
index 1801634..2270830 100644
--- a/drivers/of/unittest.c
+++ b/drivers/of/unittest.c
@@ -907,7 +907,7 @@ static int __init unittest_data_add(void)
not running tests\n, __func__);
return -ENOMEM;
}
-   of_fdt_unflatten_tree(unittest_data, unittest_data_node);
+   of_fdt_unflatten_tree(unittest_data, NULL, unittest_data_node);
if (!unittest_data_node) {
pr_warn(%s: No tree to attach; not running tests\n, __func__);
return -ENODATA;
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index df9ef38..3644960 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -38,6 +38,7 @@ extern bool of_fdt_is_big_endian(const void *blob,
 extern int of_fdt_match(const void *blob, unsigned long node,
const char *const *compat);
 extern void of_fdt_unflatten_tree(const unsigned long *blob,
+  struct device_node *dad,
   struct device_node **mynodes);
 
 /* TBD: Temporary export of fdt globals - remove when code fully merged */
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v6 32/42] powerpc/powernv: Introduce pnv_pci_poll()

2015-08-05 Thread Gavin Shan
This converts pnv_eeh_poll() to pnv_pci_poll() in order to:

   * Return linux error code other than OPAL error code.
   * The return value from last OPAL call, requested delay, is
 passed to pnv_pci_poll() and delay accordingly. Thus one
 call to opal_pci_poll() is saved.
   * More information (e.g. PCI slot power status) is returned
 if the last argument isn't NULL.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/eeh-powernv.c | 47 ++--
 arch/powerpc/platforms/powernv/pci.c | 21 +
 arch/powerpc/platforms/powernv/pci.h |  1 +
 3 files changed, 31 insertions(+), 38 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c 
b/arch/powerpc/platforms/powernv/eeh-powernv.c
index 4ae48ff..e664542 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -745,28 +745,11 @@ static int pnv_eeh_get_state(struct eeh_pe *pe, int 
*delay)
return ret;
 }
 
-static s64 pnv_eeh_poll(uint64_t id)
-{
-   s64 rc = OPAL_HARDWARE;
-
-   while (1) {
-   rc = opal_pci_poll(id, NULL);
-   if (rc = 0)
-   break;
-
-   if (system_state  SYSTEM_RUNNING)
-   udelay(1000 * rc);
-   else
-   msleep(rc);
-   }
-
-   return rc;
-}
-
 int pnv_eeh_phb_reset(struct pci_controller *hose, int option)
 {
struct pnv_phb *phb = hose-private_data;
s64 rc = OPAL_HARDWARE;
+   int ret;
 
pr_debug(%s: Reset PHB#%x, option=%d\n,
 __func__, hose-global_number, option);
@@ -781,8 +764,6 @@ int pnv_eeh_phb_reset(struct pci_controller *hose, int 
option)
rc = opal_pci_reset(phb-opal_id,
OPAL_RESET_PHB_COMPLETE,
OPAL_DEASSERT_RESET);
-   if (rc  0)
-   goto out;
 
/*
 * Poll state of the PHB until the request is done
@@ -790,24 +771,22 @@ int pnv_eeh_phb_reset(struct pci_controller *hose, int 
option)
 * reset followed by hot reset on root bus. So we also
 * need the PCI bus settlement delay.
 */
-   rc = pnv_eeh_poll(phb-opal_id);
-   if (option == EEH_RESET_DEACTIVATE) {
+   ret = pnv_pci_poll(phb-opal_id, rc, NULL);
+   if (option == EEH_RESET_DEACTIVATE  !ret) {
if (system_state  SYSTEM_RUNNING)
udelay(1000 * EEH_PE_RST_SETTLE_TIME);
else
msleep(EEH_PE_RST_SETTLE_TIME);
}
-out:
-   if (rc != OPAL_SUCCESS)
-   return -EIO;
 
-   return 0;
+   return ret;
 }
 
 static int pnv_eeh_root_reset(struct pci_controller *hose, int option)
 {
struct pnv_phb *phb = hose-private_data;
s64 rc = OPAL_HARDWARE;
+   int ret;
 
pr_debug(%s: Reset PHB#%x, option=%d\n,
 __func__, hose-global_number, option);
@@ -829,18 +808,13 @@ static int pnv_eeh_root_reset(struct pci_controller 
*hose, int option)
rc = opal_pci_reset(phb-opal_id,
OPAL_RESET_PCI_HOT,
OPAL_DEASSERT_RESET);
-   if (rc  0)
-   goto out;
 
/* Poll state of the PHB until the request is done */
-   rc = pnv_eeh_poll(phb-opal_id);
-   if (option == EEH_RESET_DEACTIVATE)
+   ret = pnv_pci_poll(phb-opal_id, rc, NULL);
+   if (option == EEH_RESET_DEACTIVATE  !ret)
msleep(EEH_PE_RST_SETTLE_TIME);
-out:
-   if (rc != OPAL_SUCCESS)
-   return -EIO;
 
-   return 0;
+   return ret;
 }
 
 static int __pnv_eeh_bridge_reset(struct pci_dev *dev, int option)
@@ -930,10 +904,7 @@ static int pnv_eeh_bridge_reset(struct pci_dev *pdev, int 
option)
phb = hose-private_data;
id |= (pdev-bus-number  24) | (pdev-devfn  16) | phb-opal_id;
rc = opal_pci_reset(id, scope, OPAL_ASSERT_RESET);
-   if (rc  0)
-   rc = pnv_eeh_poll(id);
-
-   return (rc == OPAL_SUCCESS) ? 0 : -EIO;
+   return pnv_pci_poll(id, rc, NULL);
 }
 
 static void pnv_eeh_wait_for_pending(struct pci_dn *pdn, int pos,
diff --git a/arch/powerpc/platforms/powernv/pci.c 
b/arch/powerpc/platforms/powernv/pci.c
index 6c350a2..801e3e8 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -44,6 +44,27 @@
 #define cfg_dbg(fmt...)do { } while(0)
 //#define cfg_dbg(fmt...)  printk(fmt)
 
+int pnv_pci_poll(uint64_t id, int64_t rval, uint8_t *pval)
+{
+   while (rval  0) {
+   if (system_state  SYSTEM_RUNNING)
+   udelay(1000 * rval);
+   else
+   msleep(rval);
+
+   rval = opal_pci_poll(id, pval);
+   }
+
+   /*
+* The caller expects to retrieve additional 

Re: [PATCH 3/3] PowerPC/mpc85xx: Add hotplug support on E6500 cores

2015-08-05 Thread Chenhui Zhao



On Thu, Aug 6, 2015 at 11:16 AM, Scott Wood scottw...@freescale.com 
wrote:

On Wed, 2015-08-05 at 19:08 +0800, Chenhui Zhao wrote:

 On Sat, Aug 1, 2015 at 8:22 AM, Scott Wood scottw...@freescale.com
 wrote:
  On Fri, 2015-07-31 at 17:20 +0800,  b29983@freescale.comwrote:
+ /*
+  * If both threads are offline, reset core to 
start.
+  * When core is up, Thread 0 always gets up 
first,

+  * so bind the current logical cpu with Thread 0.
+  */
+ if (hw_cpu != cpu_first_thread_sibling(hw_cpu)) {
+ int hw_cpu1, hw_cpu2;
+
+ hw_cpu1 = 
get_hard_smp_processor_id(primary);
+ hw_cpu2 = 
get_hard_smp_processor_id(primary +

   1);
+ set_hard_smp_processor_id(primary, 
hw_cpu2);

+ set_hard_smp_processor_id(primary + 1,
   hw_cpu1);
+ /* get new physical cpu id */
+ hw_cpu = get_hard_smp_processor_id(nr);
 
  NACK as discussed in http://patchwork.ozlabs.org/patch/454944/
 
  -Scott

 You said,

 There's no need for this. I have booting from a thread1, and 
having

 it
 kick its thread0, working locally without messing with the 
hwid/cpu

 mapping.

 I still have questions here. After a core reset, how can you boot
 Thread1
 of the core first. As I know, Thread0 boots up first by default.


So the issue isn't that thread1 comes up first, but that you *want* 
thread1
to come up first and it won't.  I don't think this remapping is an 
acceptable
answer, though.  Instead, if you need only thread1 to come up, start 
the
core, have thread0 start thread1, and then send thread0 into whatever 
waiting

state it would be in if thread1 had never been offlined.

-Scott


Remapping is a concise solution. what's the harm of it?
Keeping things simple is good in my opinion.

-Chenhui



___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v2 2/2] powerpc32: optimise csum_partial() loop

2015-08-05 Thread Segher Boessenkool
On Wed, Aug 05, 2015 at 09:31:41PM -0500, Scott Wood wrote:
 On Wed, 2015-08-05 at 19:30 -0500, Segher Boessenkool wrote:
  On Wed, Aug 05, 2015 at 03:29:35PM +0200, Christophe Leroy wrote:
   On the 8xx, load latency is 2 cycles and taking branches also takes
   2 cycles. So let's unroll the loop.
  
  This is not true for most other 32-bit PowerPC; this patch makes
  performance worse on e.g. 6xx/7xx/7xxx.  Let's not!
 
 Chips with a load latency greater than 2 cycles should also benefit from the 
 unrolling.  Have you benchmarked this somewhere and seen it reduce 
 performance?  Do you know of any 32-bit PPC chips with a load latency less 
 than 2 cycles?

The original loop was already optimal, as the comment said.  The new
code adds extra instructions and a mispredicted branch.  You also
might get less overlap between the loads and adde (I didn't check
if there is any originally): those instructions are no longer
interleaved.

I think it is a stupid idea to optimise code for all 32-bit PowerPC
CPUs based on solely what is best for a particularly simple, slow
implementation; and that is what this patch is doing.


Segher
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [RFC v4] genalloc:support memory-allocation with bytes-alignment to genalloc

2015-08-05 Thread Scott Wood
On Wed, 2015-08-05 at 14:50 +0800, Zhao Qiang wrote:
 Bytes alignment is required to manage some special RAM,
 so add gen_pool_first_fit_align to genalloc,
 meanwhile add gen_pool_alloc_data to pass data to
 gen_pool_first_fit_align(modify gen_pool_alloc as a wrapper)
 
 Signed-off-by: Zhao Qiang qiang.z...@freescale.com
 ---
 *v2:
 changes:
 title has been modified, original patch link: 
 http://patchwork.ozlabs.org/patch/493297/
 
 original patch add a func gen_pool_alloc_align, 
 then pass alignment to it as an parameter.
 after discussing with lauraa and scott, they recommend 
 to pass alignment as part of data based on 
 commit message for ca279cf1065fb689abea1dc7d8c11787729bb185 which adds 
 data:
 
 As I can't predict all the possible requirements/needs for all allocation  
   
 uses cases, I add a free field 'void *data' to pass any needed 
 information to the allocation function.  For example 'data' could be used   
   
 to handle a structure where you store the alignment, the expected memory
 bank, the requester device, or any information that could influence the 
 allocation algorithm.
 
 *v3:
 changes:
 title has been modified, original patch link: 
 http://patchwork.ozlabs.org/patch/500317/
 
 according to the comments, add gen_pool_alloc_data,
 modify gen_pool_alloc as a wrapper, define struct data_align
 for gen_pool_first_fit_align algorithm. add parameter 
 pointer pool to algorithm.
 
 *v4:
 changes:
 v3 link: 
 http://patchwork.ozlabs.org/patch/500317/
 There are comments for v3, according to the comments,
 modify the patch for v4. such as modifying annotations,
 removing unnecessary chek, removing unnecessary cast and so on.
 
  include/linux/genalloc.h | 23 +++
  lib/genalloc.c   | 58 +++--
 ---
  2 files changed, 72 insertions(+), 9 deletions(-)
 

Looks good to me (except a minor change to the comments described below); 
send a non-RFC patch with the patches that use it.

 @@ -500,15 +518,42 @@ EXPORT_SYMBOL(gen_pool_set_algo);
   * @start: The bitnumber to start searching at
   * @nr: The number of zeroed bits we're looking for
   * @data: additional data - unused
 + * @pool: unused, but the algorithm functions have same format.
   */

Describe what pool actually is.  Whether it's used is irrelevant (and you can 
assume the reader knows that all algorithm functions have the same 
signature).  @data is different because it's defined per-algorithm and thus 
unused means no definition.

In other words, the purpose of these headers is to be a guide to the caller 
of the function, describing the API, not the function internals.

-Scott

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v6 02/42] powerpc/powernv: Drop pnv_ioda_setup_dev_PE()

2015-08-05 Thread Gavin Shan
Nobody is using the this function. The patch drops it.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
Reviewed-by: Alexey Kardashevskiy a...@ozlabs.ru
---
 arch/powerpc/platforms/powernv/pci-ioda.c | 71 ---
 1 file changed, 71 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 07666ec..38b5405 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -923,77 +923,6 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, 
int offset)
 }
 #endif /* CONFIG_PCI_IOV */
 
-#if 0
-static struct pnv_ioda_pe *pnv_ioda_setup_dev_PE(struct pci_dev *dev)
-{
-   struct pci_controller *hose = pci_bus_to_host(dev-bus);
-   struct pnv_phb *phb = hose-private_data;
-   struct pci_dn *pdn = pci_get_pdn(dev);
-   struct pnv_ioda_pe *pe;
-   int pe_num;
-
-   if (!pdn) {
-   pr_err(%s: Device tree node not associated properly\n,
-  pci_name(dev));
-   return NULL;
-   }
-   if (pdn-pe_number != IODA_INVALID_PE)
-   return NULL;
-
-   /* PE#0 has been pre-set */
-   if (dev-bus-number == 0)
-   pe_num = 0;
-   else
-   pe_num = pnv_ioda_alloc_pe(phb);
-   if (pe_num == IODA_INVALID_PE) {
-   pr_warning(%s: Not enough PE# available, disabling device\n,
-  pci_name(dev));
-   return NULL;
-   }
-
-   /* NOTE: We get only one ref to the pci_dev for the pdn, not for the
-* pointer in the PE data structure, both should be destroyed at the
-* same time. However, this needs to be looked at more closely again
-* once we actually start removing things (Hotplug, SR-IOV, ...)
-*
-* At some point we want to remove the PDN completely anyways
-*/
-   pe = phb-ioda.pe_array[pe_num];
-   pci_dev_get(dev);
-   pdn-pcidev = dev;
-   pdn-pe_number = pe_num;
-   pe-pdev = dev;
-   pe-pbus = NULL;
-   pe-tce32_seg = -1;
-   pe-mve_number = -1;
-   pe-rid = dev-bus-number  8 | pdn-devfn;
-
-   pe_info(pe, Associated device to PE\n);
-
-   if (pnv_ioda_configure_pe(phb, pe)) {
-   /* XXX What do we do here ? */
-   if (pe_num)
-   pnv_ioda_free_pe(phb, pe_num);
-   pdn-pe_number = IODA_INVALID_PE;
-   pe-pdev = NULL;
-   pci_dev_put(dev);
-   return NULL;
-   }
-
-   /* Assign a DMA weight to the device */
-   pe-dma_weight = pnv_ioda_dma_weight(dev);
-   if (pe-dma_weight != 0) {
-   phb-ioda.dma_weight += pe-dma_weight;
-   phb-ioda.dma_pe_count++;
-   }
-
-   /* Link the PE */
-   pnv_ioda_link_pe_by_weight(phb, pe);
-
-   return pe;
-}
-#endif /* Useful for SRIOV case */
-
 static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe)
 {
struct pci_dev *dev;
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v6 11/42] powerpc/powernv: Trace DMA32 segments consumed by PE

2015-08-05 Thread Gavin Shan
On P7IOC, the whole DMA32 space is divided evenly to 256MB segments.
Each PE can consume one or multiple DMA32 segments. Current code
doesn't trace the available DMA32 segments and those consumed by
one particular PE. It's conflicting with PCI hotplug.

The patch introduces one bitmap to PHB to trace the available
DMA32 segments for allocation, more fields to struct pnv_ioda_pe
to trace the consumed DMA32 segments by the PE, which is going to
be released when the PE is destroyed at PCI unplugging time.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/pci-ioda.c | 40 +++
 arch/powerpc/platforms/powernv/pci.h  |  4 +++-
 2 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index cd22002..57ba8fd 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1946,6 +1946,7 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
 
/* Grab a 32-bit TCE table */
pe-dma32_seg = base;
+   pe-dma32_segcount = segs;
pe_info(pe,  Setting up 32-bit TCE table at %08x..%08x\n,
(base  28), ((base + segs)  28) - 1);
 
@@ -2006,8 +2007,13 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb 
*phb,
return;
  fail:
/* XXX Failure: Try to fallback to 64-bit only ? */
-   if (pe-dma32_seg = 0)
+   if (pe-dma32_seg = 0) {
+   bitmap_clear(phb-ioda.dma32_segmap,
+pe-dma32_seg, pe-dma32_segcount);
pe-dma32_seg = -1;
+   pe-dma32_segcount = 0;
+   }
+
if (tce_mem)
__free_pages(tce_mem, get_order(TCE32_TABLE_SIZE * segs));
if (tbl) {
@@ -2443,12 +2449,11 @@ static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb 
*phb,
pnv_ioda_setup_bus_dma(pe, pe-pbus);
 }
 
-static unsigned int pnv_ioda1_setup_dma(struct pnv_phb *phb,
-   struct pnv_ioda_pe *pe,
-   unsigned int base)
+static void pnv_ioda1_setup_dma(struct pnv_phb *phb,
+   struct pnv_ioda_pe *pe)
 {
struct pci_controller *hose = phb-hose;
-   unsigned int dma_weight, segs;
+   unsigned int dma_weight, base, segs;
 
/* Calculate the PHB's DMA weight */
dma_weight = pnv_ioda_phb_dma_weight(phb);
@@ -2461,11 +2466,28 @@ static unsigned int pnv_ioda1_setup_dma(struct pnv_phb 
*phb,
else
segs = (pe-dma32_weight *
phb-ioda.dma32_segcount) / dma_weight;
+
+   /*
+* Allocate DMA32 segments. We might not have enough
+* resources available. However we expect at least one
+* to be available.
+*/
+   do {
+   base = bitmap_find_next_zero_area(phb-ioda.dma32_segmap,
+ phb-ioda.dma32_segcount,
+ 0, segs, 0);
+   if (base  phb-ioda.dma32_segcount) {
+   bitmap_set(phb-ioda.dma32_segmap, base, segs);
+   break;
+   }
+   } while (--segs);
+
+   if (WARN_ON(!segs))
+   return;
+
pe_info(pe, DMA weight %d, assigned %d segments\n,
pe-dma32_weight, segs);
pnv_pci_ioda_setup_dma_pe(phb, pe, base, segs);
-
-   return segs;
 }
 
 #ifdef CONFIG_PCI_MSI
@@ -2933,20 +2955,18 @@ static void pnv_pci_ioda_setup_DMA(void)
struct pci_controller *hose, *tmp;
struct pnv_phb *phb;
struct pnv_ioda_pe *pe;
-   unsigned int base;
 
list_for_each_entry_safe(hose, tmp, hose_list, list_node) {
phb = hose-private_data;
pnv_pci_ioda_setup_opal_tce_kill(phb);
 
-   base = 0;
list_for_each_entry(pe, phb-ioda.pe_dma_list, dma_link) {
if (!pe-dma32_weight)
continue;
 
switch (phb-type) {
case PNV_PHB_IODA1:
-   base += pnv_ioda1_setup_dma(phb, pe, base);
+   pnv_ioda1_setup_dma(phb, pe);
break;
case PNV_PHB_IODA2:
pnv_pci_ioda2_setup_dma_pe(phb, pe);
diff --git a/arch/powerpc/platforms/powernv/pci.h 
b/arch/powerpc/platforms/powernv/pci.h
index 574fe43..1dc9578 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -65,6 +65,7 @@ struct pnv_ioda_pe {
 
/* Base iommu table, ie, 4K TCEs, 32-bit DMA */
int dma32_seg;
+   int dma32_segcount;
struct iommu_table_group table_group;
 
/* 64-bit TCE bypass region */
@@ -153,10 

Re: [PATCH 1/3] Powerpc: mpc85xx: refactor the PM operations

2015-08-05 Thread Chenhui Zhao



On Thu, Aug 6, 2015 at 1:46 PM, Scott Wood scottw...@freescale.com 
wrote:

On Thu, 2015-08-06 at 12:20 +0800, Chenhui Zhao wrote:
 On Thu, Aug 6, 2015 at 10:57 AM, Scott Wood 
scottw...@freescale.com

 wrote:
  On Wed, 2015-08-05 at 18:11 +0800, Chenhui Zhao wrote:
On Tue, Aug 4, 2015 at 4:26 AM, Scott Wood 
scottw...@freescale.com

wrote:
 On Mon, 2015-08-03 at 19:32 +0800, Chenhui Zhao wrote:
   

   On Sat, Aug 1, 2015 at 7:59 AM, Scott Wood
   scottw...@freescale.com
   wrote:

   
Could you explain irq_mask()?  Why would there still be 
IRQs

  destined
for
this CPU at this point?
 
   This function just masks irq by setting the registers in 
RCPM

   (for
   example, RCPM_CPMIMR, RCPM_CPMCIMR). Actually, all irqs to
   this CPU
   have been migrated to other CPUs.

 So why do we need to set those bits in RCPM?  Is it just 
caution?

  
Setting these bits can mask interrupts signalled to RCPM from 
MPIC

   as a
means of
waking up from a lower power state. So, cores will not be 
waked up

unexpectedly.
 
  Why would the MPIC be signalling those interrupts if they've been
  masked at
  the MPIC?
 
  -Scott
 

 The interrupts to RCPM from MPIC are IRQ, Machine Check, NMI and
 Critical interrupts. Some of them didn't be masked in MPIC.


What interrupt could actually happen to a sleeping cpu that this 
protects

against?

-Scott


Not sure. Maybe spurious interrupts or hardware exceptions. However, 
setting them make sure dead cpus can not be waked up unexpectedly.


-Chenhui

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v6 05/42] powerpc/powernv: Track IO/M32/M64 segments from PE

2015-08-05 Thread Gavin Shan
The patch is adding 6 bitmaps, three to PE and three to PHB, to track
the consumed by one particular PE, which can be released once the PE
is destroyed during PCI unplugging time. Also, we're using fixed
quantity of bits to trace the used IO, M32 and M64 segments by PEs
in one particular PHB.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/pci-ioda.c | 29 +++--
 arch/powerpc/platforms/powernv/pci.h  | 18 ++
 2 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index e4ac703..78b49a1 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -388,6 +388,12 @@ static int pnv_ioda_pick_m64_pe(struct pci_bus *bus, bool 
all)
list_add_tail(pe-list, master_pe-slaves);
}
 
+   /* M64 segments consumed by slave PEs are tracked
+* by master PE
+*/
+   set_bit(pe-pe_number, master_pe-m64_segmap);
+   set_bit(pe-pe_number, phb-ioda.m64_segmap);
+
/* P7IOC supports M64DT, which helps mapping M64 segment
 * to one particular PE#. However, PHB3 has fixed mapping
 * between M64 segment and PE#. In order to have same logic
@@ -2871,9 +2877,11 @@ static void pnv_ioda_setup_pe_seg(struct pci_controller 
*hose,
 
while (index  phb-ioda.total_pe 
   region.start = region.end) {
-   phb-ioda.io_segmap[index] = pe-pe_number;
+   set_bit(index, pe-io_segmap);
+   set_bit(index, phb-ioda.io_segmap);
rc = opal_pci_map_pe_mmio_window(phb-opal_id,
-   pe-pe_number, OPAL_IO_WINDOW_TYPE, 0, 
index);
+   pe-pe_number, OPAL_IO_WINDOW_TYPE,
+   0, index);
if (rc != OPAL_SUCCESS) {
pr_err(%s: OPAL error %d when mapping 
IO 
   segment #%d to PE#%d\n,
@@ -2896,9 +2904,11 @@ static void pnv_ioda_setup_pe_seg(struct pci_controller 
*hose,
 
while (index  phb-ioda.total_pe 
   region.start = region.end) {
-   phb-ioda.m32_segmap[index] = pe-pe_number;
+   set_bit(index, pe-m32_segmap);
+   set_bit(index, phb-ioda.m32_segmap);
rc = opal_pci_map_pe_mmio_window(phb-opal_id,
-   pe-pe_number, OPAL_M32_WINDOW_TYPE, 0, 
index);
+   pe-pe_number, OPAL_M32_WINDOW_TYPE,
+   0, index);
if (rc != OPAL_SUCCESS) {
pr_err(%s: OPAL error %d when mapping 
M32 
   segment#%d to PE#%d,
@@ -3090,7 +3100,7 @@ static void __init pnv_pci_init_ioda_phb(struct 
device_node *np,
 {
struct pci_controller *hose;
struct pnv_phb *phb;
-   unsigned long size, m32map_off, pemap_off, iomap_off = 0;
+   unsigned long size, pemap_off;
const __be64 *prop64;
const __be32 *prop32;
int len;
@@ -3175,19 +3185,10 @@ static void __init pnv_pci_init_ioda_phb(struct 
device_node *np,
 
/* Allocate aux data  arrays. We don't have IO ports on PHB3 */
size = _ALIGN_UP(phb-ioda.total_pe / 8, sizeof(unsigned long));
-   m32map_off = size;
-   size += phb-ioda.total_pe * sizeof(phb-ioda.m32_segmap[0]);
-   if (phb-type == PNV_PHB_IODA1) {
-   iomap_off = size;
-   size += phb-ioda.total_pe * sizeof(phb-ioda.io_segmap[0]);
-   }
pemap_off = size;
size += phb-ioda.total_pe * sizeof(struct pnv_ioda_pe);
aux = memblock_virt_alloc(size, 0);
phb-ioda.pe_alloc = aux;
-   phb-ioda.m32_segmap = aux + m32map_off;
-   if (phb-type == PNV_PHB_IODA1)
-   phb-ioda.io_segmap = aux + iomap_off;
phb-ioda.pe_array = aux + pemap_off;
set_bit(phb-ioda.reserved_pe, phb-ioda.pe_alloc);
 
diff --git a/arch/powerpc/platforms/powernv/pci.h 
b/arch/powerpc/platforms/powernv/pci.h
index 62239b1..08a4e57 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -49,6 +49,15 @@ struct pnv_ioda_pe {
/* PE number */
unsigned intpe_number;
 
+   /* IO/M32/M64 segments consumed by the PE. Each PE can
+* have one M64 segment at most, but M64 segments consumed
+* by slave PEs will be contributed to the master PE. One
+ 

[PATCH v6 07/42] powerpc/powernv: Improve IO and M32 mapping

2015-08-05 Thread Gavin Shan
There're 3 windows (IO, M32 and M64) for PHB, root port and upstream
port of the PCIE switch behind root port. In order to support PCI
hotplug, we extend the start/end address of those 3 windows of root
port or upstream port to the start/end address of the 3 PHB's windows.
The current implementation, assigning IO or M32 segment based on the
bridge's windows, isn't reliable.

The patch fixes above issue by calculating PE's consumed IO or M32
segments from its contained devices, no PCI bridge windows involved
if the PE doesn't contain all the subordinate PCI buses. Otherwise,
the PCI bridge windows still contribute to PE's consumed IO or M32
segments.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/pci-ioda.c | 136 +-
 1 file changed, 79 insertions(+), 57 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 488a53e..713f4b4 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -2844,75 +2844,97 @@ static void pnv_pci_ioda_fixup_iov_resources(struct 
pci_dev *pdev)
 }
 #endif /* CONFIG_PCI_IOV */
 
-/*
- * This function is supposed to be called on basis of PE from top
- * to bottom style. So the the I/O or MMIO segment assigned to
- * parent PE could be overrided by its child PEs if necessary.
- */
-static void pnv_ioda_setup_pe_seg(struct pci_controller *hose,
- struct pnv_ioda_pe *pe)
+static int pnv_ioda_setup_one_res(struct pci_controller *hose,
+ struct pnv_ioda_pe *pe,
+ struct resource *res)
 {
struct pnv_phb *phb = hose-private_data;
struct pci_bus_region region;
-   struct resource *res;
-   int i, index;
-   unsigned int segsize;
+   unsigned int index, segsize;
unsigned long *segmap, *pe_segmap;
uint16_t win;
int64_t rc;
 
-   /*
-* NOTE: We only care PCI bus based PE for now. For PCI
-* device based PE, for example SRIOV sensitive VF should
-* be figured out later.
-*/
-   BUG_ON(!(pe-flags  (PNV_IODA_PE_BUS | PNV_IODA_PE_BUS_ALL)));
+   /* Check if we need map the resource */
+   if (!res-parent || !res-flags || res-start  res-end)
+   return 0;
 
-   pci_bus_for_each_resource(pe-pbus, res, i) {
-   if (!res || !res-flags ||
-   res-start  res-end)
-   continue;
+   if (res-flags  IORESOURCE_IO) {
+   region.start = res-start - phb-ioda.io_pci_base;
+   region.end   = res-end - phb-ioda.io_pci_base;
+   segsize  = phb-ioda.io_segsize;
+   segmap   = phb-ioda.io_segmap;
+   pe_segmap= pe-io_segmap;
+   win  = OPAL_IO_WINDOW_TYPE;
+   } else if ((res-flags  IORESOURCE_MEM) 
+  !pnv_pci_is_mem_pref_64(res-flags)) {
+   region.start = res-start -
+  hose-mem_offset[0] -
+  phb-ioda.m32_pci_base;
+   region.end   = res-end -
+  hose-mem_offset[0] -
+  phb-ioda.m32_pci_base;
+   segsize  = phb-ioda.m32_segsize;
+   segmap   = phb-ioda.m32_segmap;
+   pe_segmap= pe-m32_segmap;
+   win  = OPAL_M32_WINDOW_TYPE;
+   } else {
+   return 0;
+   }
 
-   if (res-flags  IORESOURCE_IO) {
-   region.start = res-start - phb-ioda.io_pci_base;
-   region.end   = res-end - phb-ioda.io_pci_base;
-   segsize  = phb-ioda.io_segsize;
-   segmap   = phb-ioda.io_segmap;
-   pe_segmap= pe-io_segmap;
-   win  = OPAL_IO_WINDOW_TYPE;
-   } else if ((res-flags  IORESOURCE_MEM) 
-  !pnv_pci_is_mem_pref_64(res-flags)) {
-   region.start = res-start -
-  hose-mem_offset[0] -
-  phb-ioda.m32_pci_base;
-   region.end   = res-end -
-  hose-mem_offset[0] -
-  phb-ioda.m32_pci_base;
-   segsize  = phb-ioda.m32_segsize;
-   segmap   = phb-ioda.m32_segmap;
-   pe_segmap= pe-m32_segmap;
-   win  = OPAL_M32_WINDOW_TYPE;
-   } else {
-   continue;
+   region.start = _ALIGN_DOWN(region.start, segsize);
+   region.end   = _ALIGN_UP(region.end, segsize);
+   index = region.start / segsize;
+   while (index  phb-ioda.total_pe 
+  region.start  

[PATCH v6 14/42] powerpc/pci: Override pcibios_setup_bridge()

2015-08-05 Thread Gavin Shan
The patch overrides pcibios_setup_bridge(), called to update PCI
bridge windows at completion of PCI resource assignment, to assign
PE and setup various (resource) mapping in next patch.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/include/asm/pci-bridge.h | 2 ++
 arch/powerpc/kernel/pci-common.c  | 8 
 2 files changed, 10 insertions(+)

diff --git a/arch/powerpc/include/asm/pci-bridge.h 
b/arch/powerpc/include/asm/pci-bridge.h
index d627abf..65357a9 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -34,6 +34,8 @@ struct pci_controller_ops {
/* Called during PCI resource reassignment */
resource_size_t (*window_alignment)(struct pci_bus *bus,
unsigned long type);
+   void(*setup_bridge)(struct pci_bus *bus,
+   unsigned long type);
void(*reset_secondary_bus)(struct pci_dev *dev);
 
 #ifdef CONFIG_PCI_MSI
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index b9de34d..9c88dcd1 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -123,6 +123,14 @@ resource_size_t pcibios_window_alignment(struct pci_bus 
*bus,
return 1;
 }
 
+void pcibios_setup_bridge(struct pci_bus *bus, unsigned long type)
+{
+   struct pci_controller *hose = pci_bus_to_host(bus);
+
+   if (hose-controller_ops.setup_bridge)
+   hose-controller_ops.setup_bridge(bus, type);
+}
+
 void pcibios_reset_secondary_bus(struct pci_dev *dev)
 {
struct pci_controller *phb = pci_bus_to_host(dev-bus);
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v6 33/42] powerpc/powernv: Functions to get/reset PCI slot status

2015-08-05 Thread Gavin Shan
The patch exports 4 functions, which base on corresponding OPAL
APIs to get or set PCI slot status. Those functions are going to
be used by PCI hotplug module in subsequent patches:

   pnv_pci_get_device_tree()  opal_get_device_tree()
   pnv_pci_get_presence_status()  opal_pci_get_presence_status()
   pnv_pci_get_power_status() opal_pci_get_power_status()
   pnv_pci_set_power_status() opal_pci_set_power_status()

Besides, the patch also exports pnv_pci_hotplug_notifier_{register,
unregister}() to allow registration and unregistration of PCI hotplug
notifier, which will be used to receive PCI hotplug message from skiboot
firmware.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/include/asm/opal-api.h|  8 +++-
 arch/powerpc/include/asm/opal.h|  5 ++
 arch/powerpc/include/asm/pnv-pci.h |  7 +++
 arch/powerpc/platforms/powernv/opal-wrappers.S |  4 ++
 arch/powerpc/platforms/powernv/pci.c   | 66 ++
 5 files changed, 89 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/opal-api.h 
b/arch/powerpc/include/asm/opal-api.h
index 442995b..33c67ee 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -154,7 +154,11 @@
 #define OPAL_FLASH_WRITE   111
 #define OPAL_FLASH_ERASE   112
 #define OPAL_PRD_MSG   113
-#define OPAL_LAST  113
+#define OPAL_GET_DEVICE_TREE   117
+#define OPAL_PCI_GET_PRESENCE_STATUS   118
+#define OPAL_PCI_GET_POWER_STATUS  119
+#define OPAL_PCI_SET_POWER_STATUS  120
+#define OPAL_LAST  120
 
 /* Device tree flags */
 
@@ -361,6 +365,8 @@ enum opal_msg_type {
OPAL_MSG_HMI_EVT,
OPAL_MSG_DPO,
OPAL_MSG_PRD,
+   OPAL_MSG_OCC,
+   OPAL_MSG_PCI_HOTPLUG,
OPAL_MSG_TYPE_MAX,
 };
 
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index bbb3aa6..53b8528 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -203,6 +203,11 @@ int64_t opal_flash_write(uint64_t id, uint64_t offset, 
uint64_t buf,
uint64_t size, uint64_t token);
 int64_t opal_flash_erase(uint64_t id, uint64_t offset, uint64_t size,
uint64_t token);
+int64_t opal_get_device_tree(uint32_t phandle, uint64_t buf, uint64_t len);
+int64_t opal_pci_get_presence_status(uint64_t id, uint8_t *status);
+int64_t opal_pci_get_power_status(uint64_t id, uint8_t *status);
+int64_t opal_pci_set_power_status(uint64_t id, uint8_t status);
+
 
 /* Internal functions */
 extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
diff --git a/arch/powerpc/include/asm/pnv-pci.h 
b/arch/powerpc/include/asm/pnv-pci.h
index 6f77f71..7efa87f 100644
--- a/arch/powerpc/include/asm/pnv-pci.h
+++ b/arch/powerpc/include/asm/pnv-pci.h
@@ -13,6 +13,13 @@
 #include linux/pci.h
 #include misc/cxl-base.h
 
+extern int pnv_pci_get_device_tree(uint32_t phandle, void *buf, uint64_t len);
+extern int pnv_pci_get_presence_status(uint64_t id, uint8_t *status);
+extern int pnv_pci_get_power_status(uint64_t id, uint8_t *status);
+extern int pnv_pci_set_power_status(uint64_t id, uint8_t status);
+extern int pnv_pci_hotplug_notifier_register(struct notifier_block *nb);
+extern int pnv_pci_hotplug_notifier_unregister(struct notifier_block *nb);
+
 int pnv_phb_to_cxl_mode(struct pci_dev *dev, uint64_t mode);
 int pnv_cxl_ioda_msi_setup(struct pci_dev *dev, unsigned int hwirq,
   unsigned int virq);
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S 
b/arch/powerpc/platforms/powernv/opal-wrappers.S
index 88e4333..804f8cc 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -298,3 +298,7 @@ OPAL_CALL(opal_flash_read,  
OPAL_FLASH_READ);
 OPAL_CALL(opal_flash_write,OPAL_FLASH_WRITE);
 OPAL_CALL(opal_flash_erase,OPAL_FLASH_ERASE);
 OPAL_CALL(opal_prd_msg,OPAL_PRD_MSG);
+OPAL_CALL(opal_get_device_tree,OPAL_GET_DEVICE_TREE);
+OPAL_CALL(opal_pci_get_presence_status,
OPAL_PCI_GET_PRESENCE_STATUS);
+OPAL_CALL(opal_pci_get_power_status,   OPAL_PCI_GET_POWER_STATUS);
+OPAL_CALL(opal_pci_set_power_status,   OPAL_PCI_SET_POWER_STATUS);
diff --git a/arch/powerpc/platforms/powernv/pci.c 
b/arch/powerpc/platforms/powernv/pci.c
index 801e3e8..5982110 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -65,6 +65,72 @@ int pnv_pci_poll(uint64_t id, int64_t rval, uint8_t *pval)
return rval ? -EIO : 0;
 }
 
+int pnv_pci_get_device_tree(uint32_t phandle, void *buf, uint64_t len)
+{
+   int64_t rc;
+
+   if (!opal_check_token(OPAL_GET_DEVICE_TREE))

[PATCH v6 20/42] powerpc/powernv: Create PEs dynamically

2015-08-05 Thread Gavin Shan
Currently, the PEs and their associated resources are assigned
in ppc_md.pcibios_fixup() except those consumed by SRIOV VFs.
The function is called for once after PCI probing and resources
assignment is finished which isn't hotplug friendly.

The patch creates PEs dynamically by ppc_md.pcibios_setup_bridge(),
which is called on the event during system bootup and PCI hotplug:
updating PCI bridge's windows after resource assignment/reassignment
are finished. For partial hotplug case, where not all PCI devices
belonging to the PE are unplugged and plugged again, we just need
unbinding/binding the affected PCI devices with the corresponding
PE without creating new one.

Besides, it might require additional resources (e.g. M32) to the
windows of the PCI bridge when unplugging current adapter, and
insert a different adapter if there is one PCI slot, which is
assumed behind root port, or the downstream bridge of the PCIE
switch behind root port. The parent bridge of the newly plugged
adapter would reject the request to add more resources, leading
to hotplug failure. For the issue, the patch extends the windows
of root port, or the upstream port of the PCIe switch behind root
port to PHB's windows when ppc_md.pcibios_setup_bridge() is called.

There is no upstream bridge for root bus, so we have to fix it up
before any PE is created because the root bus PE is the ancestor
to anyone else.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/pci-ioda.c | 226 ++
 arch/powerpc/platforms/powernv/pci.h  |   1 +
 2 files changed, 137 insertions(+), 90 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 8aa6ab8..37847a3 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1083,6 +1083,13 @@ static void pnv_ioda_setup_same_PE(struct pci_bus *bus, 
struct pnv_ioda_pe *pe)
pci_name(dev));
continue;
}
+
+   /* The PCI device might be not detached from the
+* PE in partial hotplug case.
+*/
+   if (pdn-pe_number != IODA_INVALID_PE)
+   continue;
+
pdn-pe_number = pe-pe_number;
pe-dma32_weight += pnv_ioda_dma_weight(dev);
if ((pe-flags  PNV_IODA_PE_BUS_ALL)  dev-subordinate)
@@ -1101,9 +1108,27 @@ static struct pnv_ioda_pe *pnv_ioda_setup_bus_PE(struct 
pci_bus *bus, bool all)
struct pci_controller *hose = pci_bus_to_host(bus);
struct pnv_phb *phb = hose-private_data;
struct pnv_ioda_pe *pe = NULL;
+   int pe_num;
+
+   /* For partial hotplug case, the PE instance hasn't been destroyed
+* yet. We shouldn't allocated a new one and assign resources to
+* it. The existing PE instance should be reused, but we should
+* associate the devices to the PE.
+*/
+   pe_num = phb-ioda.pe_rmap[bus-number  8];
+   if (pe_num != IODA_INVALID_PE) {
+   pe = phb-ioda.pe_array[pe_num];
+   pnv_ioda_setup_same_PE(bus, pe);
+   return NULL;
+   }
+
+   /* PE number for root bus should have been reserved */
+   if (pci_is_root_bus(bus) 
+   phb-ioda.root_pe_idx != IODA_INVALID_PE)
+   pe = phb-ioda.pe_array[phb-ioda.root_pe_idx];
 
/* Check if PE is determined by M64 */
-   if (phb-pick_m64_pe)
+   if (!pe  phb-pick_m64_pe)
pe = phb-pick_m64_pe(bus, all);
 
/* The PE number isn't pinned by M64 */
@@ -1150,46 +1175,6 @@ static struct pnv_ioda_pe *pnv_ioda_setup_bus_PE(struct 
pci_bus *bus, bool all)
return pe;
 }
 
-static void pnv_ioda_setup_PEs(struct pci_bus *bus)
-{
-   struct pci_dev *dev;
-
-   pnv_ioda_setup_bus_PE(bus, false);
-
-   list_for_each_entry(dev, bus-devices, bus_list) {
-   if (dev-subordinate) {
-   if (pci_pcie_type(dev) == PCI_EXP_TYPE_PCI_BRIDGE)
-   pnv_ioda_setup_bus_PE(dev-subordinate, true);
-   else
-   pnv_ioda_setup_PEs(dev-subordinate);
-   }
-   }
-}
-
-/*
- * Configure PEs so that the downstream PCI buses and devices
- * could have their associated PE#. Unfortunately, we didn't
- * figure out the way to identify the PLX bridge yet. So we
- * simply put the PCI bus and the subordinate behind the root
- * port to PE# here. The game rule here is expected to be changed
- * as soon as we can detected PLX bridge correctly.
- */
-static void pnv_pci_ioda_setup_PEs(void)
-{
-   struct pci_controller *hose, *tmp;
-   struct pnv_phb *phb;
-
-   list_for_each_entry_safe(hose, tmp, hose_list, list_node) {
-   phb = hose-private_data;
-
-   /* M64 layout might affect PE allocation */
-

Re: [PATCH 1/3] Powerpc: mpc85xx: refactor the PM operations

2015-08-05 Thread Chenhui Zhao



On Thu, Aug 6, 2015 at 10:57 AM, Scott Wood scottw...@freescale.com 
wrote:

On Wed, 2015-08-05 at 18:11 +0800, Chenhui Zhao wrote:

 On Tue, Aug 4, 2015 at 4:26 AM, Scott Wood scottw...@freescale.com
 wrote:
  On Mon, 2015-08-03 at 19:32 +0800, Chenhui Zhao wrote:

 
On Sat, Aug 1, 2015 at 7:59 AM, Scott Wood 
scottw...@freescale.com

wrote:
 

 Could you explain irq_mask()?  Why would there still be IRQs
   destined
 for
 this CPU at this point?
  
This function just masks irq by setting the registers in RCPM 
(for
example, RCPM_CPMIMR, RCPM_CPMCIMR). Actually, all irqs to 
this CPU

have been migrated to other CPUs.
 
  So why do we need to set those bits in RCPM?  Is it just caution?

 Setting these bits can mask interrupts signalled to RCPM from MPIC 
as a

 means of
 waking up from a lower power state. So, cores will not be waked up
 unexpectedly.


Why would the MPIC be signalling those interrupts if they've been 
masked at

the MPIC?

-Scott



The interrupts to RCPM from MPIC are IRQ, Machine Check, NMI and 
Critical interrupts. Some of them didn't be masked in MPIC.


-Chenhui

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH V2 1/6] powerpc/powernv: don't enable SRIOV when VF BAR contains non M64 BAR

2015-08-05 Thread Gavin Shan
On Wed, Aug 05, 2015 at 09:24:58AM +0800, Wei Yang wrote:
On PHB_IODA2, we enable SRIOV devices by mapping IOV BAR with M64 BARs. If
a SRIOV device's BAR is not 64-bit prefetchable, this is not assigned from
M64 windwo, which means M64 BAR can't work on it.


s/PHB_IODA2/PHB3
s/windwo/window

This patch makes this explicit.

Signed-off-by: Wei Yang weiy...@linux.vnet.ibm.com

The idea sounds right, but there is one question as below.

---
 arch/powerpc/platforms/powernv/pci-ioda.c |   25 +
 1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 5738d31..9b41dba 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -908,9 +908,6 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, 
int offset)
   if (!res-flags || !res-parent)
   continue;

-  if (!pnv_pci_is_mem_pref_64(res-flags))
-  continue;
-
   /*
* The actual IOV BAR range is determined by the start address
* and the actual size for num_vfs VFs BAR.  This check is to
@@ -939,9 +936,6 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, 
int offset)
   if (!res-flags || !res-parent)
   continue;

-  if (!pnv_pci_is_mem_pref_64(res-flags))
-  continue;
-
   size = pci_iov_resource_size(dev, i + PCI_IOV_RESOURCES);
   res2 = *res;
   res-start += size * offset;
@@ -1221,9 +1215,6 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, 
u16 num_vfs)
   if (!res-flags || !res-parent)
   continue;

-  if (!pnv_pci_is_mem_pref_64(res-flags))
-  continue;
-
   for (j = 0; j  vf_groups; j++) {
   do {
   win = 
 find_next_zero_bit(phb-ioda.m64_bar_alloc,
@@ -1510,6 +1501,12 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 
num_vfs)
   pdn = pci_get_pdn(pdev);

   if (phb-type == PNV_PHB_IODA2) {
+  if (!pdn-vfs_expanded) {
+  dev_info(pdev-dev, don't support this SRIOV device
+   with non M64 VF BAR\n);
+  return -EBUSY;
+  }
+

It would be -ENOSPC since -EBUSY indicates the devices (VFs) are temparily
unavailable. For this case, the VFs are permanently unavailable because of
running out of space to accomodate M64 and non-M64 VF BARs.

The error message could be printed with dev_warn() and it would be precise
as below or something else you prefer:

dev_warn(pdev-dev, SRIOV not supported because of non-M64 VF BAR\n);


   /* Calculate available PE for required VFs */
   mutex_lock(phb-ioda.pe_alloc_mutex);
   pdn-offset = bitmap_find_next_zero_area(
@@ -2774,9 +2771,10 @@ static void pnv_pci_ioda_fixup_iov_resources(struct 
pci_dev *pdev)
   if (!res-flags || res-parent)
   continue;
   if (!pnv_pci_is_mem_pref_64(res-flags)) {
-  dev_warn(pdev-dev,  non M64 VF BAR%d: %pR\n,
+  dev_warn(pdev-dev, Don't support SR-IOV with
+   non M64 VF BAR%d: %pR. \n,
i, res);
-  continue;
+  return;
   }

   size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
@@ -2795,11 +2793,6 @@ static void pnv_pci_ioda_fixup_iov_resources(struct 
pci_dev *pdev)
   res = pdev-resource[i + PCI_IOV_RESOURCES];
   if (!res-flags || res-parent)
   continue;
-  if (!pnv_pci_is_mem_pref_64(res-flags)) {
-  dev_warn(pdev-dev, Skipping expanding VF BAR%d: 
%pR\n,
-   i, res);
-  continue;
-  }

When any one IOV BAR on the PF is non-M64, none of the VFs can be enabled.
Will we still allocate/assign M64 or M32 resources for the IOV BARs? If so,
I think it can be avoided.


   dev_dbg(pdev-dev,  Fixing VF BAR%d: %pR to\n, i, res);
   size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
-- 
1.7.9.5


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH 1/3] Powerpc: mpc85xx: refactor the PM operations

2015-08-05 Thread Scott Wood
On Thu, 2015-08-06 at 12:20 +0800, Chenhui Zhao wrote:
 On Thu, Aug 6, 2015 at 10:57 AM, Scott Wood scottw...@freescale.com 
 wrote:
  On Wed, 2015-08-05 at 18:11 +0800, Chenhui Zhao wrote:
On Tue, Aug 4, 2015 at 4:26 AM, Scott Wood scottw...@freescale.com
wrote:
 On Mon, 2015-08-03 at 19:32 +0800, Chenhui Zhao wrote:
   

   On Sat, Aug 1, 2015 at 7:59 AM, Scott Wood 
   scottw...@freescale.com
   wrote:

   
Could you explain irq_mask()?  Why would there still be IRQs
  destined
for
this CPU at this point?
 
   This function just masks irq by setting the registers in RCPM 
   (for
   example, RCPM_CPMIMR, RCPM_CPMCIMR). Actually, all irqs to 
   this CPU
   have been migrated to other CPUs.

 So why do we need to set those bits in RCPM?  Is it just caution?
   
Setting these bits can mask interrupts signalled to RCPM from MPIC 
   as a
means of
waking up from a lower power state. So, cores will not be waked up
unexpectedly.
  
  Why would the MPIC be signalling those interrupts if they've been 
  masked at
  the MPIC?
  
  -Scott
  
 
 The interrupts to RCPM from MPIC are IRQ, Machine Check, NMI and 
 Critical interrupts. Some of them didn't be masked in MPIC.

What interrupt could actually happen to a sleeping cpu that this protects 
against?

-Scott

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v6 01/42] PCI: Add pcibios_setup_bridge()

2015-08-05 Thread Gavin Shan
Currently, PowerPC PowerNV platform utilizes ppc_md.pcibios_fixup(),
which is called for once after PCI probing and resource assignment
are completed, to allocate platform required resources for PCI devices:
PE#, IO and MMIO mapping, DMA address translation (TCE) table etc.
Obviously, it's not hotplug friendly.

The patch adds weak function pcibios_setup_bridge(), which is called
by pci_setup_bridge(). PowerPC PowerNV platform will reuse the function
to assign above platform required resources to newly added PCI devices,
in order to support PCI hotplug in subsequent patches.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
Acked-by: Bjorn Helgaas bhelg...@google.com
---
 drivers/pci/setup-bus.c | 5 +
 include/linux/pci.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 508cc56..a69eae1 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -696,11 +696,16 @@ static void __pci_setup_bridge(struct pci_bus *bus, 
unsigned long type)
pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus-bridge_ctl);
 }
 
+void __weak pcibios_setup_bridge(struct pci_bus *bus, unsigned long type)
+{
+}
+
 void pci_setup_bridge(struct pci_bus *bus)
 {
unsigned long type = IORESOURCE_IO | IORESOURCE_MEM |
  IORESOURCE_PREFETCH;
 
+   pcibios_setup_bridge(bus, type);
__pci_setup_bridge(bus, type);
 }
 
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 3fed437..0fa9712 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -816,6 +816,7 @@ void pci_stop_and_remove_bus_device_locked(struct pci_dev 
*dev);
 void pci_stop_root_bus(struct pci_bus *bus);
 void pci_remove_root_bus(struct pci_bus *bus);
 void pci_setup_cardbus(struct pci_bus *bus);
+void pcibios_setup_bridge(struct pci_bus *bus, unsigned long type);
 void pci_sort_breadthfirst(void);
 #define dev_is_pci(d) ((d)-bus == pci_bus_type)
 #define dev_is_pf(d) ((dev_is_pci(d) ? to_pci_dev(d)-is_physfn : false))
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v6 15/42] powerpc/powernv: PE oriented during configuration

2015-08-05 Thread Gavin Shan
Several functions used to configure PE take pe_number to indentify
PE instance. As the pe_number is included in PE instance after it
is reserved or allocated. It's convienent for those functions to
return PE instance which includes the required pe_number.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/pci-ioda.c | 51 ---
 arch/powerpc/platforms/powernv/pci.h  |  2 +-
 2 files changed, 27 insertions(+), 26 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 3094c61..9f53682 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -132,12 +132,12 @@ static inline bool pnv_pci_is_mem_pref_64(unsigned long 
flags)
(IORESOURCE_MEM_64 | IORESOURCE_PREFETCH));
 }
 
-static void pnv_ioda_reserve_pe(struct pnv_phb *phb, int pe_no)
+static struct pnv_ioda_pe *pnv_ioda_reserve_pe(struct pnv_phb *phb, int pe_no)
 {
if (!(pe_no = 0  pe_no  phb-ioda.total_pe)) {
pr_warn(%s: Invalid PE %d on PHB#%x\n,
__func__, pe_no, phb-hose-global_number);
-   return;
+   return NULL;
}
 
if (test_and_set_bit(pe_no, phb-ioda.pe_alloc))
@@ -146,9 +146,11 @@ static void pnv_ioda_reserve_pe(struct pnv_phb *phb, int 
pe_no)
 
phb-ioda.pe_array[pe_no].phb = phb;
phb-ioda.pe_array[pe_no].pe_number = pe_no;
+
+   return phb-ioda.pe_array[pe_no];
 }
 
-static int pnv_ioda_alloc_pe(struct pnv_phb *phb)
+static struct pnv_ioda_pe *pnv_ioda_alloc_pe(struct pnv_phb *phb)
 {
unsigned long pe;
 
@@ -156,12 +158,12 @@ static int pnv_ioda_alloc_pe(struct pnv_phb *phb)
pe = find_next_zero_bit(phb-ioda.pe_alloc,
phb-ioda.total_pe, 0);
if (pe = phb-ioda.total_pe)
-   return IODA_INVALID_PE;
+   return NULL;
} while(test_and_set_bit(pe, phb-ioda.pe_alloc));
 
phb-ioda.pe_array[pe].phb = phb;
phb-ioda.pe_array[pe].pe_number = pe;
-   return pe;
+   return phb-ioda.pe_array[pe];
 }
 
 static void pnv_ioda_free_pe(struct pnv_phb *phb, int pe)
@@ -334,7 +336,7 @@ static void pnv_ioda_reserve_m64_pe(struct pci_bus *bus,
}
 }
 
-static int pnv_ioda_pick_m64_pe(struct pci_bus *bus, bool all)
+static struct pnv_ioda_pe *pnv_ioda_pick_m64_pe(struct pci_bus *bus, bool all)
 {
struct pci_controller *hose = pci_bus_to_host(bus);
struct pnv_phb *phb = hose-private_data;
@@ -344,7 +346,7 @@ static int pnv_ioda_pick_m64_pe(struct pci_bus *bus, bool 
all)
 
/* Root bus shouldn't use M64 */
if (pci_is_root_bus(bus))
-   return IODA_INVALID_PE;
+   return NULL;
 
/* Allocate bitmap */
size = _ALIGN_UP(phb-ioda.total_pe / 8, sizeof(unsigned long));
@@ -352,7 +354,7 @@ static int pnv_ioda_pick_m64_pe(struct pci_bus *bus, bool 
all)
if (!pe_alloc) {
pr_warn(%s: Out of memory !\n,
__func__);
-   return IODA_INVALID_PE;
+   return NULL;
}
 
/* Figure out reserved PE numbers by the PE */
@@ -365,7 +367,7 @@ static int pnv_ioda_pick_m64_pe(struct pci_bus *bus, bool 
all)
 */
if (bitmap_empty(pe_alloc, phb-ioda.total_pe)) {
kfree(pe_alloc);
-   return IODA_INVALID_PE;
+   return NULL;
}
 
/*
@@ -416,7 +418,7 @@ static int pnv_ioda_pick_m64_pe(struct pci_bus *bus, bool 
all)
}
 
kfree(pe_alloc);
-   return master_pe-pe_number;
+   return master_pe;
 }
 
 static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb)
@@ -1069,28 +1071,26 @@ static void pnv_ioda_setup_same_PE(struct pci_bus *bus, 
struct pnv_ioda_pe *pe)
  * subordinate PCI devices and buses. The second type of PE is normally
  * orgiriated by PCIe-to-PCI bridge or PLX switch downstream ports.
  */
-static void pnv_ioda_setup_bus_PE(struct pci_bus *bus, bool all)
+static struct pnv_ioda_pe *pnv_ioda_setup_bus_PE(struct pci_bus *bus, bool all)
 {
struct pci_controller *hose = pci_bus_to_host(bus);
struct pnv_phb *phb = hose-private_data;
-   struct pnv_ioda_pe *pe;
-   int pe_num = IODA_INVALID_PE;
+   struct pnv_ioda_pe *pe = NULL;
 
/* Check if PE is determined by M64 */
if (phb-pick_m64_pe)
-   pe_num = phb-pick_m64_pe(bus, all);
+   pe = phb-pick_m64_pe(bus, all);
 
/* The PE number isn't pinned by M64 */
-   if (pe_num == IODA_INVALID_PE)
-   pe_num = pnv_ioda_alloc_pe(phb);
+   if (!pe)
+   pe = pnv_ioda_alloc_pe(phb);
 
-   if (pe_num == IODA_INVALID_PE) {
-   pr_warning(%s: Not enough PE# available for PCI bus 
%04x:%02x\n,
+   if (!pe) {
+   

[PATCH v6 41/42] drivers/of: Export OF changeset functions

2015-08-05 Thread Gavin Shan
The PowerNV PCI hotplug driver is going to use the OF changeset
to manage the changed device sub-tree, which requires those OF
changeset functions are exported.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 drivers/of/dynamic.c  | 65 ---
 drivers/of/overlay.c  |  8 +++
 drivers/of/unittest.c |  4 ++--
 include/linux/of.h|  2 ++
 4 files changed, 54 insertions(+), 25 deletions(-)

diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index 53826b8..af65b5b 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -646,6 +646,7 @@ void of_changeset_init(struct of_changeset *ocs)
memset(ocs, 0, sizeof(*ocs));
INIT_LIST_HEAD(ocs-entries);
 }
+EXPORT_SYMBOL(of_changeset_init);
 
 /**
  * of_changeset_destroy - Destroy a changeset
@@ -662,20 +663,9 @@ void of_changeset_destroy(struct of_changeset *ocs)
list_for_each_entry_safe_reverse(ce, cen, ocs-entries, node)
__of_changeset_entry_destroy(ce);
 }
+EXPORT_SYMBOL(of_changeset_destroy);
 
-/**
- * of_changeset_apply - Applies a changeset
- *
- * @ocs:   changeset pointer
- *
- * Applies a changeset to the live tree.
- * Any side-effects of live tree state changes are applied here on
- * sucess, like creation/destruction of devices and side-effects
- * like creation of sysfs properties and directories.
- * Returns 0 on success, a negative error value in case of an error.
- * On error the partially applied effects are reverted.
- */
-int of_changeset_apply(struct of_changeset *ocs)
+int __of_changeset_apply(struct of_changeset *ocs)
 {
struct of_changeset_entry *ce;
int ret;
@@ -704,17 +694,30 @@ int of_changeset_apply(struct of_changeset *ocs)
 }
 
 /**
- * of_changeset_revert - Reverts an applied changeset
+ * of_changeset_apply - Applies a changeset
  *
  * @ocs:   changeset pointer
  *
- * Reverts a changeset returning the state of the tree to what it
- * was before the application.
- * Any side-effects like creation/destruction of devices and
- * removal of sysfs properties and directories are applied.
+ * Applies a changeset to the live tree.
+ * Any side-effects of live tree state changes are applied here on
+ * sucess, like creation/destruction of devices and side-effects
+ * like creation of sysfs properties and directories.
  * Returns 0 on success, a negative error value in case of an error.
+ * On error the partially applied effects are reverted.
  */
-int of_changeset_revert(struct of_changeset *ocs)
+int of_changeset_apply(struct of_changeset *ocs)
+{
+   int ret;
+
+   mutex_lock(of_mutex);
+   ret = __of_changeset_apply(ocs);
+   mutex_unlock(of_mutex);
+
+   return ret;
+}
+EXPORT_SYMBOL(of_changeset_apply);
+
+int __of_changeset_revert(struct of_changeset *ocs)
 {
struct of_changeset_entry *ce;
int ret;
@@ -742,6 +745,29 @@ int of_changeset_revert(struct of_changeset *ocs)
 }
 
 /**
+ * of_changeset_revert - Reverts an applied changeset
+ *
+ * @ocs:   changeset pointer
+ *
+ * Reverts a changeset returning the state of the tree to what it
+ * was before the application.
+ * Any side-effects like creation/destruction of devices and
+ * removal of sysfs properties and directories are applied.
+ * Returns 0 on success, a negative error value in case of an error.
+ */
+int of_changeset_revert(struct of_changeset *ocs)
+{
+   int ret;
+
+   mutex_lock(of_mutex);
+   ret = __of_changeset_revert(ocs);
+   mutex_unlock(of_mutex);
+
+   return ret;
+}
+EXPORT_SYMBOL(of_changeset_revert);
+
+/**
  * of_changeset_action - Perform a changeset action
  *
  * @ocs:   changeset pointer
@@ -779,3 +805,4 @@ int of_changeset_action(struct of_changeset *ocs, unsigned 
long action,
list_add_tail(ce-node, ocs-entries);
return 0;
 }
+EXPORT_SYMBOL(of_changeset_action);
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index 24e025f..804ea33 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -378,9 +378,9 @@ int of_overlay_create(struct device_node *tree)
}
 
/* apply the changeset */
-   err = of_changeset_apply(ov-cset);
+   err = __of_changeset_apply(ov-cset);
if (err) {
-   pr_err(%s: of_changeset_apply() failed for tree@%s\n,
+   pr_err(%s: __of_changeset_apply() failed for tree@%s\n,
__func__, tree-full_name);
goto err_revert_overlay;
}
@@ -508,7 +508,7 @@ int of_overlay_destroy(int id)
 
 
list_del(ov-node);
-   of_changeset_revert(ov-cset);
+   __of_changeset_revert(ov-cset);
of_free_overlay_info(ov);
idr_remove(ov_idr, id);
of_changeset_destroy(ov-cset);
@@ -539,7 +539,7 @@ int of_overlay_destroy_all(void)
/* the tail of list is guaranteed to be safe to remove */
list_for_each_entry_safe_reverse(ov, ovn, ov_list, node) {
list_del(ov-node);
-  

Re: [PATCH V2 5/6] powerpc/powernv: boundary the total vf bar size instead of the individual one

2015-08-05 Thread Gavin Shan
On Wed, Aug 05, 2015 at 09:25:02AM +0800, Wei Yang wrote:
Each VF could have 6 BARs at most. When the total BAR size exceeds the
gate, after expanding it will also exhaust the M64 Window.

This patch limits the boundary by checking the total VF BAR size instead of
the individual BAR.

Signed-off-by: Wei Yang weiy...@linux.vnet.ibm.com

Ok. I didn't look at this when giving comments to last patch. It turns
you have the change in this patch. Please merge it with the previous
patch.

---
 arch/powerpc/platforms/powernv/pci-ioda.c |   13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 31dcedc..4042303 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -2702,7 +2702,7 @@ static void pnv_pci_ioda_fixup_iov_resources(struct 
pci_dev *pdev)
   struct pnv_phb *phb;
   struct resource *res;
   int i;
-  resource_size_t size, gate;
+  resource_size_t size, gate, total_vf_bar_sz;
   struct pci_dn *pdn;
   int mul, total_vfs;

@@ -2729,6 +2729,7 @@ static void pnv_pci_ioda_fixup_iov_resources(struct 
pci_dev *pdev)
* Window and limit the system flexibility.
*/
   gate = phb-ioda.m64_segsize  1;
+  total_vf_bar_sz = 0;

   for (i = 0; i  PCI_SRIOV_NUM_BARS; i++) {
   res = pdev-resource[i + PCI_IOV_RESOURCES];
@@ -2741,13 +2742,13 @@ static void pnv_pci_ioda_fixup_iov_resources(struct 
pci_dev *pdev)
   return;
   }

-  size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
+  total_vf_bar_sz += pci_iov_resource_size(pdev,
+  i + PCI_IOV_RESOURCES);

   /* bigger than or equal to gate */
-  if (size = gate) {
-  dev_info(pdev-dev, PowerNV: VF BAR%d: %pR IOV size 
-  is bigger than %lld, roundup power2\n,
-   i, res, gate);
+  if (total_vf_bar_sz = gate) {
+  dev_info(pdev-dev, PowerNV: VF BAR Total IOV size 
+  is bigger than %lld, roundup power2\n, gate);
   mul = roundup_pow_of_two(total_vfs);
   pdn-m64_single_mode = true;
   break;
-- 
1.7.9.5


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH V2 6/6] powerpc/powernv: allocate discrete PE# when using M64 BAR in Single PE mode

2015-08-05 Thread Gavin Shan
On Wed, Aug 05, 2015 at 09:25:03AM +0800, Wei Yang wrote:
When M64 BAR is set to Single PE mode, the PE# assigned to VF could be
discrete.

This patch restructures the patch to allocate discrete PE# for VFs when M64
BAR is set to Single PE mode.

Signed-off-by: Wei Yang weiy...@linux.vnet.ibm.com
---
 arch/powerpc/include/asm/pci-bridge.h |2 +-
 arch/powerpc/platforms/powernv/pci-ioda.c |   69 +
 2 files changed, 51 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/include/asm/pci-bridge.h 
b/arch/powerpc/include/asm/pci-bridge.h
index 8aeba4c..72415c7 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -213,7 +213,7 @@ struct pci_dn {
 #ifdef CONFIG_PCI_IOV
   u16 vfs_expanded;   /* number of VFs IOV BAR expanded */
   u16 num_vfs;/* number of VFs enabled*/
-  int offset; /* PE# for the first VF PE */
+  int *offset;/* PE# for the first VF PE or array */
   boolm64_single_mode;/* Use M64 BAR in Single Mode */
 #define IODA_INVALID_M64(-1)
   int (*m64_map)[PCI_SRIOV_NUM_BARS];

how about renaming offset to pe_num_map, or pe_map ? Similar to the 
comments
I gave to the m64_bar_map, num_of_max_vfs entries can be allocated. Though not
all of them will be used, not too much memory will be wasted.

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 4042303..9953829 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1243,7 +1243,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, 
u16 num_vfs)

   /* Map the M64 here */
   if (pdn-m64_single_mode) {
-  pe_num = pdn-offset + j;
+  pe_num = pdn-offset[j];
   rc = opal_pci_map_pe_mmio_window(phb-opal_id,
   pe_num, OPAL_M64_WINDOW_TYPE,
   pdn-m64_map[j][i], 0);
@@ -1347,7 +1347,7 @@ void pnv_pci_sriov_disable(struct pci_dev *pdev)
   struct pnv_phb*phb;
   struct pci_dn *pdn;
   struct pci_sriov  *iov;
-  u16 num_vfs;
+  u16num_vfs, i;

   bus = pdev-bus;
   hose = pci_bus_to_host(bus);
@@ -1361,14 +1361,18 @@ void pnv_pci_sriov_disable(struct pci_dev *pdev)

   if (phb-type == PNV_PHB_IODA2) {
   if (!pdn-m64_single_mode)
-  pnv_pci_vf_resource_shift(pdev, -pdn-offset);
+  pnv_pci_vf_resource_shift(pdev, -*pdn-offset);

   /* Release M64 windows */
   pnv_pci_vf_release_m64(pdev, num_vfs);

   /* Release PE numbers */
-  bitmap_clear(phb-ioda.pe_alloc, pdn-offset, num_vfs);
-  pdn-offset = 0;
+  if (pdn-m64_single_mode) {
+  for (i = 0; i  num_vfs; i++)
+  pnv_ioda_free_pe(phb, pdn-offset[i]);
+  } else
+  bitmap_clear(phb-ioda.pe_alloc, *pdn-offset, num_vfs);
+  kfree(pdn-offset);

Can pnv_ioda_free_pe() be reused to release PE ?

   }
 }

@@ -1394,7 +1398,10 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, 
u16 num_vfs)

   /* Reserve PE for each VF */
   for (vf_index = 0; vf_index  num_vfs; vf_index++) {
-  pe_num = pdn-offset + vf_index;
+  if (pdn-m64_single_mode)
+  pe_num = pdn-offset[vf_index];
+  else
+  pe_num = *pdn-offset + vf_index;

   pe = phb-ioda.pe_array[pe_num];
   pe-pe_number = pe_num;
@@ -1436,6 +1443,7 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 
num_vfs)
   struct pnv_phb*phb;
   struct pci_dn *pdn;
   intret;
+  u16i;

   bus = pdev-bus;
   hose = pci_bus_to_host(bus);
@@ -1462,19 +1470,38 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 
num_vfs)
   }

   /* Calculate available PE for required VFs */
-  mutex_lock(phb-ioda.pe_alloc_mutex);
-  pdn-offset = bitmap_find_next_zero_area(
-  phb-ioda.pe_alloc, phb-ioda.total_pe,
-  0, num_vfs, 0);
-  if (pdn-offset = phb-ioda.total_pe) {
+  if (pdn-m64_single_mode) {
+  pdn-offset = kmalloc(sizeof(*pdn-offset) * num_vfs,
+  GFP_KERNEL);
+  if (!pdn-offset)
+  return -ENOMEM;
+  for (i = 0; i  num_vfs; i++)
+  pdn-offset[i] = IODA_INVALID_PE;
+  for (i = 0; i  num_vfs; i++) {
+

[PATCH v6 08/42] powerpc/powernv: Calculate PHB's DMA weight dynamically

2015-08-05 Thread Gavin Shan
For P7IOC, the whole available DMA32 space, which is below the
MEM32 space, is divided evenly into 256MB segments. The number
of continuous segments assigned to one particular PE depends on
the PE's DMA weight that is calculated based on the type of each
PCI devices contained in the PE, and PHB's DMA weight which is
accumulative DMA weight of PEs contained in the PHB. It means
that the PHB's DMA weight calculation depends on existing PEs,
which works perfectly now, but not hotplug friendly. As the
whole available DMA32 space can be assigned to one PE on PHB3,
so we don't have the issue on PHB3.

The patch calculates PHB's DMA weight based on the PCI devices
contained in the PHB dynamically so that it's hotplug friendly.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/pci-ioda.c | 88 +++
 arch/powerpc/platforms/powernv/pci.h  |  6 ---
 2 files changed, 43 insertions(+), 51 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 713f4b4..7342cfd 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -927,6 +927,9 @@ static void pnv_ioda_link_pe_by_weight(struct pnv_phb *phb,
 
 static unsigned int pnv_ioda_dma_weight(struct pci_dev *dev)
 {
+   struct pci_controller *hose = pci_bus_to_host(dev-bus);
+   struct pnv_phb *phb = hose-private_data;
+
/* This is quite simplistic. The base weight of a device
 * is 10. 0 means no DMA is to be accounted for it.
 */
@@ -939,14 +942,34 @@ static unsigned int pnv_ioda_dma_weight(struct pci_dev 
*dev)
if (dev-class == PCI_CLASS_SERIAL_USB_UHCI ||
dev-class == PCI_CLASS_SERIAL_USB_OHCI ||
dev-class == PCI_CLASS_SERIAL_USB_EHCI)
-   return 3;
+   return 3 * phb-ioda.tce32_count;
 
/* Increase the weight of RAID (includes Obsidian) */
if ((dev-class  8) == PCI_CLASS_STORAGE_RAID)
-   return 15;
+   return 15 * phb-ioda.tce32_count;
 
/* Default */
-   return 10;
+   return 10 * phb-ioda.tce32_count;
+}
+
+static int __pnv_ioda_phb_dma_weight(struct pci_dev *pdev, void *data)
+{
+   unsigned int *dma_weight = data;
+
+   *dma_weight += pnv_ioda_dma_weight(pdev);
+   return 0;
+}
+
+static unsigned int pnv_ioda_phb_dma_weight(struct pnv_phb *phb)
+{
+   unsigned int dma_weight = 0;
+
+   if (!phb-hose-bus)
+   return 0;
+
+   pci_walk_bus(phb-hose-bus,
+__pnv_ioda_phb_dma_weight, dma_weight);
+   return dma_weight;
 }
 
 #ifdef CONFIG_PCI_IOV
@@ -1097,14 +1120,6 @@ static void pnv_ioda_setup_bus_PE(struct pci_bus *bus, 
bool all)
/* Put PE to the list */
list_add_tail(pe-list, phb-ioda.pe_list);
 
-   /* Account for one DMA PE if at least one DMA capable device exist
-* below the bridge
-*/
-   if (pe-dma_weight != 0) {
-   phb-ioda.dma_weight += pe-dma_weight;
-   phb-ioda.dma_pe_count++;
-   }
-
/* Link the PE */
pnv_ioda_link_pe_by_weight(phb, pe);
 }
@@ -2431,24 +2446,13 @@ static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb 
*phb,
 static void pnv_ioda_setup_dma(struct pnv_phb *phb)
 {
struct pci_controller *hose = phb-hose;
-   unsigned int residual, remaining, segs, tw, base;
struct pnv_ioda_pe *pe;
+   unsigned int dma_weight;
 
-   /* If we have more PE# than segments available, hand out one
-* per PE until we run out and let the rest fail. If not,
-* then we assign at least one segment per PE, plus more based
-* on the amount of devices under that PE
-*/
-   if (phb-ioda.dma_pe_count  phb-ioda.tce32_count)
-   residual = 0;
-   else
-   residual = phb-ioda.tce32_count -
-   phb-ioda.dma_pe_count;
-
-   pr_info(PCI: Domain %04x has %ld available 32-bit DMA segments\n,
-   hose-global_number, phb-ioda.tce32_count);
-   pr_info(PCI: %d PE# for a total weight of %d\n,
-   phb-ioda.dma_pe_count, phb-ioda.dma_weight);
+   /* Calculate the PHB's DMA weight */
+   dma_weight = pnv_ioda_phb_dma_weight(phb);
+   pr_info(PCI%04x has %ld DMA32 segments, total weight %d\n,
+   hose-global_number, phb-ioda.tce32_count, dma_weight);
 
pnv_pci_ioda_setup_opal_tce_kill(phb);
 
@@ -2456,22 +2460,9 @@ static void pnv_ioda_setup_dma(struct pnv_phb *phb)
 * out one base segment plus any residual segments based on
 * weight
 */
-   remaining = phb-ioda.tce32_count;
-   tw = phb-ioda.dma_weight;
-   base = 0;
list_for_each_entry(pe, phb-ioda.pe_dma_list, dma_link) {
if (!pe-dma_weight)
continue;
-   if (!remaining) {
-   pe_warn(pe, 

[PATCH v6 03/42] powerpc/powernv: Enable M64 on P7IOC

2015-08-05 Thread Gavin Shan
The patch enables M64 window on P7IOC, which has been enabled on
PHB3. Different from PHB3 where 16 M64 BARs are supported and each
of them can be owned by one particular PE# exclusively or divided
evenly to 256 segments, each P7IOC PHB has 16 M64 BARs and each
of them are divided into 8 segments. So each P7IOC PHB can support
128 M64 segments only. Also, P7IOC has M64DT, which helps mapping
one particular M64 segment# to arbitrary PE#. PHB3 doesn't have
M64DT, indicating that one M64 segment can only be pinned to the
fixed PE#. In order to have similar logic to support M64 for PHB3
and P7IOC, we just provide 128 M64 (16 BARs) segments and fixed
mapping between PE# and M64 segment# on P7IOC. In turn, we just
need different phb-init_m64() hooks for P7IOC and PHB3 to support
M64.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/pci-ioda.c | 116 ++
 1 file changed, 104 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 38b5405..e4ac703 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -172,6 +172,69 @@ static void pnv_ioda_free_pe(struct pnv_phb *phb, int pe)
clear_bit(pe, phb-ioda.pe_alloc);
 }
 
+static int pnv_ioda1_init_m64(struct pnv_phb *phb)
+{
+   struct resource *r;
+   int seg;
+
+   /* There are as many M64 segments as the maximum number
+* of PEs, which is 128.
+*/
+   for (seg = 0; seg  phb-ioda.total_pe; seg += 8) {
+   unsigned long base;
+   int64_t rc;
+
+   base = phb-ioda.m64_base + seg * phb-ioda.m64_segsize;
+   rc = opal_pci_set_phb_mem_window(phb-opal_id,
+OPAL_M64_WINDOW_TYPE,
+seg / 8,
+base,
+0, /* unused */
+8 * phb-ioda.m64_segsize);
+   if (rc != OPAL_SUCCESS) {
+   pr_warn(  Error %lld setting M64 PHB#%d-BAR#%d\n,
+   rc, phb-hose-global_number, seg / 8);
+   goto fail;
+   }
+
+   rc = opal_pci_phb_mmio_enable(phb-opal_id,
+ OPAL_M64_WINDOW_TYPE,
+ seg / 8,
+ OPAL_ENABLE_M64_SPLIT);
+   if (rc != OPAL_SUCCESS) {
+   pr_warn(  Error %lld enabling M64 PHB#%d-BAR#%d\n,
+   rc, phb-hose-global_number, seg / 8);
+   goto fail;
+   }
+   }
+
+   /* Strip off the segment used by the reserved PE, which
+* is expected to be 0 or last supported PE#. The PHB's
+* first memory window traces the 32-bits MMIO range
+* while the second one traces the 64-bits prefetchable
+* MMIO range that the PHB supports.
+*/
+   r = phb-hose-mem_resources[1];
+   if (phb-ioda.reserved_pe == 0)
+   r-start += phb-ioda.m64_segsize;
+   else if (phb-ioda.reserved_pe == (phb-ioda.total_pe - 1))
+   r-end -= phb-ioda.m64_segsize;
+   else
+   pr_warn(  Cannot strip M64 segment for reserved PE#%d\n,
+   phb-ioda.reserved_pe);
+
+   return 0;
+
+fail:
+   for ( ; seg = 0; seg -= 8)
+   opal_pci_phb_mmio_enable(phb-opal_id,
+OPAL_M64_WINDOW_TYPE,
+seg / 8,
+OPAL_DISABLE_M64);
+
+   return -EIO;
+}
+
 /* The default M64 BAR is shared by all PEs */
 static int pnv_ioda2_init_m64(struct pnv_phb *phb)
 {
@@ -256,9 +319,9 @@ static void pnv_ioda2_reserve_dev_m64_pe(struct pci_dev 
*pdev,
}
 }
 
-static void pnv_ioda2_reserve_m64_pe(struct pci_bus *bus,
-unsigned long *pe_bitmap,
-bool all)
+static void pnv_ioda_reserve_m64_pe(struct pci_bus *bus,
+   unsigned long *pe_bitmap,
+   bool all)
 {
struct pci_dev *pdev;
 
@@ -266,12 +329,12 @@ static void pnv_ioda2_reserve_m64_pe(struct pci_bus *bus,
pnv_ioda2_reserve_dev_m64_pe(pdev, pe_bitmap);
 
if (all  pdev-subordinate)
-   pnv_ioda2_reserve_m64_pe(pdev-subordinate,
-pe_bitmap, all);
+   pnv_ioda_reserve_m64_pe(pdev-subordinate,
+   pe_bitmap, all);
}
 }
 
-static int pnv_ioda2_pick_m64_pe(struct pci_bus *bus, bool all)
+static int 

[PATCH v6 31/42] powerpc/pci: Rename pcibios_{add, remove}_pci_devices

2015-08-05 Thread Gavin Shan
This renames pcibios_{add,remove}_pci_devices to avoid conflicts
with names of weak functions in PCI subsystem. This doesn't
introduce logicial changes.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/include/asm/pci-bridge.h |  4 ++--
 arch/powerpc/kernel/eeh_driver.c  | 12 ++--
 arch/powerpc/kernel/pci-hotplug.c | 15 +++
 drivers/pci/hotplug/rpadlpar_core.c   |  2 +-
 drivers/pci/hotplug/rpaphp_core.c |  4 ++--
 drivers/pci/hotplug/rpaphp_pci.c  |  2 +-
 6 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/include/asm/pci-bridge.h 
b/arch/powerpc/include/asm/pci-bridge.h
index 84dee1e..787a879 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -262,10 +262,10 @@ static inline struct eeh_dev *pdn_to_eeh_dev(struct 
pci_dn *pdn)
 extern struct pci_bus *of_node_to_pci_bus(struct device_node *dn);
 
 /** Remove all of the PCI devices under this bus */
-extern void pcibios_remove_pci_devices(struct pci_bus *bus);
+extern void pci_remove_pci_devices(struct pci_bus *bus);
 
 /** Discover new pci devices under this bus, and add them */
-extern void pcibios_add_pci_devices(struct pci_bus *bus);
+extern void pci_add_pci_devices(struct pci_bus *bus);
 
 
 extern void isa_bridge_find_early(struct pci_controller *hose);
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index 99868e2..290a9df 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -600,7 +600,7 @@ static int eeh_reset_device(struct eeh_pe *pe, struct 
pci_bus *bus)
 * We don't remove the corresponding PE instances because
 * we need the information afterwords. The attached EEH
 * devices are expected to be attached soon when calling
-* into pcibios_add_pci_devices().
+* into pci_add_pci_devices().
 */
eeh_pe_state_mark(pe, EEH_PE_KEEP);
if (bus) {
@@ -608,7 +608,7 @@ static int eeh_reset_device(struct eeh_pe *pe, struct 
pci_bus *bus)
eeh_pe_dev_traverse(pe, eeh_rmv_device, NULL);
else {
pci_lock_rescan_remove();
-   pcibios_remove_pci_devices(bus);
+   pci_remove_pci_devices(bus);
pci_unlock_rescan_remove();
}
} else if (frozen_bus)
@@ -658,7 +658,7 @@ static int eeh_reset_device(struct eeh_pe *pe, struct 
pci_bus *bus)
if (pe-type  EEH_PE_VF)
eeh_add_virt_device(edev, NULL);
else
-   pcibios_add_pci_devices(bus);
+   pci_add_pci_devices(bus);
} else if (frozen_bus  removed) {
pr_info(EEH: Sleep 5s ahead of partial hotplug\n);
ssleep(5);
@@ -668,7 +668,7 @@ static int eeh_reset_device(struct eeh_pe *pe, struct 
pci_bus *bus)
if (pe-type  EEH_PE_VF)
eeh_add_virt_device(edev, NULL);
else
-   pcibios_add_pci_devices(frozen_bus);
+   pci_add_pci_devices(frozen_bus);
}
eeh_pe_state_clear(pe, EEH_PE_KEEP);
 
@@ -852,7 +852,7 @@ perm_error:
} else {
eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED);
pci_lock_rescan_remove();
-   pcibios_remove_pci_devices(frozen_bus);
+   pci_remove_pci_devices(frozen_bus);
pci_unlock_rescan_remove();
}
}
@@ -936,7 +936,7 @@ static void eeh_handle_special_event(void)
bus = eeh_pe_bus_get(phb_pe);
eeh_pe_dev_traverse(pe,
eeh_report_failure, NULL);
-   pcibios_remove_pci_devices(bus);
+   pci_remove_pci_devices(bus);
}
pci_unlock_rescan_remove();
}
diff --git a/arch/powerpc/kernel/pci-hotplug.c 
b/arch/powerpc/kernel/pci-hotplug.c
index 692beca..00f193b 100644
--- a/arch/powerpc/kernel/pci-hotplug.c
+++ b/arch/powerpc/kernel/pci-hotplug.c
@@ -68,20 +68,20 @@ void pcibios_release_device(struct pci_dev *dev)
 }
 
 /**
- * pcibios_remove_pci_devices - remove all devices under this bus
+ * pci_remove_pci_devices - remove all devices under this bus
  * @bus: the indicated PCI bus
  *
  * Remove all of the PCI devices under this bus both from the
  * linux pci device tree, and from the powerpc EEH address cache.
  */
-void pcibios_remove_pci_devices(struct pci_bus *bus)
+void pci_remove_pci_devices(struct pci_bus *bus)
 {
struct pci_dev *dev, *tmp;
struct pci_bus *child_bus;
 
/* First go down child busses */
list_for_each_entry(child_bus, bus-children, node)
-   

[PATCH v6 17/42] powerpc/powernv: Rename PE# fields in PHB

2015-08-05 Thread Gavin Shan
This renames the fields related to PE# in struct pnv_phb for
better reflecting of their usages as Alexey suggested. It doesn't
introduce behavioural changes.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/eeh-powernv.c |  2 +-
 arch/powerpc/platforms/powernv/pci-ioda.c| 58 ++--
 arch/powerpc/platforms/powernv/pci.c |  2 +-
 arch/powerpc/platforms/powernv/pci.h |  4 +-
 4 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c 
b/arch/powerpc/platforms/powernv/eeh-powernv.c
index e5e0d0b..347b1cf 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -81,7 +81,7 @@ static int pnv_eeh_init(void)
 * and P7IOC separately. So we should regard
 * PE#0 as valid for P7IOC.
 */
-   if (phb-ioda.reserved_pe != 0)
+   if (phb-ioda.reserved_pe_idx != 0)
eeh_add_flag(EEH_VALID_PE_ZERO);
 
break;
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 9cccf2d5..56b058c 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -145,7 +145,7 @@ static struct pnv_ioda_pe *pnv_ioda_init_pe(struct pnv_phb 
*phb, int pe_no)
 
 static struct pnv_ioda_pe *pnv_ioda_reserve_pe(struct pnv_phb *phb, int pe_no)
 {
-   if (!(pe_no = 0  pe_no  phb-ioda.total_pe)) {
+   if (!(pe_no = 0  pe_no  phb-ioda.total_pe_num)) {
pr_warn(%s: Invalid PE %d on PHB#%x\n,
__func__, pe_no, phb-hose-global_number);
return NULL;
@@ -164,8 +164,8 @@ static struct pnv_ioda_pe *pnv_ioda_alloc_pe(struct pnv_phb 
*phb)
 
do {
pe = find_next_zero_bit(phb-ioda.pe_alloc,
-   phb-ioda.total_pe, 0);
-   if (pe = phb-ioda.total_pe)
+   phb-ioda.total_pe_num, 0);
+   if (pe = phb-ioda.total_pe_num)
return NULL;
} while(test_and_set_bit(pe, phb-ioda.pe_alloc));
 
@@ -188,7 +188,7 @@ static int pnv_ioda1_init_m64(struct pnv_phb *phb)
/* There are as many M64 segments as the maximum number
 * of PEs, which is 128.
 */
-   for (seg = 0; seg  phb-ioda.total_pe; seg += 8) {
+   for (seg = 0; seg  phb-ioda.total_pe_num; seg += 8) {
unsigned long base;
int64_t rc;
 
@@ -223,13 +223,13 @@ static int pnv_ioda1_init_m64(struct pnv_phb *phb)
 * MMIO range that the PHB supports.
 */
r = phb-hose-mem_resources[1];
-   if (phb-ioda.reserved_pe == 0)
+   if (phb-ioda.reserved_pe_idx == 0)
r-start += phb-ioda.m64_segsize;
-   else if (phb-ioda.reserved_pe == (phb-ioda.total_pe - 1))
+   else if (phb-ioda.reserved_pe_idx == (phb-ioda.total_pe_num - 1))
r-end -= phb-ioda.m64_segsize;
else
pr_warn(  Cannot strip M64 segment for reserved PE#%d\n,
-   phb-ioda.reserved_pe);
+   phb-ioda.reserved_pe_idx);
 
return 0;
 
@@ -280,13 +280,13 @@ static int pnv_ioda2_init_m64(struct pnv_phb *phb)
 * expected to be 0 or last one of PE capabicity.
 */
r = phb-hose-mem_resources[1];
-   if (phb-ioda.reserved_pe == 0)
+   if (phb-ioda.reserved_pe_idx == 0)
r-start += phb-ioda.m64_segsize;
-   else if (phb-ioda.reserved_pe == (phb-ioda.total_pe - 1))
+   else if (phb-ioda.reserved_pe_idx == (phb-ioda.total_pe_num - 1))
r-end -= phb-ioda.m64_segsize;
else
pr_warn(  Cannot strip M64 segment for reserved PE#%d\n,
-   phb-ioda.reserved_pe);
+   phb-ioda.reserved_pe_idx);
 
return 0;
 
@@ -355,7 +355,7 @@ static struct pnv_ioda_pe *pnv_ioda_pick_m64_pe(struct 
pci_bus *bus, bool all)
return NULL;
 
/* Allocate bitmap */
-   size = _ALIGN_UP(phb-ioda.total_pe / 8, sizeof(unsigned long));
+   size = _ALIGN_UP(phb-ioda.total_pe_num / 8, sizeof(unsigned long));
pe_alloc = kzalloc(size, GFP_KERNEL);
if (!pe_alloc) {
pr_warn(%s: Out of memory !\n,
@@ -371,7 +371,7 @@ static struct pnv_ioda_pe *pnv_ioda_pick_m64_pe(struct 
pci_bus *bus, bool all)
 * contributed by its child buses. For the case, we needn't
 * pick M64 dependent PE#.
 */
-   if (bitmap_empty(pe_alloc, phb-ioda.total_pe)) {
+   if (bitmap_empty(pe_alloc, phb-ioda.total_pe_num)) {
kfree(pe_alloc);
return NULL;
}
@@ -382,8 +382,8 @@ static struct pnv_ioda_pe *pnv_ioda_pick_m64_pe(struct 
pci_bus *bus, bool all)
 */
master_pe = NULL;
i = 

Re: GPMC in device tree

2015-08-05 Thread Scott Wood
On Wed, 2015-08-05 at 17:27 +0300, Ran Shalit wrote:
 On Wed, Aug 5, 2015 at 9:11 AM, Ran Shalit ransha...@gmail.com wrote:
  On Wed, Aug 5, 2015 at 6:56 AM, Ran Shalit ransha...@gmail.com wrote:
   On Wed, Aug 5, 2015 at 12:25 AM, Scott Wood scottw...@freescale.com 
   wrote:
On Wed, 2015-08-05 at 00:22 +0300, Ran Shalit wrote:
 On more thing, if I may.
 The localbus is also connected to nvram  cpld.
 I've noticed that read/write works well, even though I didn't define
 anything in device tree.
 Is there any reasom to add these devices into device tree, or can we
 use the cpld and nvram without the definition in device tree ?

I don't know what you're doing in your kernel to access devices that 
aren't
in the device tree.  You should add the devices to the device tree, 
and have
the kernel use it rather than hardcoded info.

-Scott

   Hi,
   
   Yes I understand.
   But It is worse noting that I have no localbus entry in the device tree.
   Yes, The nvram, cpld which are both connected to device tree, seems to
   work without any issues.
   
   Thanks,
   Ran
  
  I apologyze for the bad english, I meant it worth to note that there
  is no localbus entry at all in the device tree.
  So I wander how the nvram and cpld worked...

I don't know how it worked -- presumably there's something in your kernel 
that hardcodes knowledge of those devices.

  If I may please ask, what should be the compatible for generic
  devices such as  nvram/cpld ?

CPLD is not a generic device.  The compatible should describe the logic that 
has been programmed into the CPLD.

  I assume that if they worked without any entry, it means that there is
  no need for specific driver.
  
  Regards,
  Ran
 
 Hi,
 
 After studing the localbus configuration as should be configured in
 device tree for powerpc, I think I have come with the following
 configuration, (not yet tested on board):
 
 
  localbus@e0005000{
 #address-cells = 2;
 #size-cells = 1;
 compatible = fsl,mpc8349-localbus, simple-bus;
  reg = 0xe0005000 0x1000;
  interrupts = 77 0x8;
  interrupt-parent = ipic;
 
 
 /* NOR and NAND Flashes */
ranges = 0x0 0x0 0xff80 0x0080 /* 8MB NOR Flash */
  0x1 0x0 0xF800 0x0800  /* User flash (same
 nor, in burst mode) 128M */
  0x2 0x0 0xf7e0 0x0020;/*NVRAM/CPLD C2 is
 selected in CPLD , */
 /*nvram 0xf7e0 1MB */
 /*cpld  0xf7f0 1M  (- different address!)*/
 nor@0,0 {
 #address-cells = 1;
 #size-cells = 1;
 compatible = cfi-flash;
 reg = 0x0 0x0 0x100;
 #bank-width = 1;
 device-width = 4;
 
 };
 };

Where are the nodes for cs1 and cs2?

Why does the node for cs0 have a reg length of 0x0100 when the ranges 
entry has a size of only 0x0080?

 I have some isssue I'm not sure about, and wanted a second opinion:
 
 1. I have not added entry for NVRAM/CPLD (8 bit width interfaces) ,
 but only specifies it in ranges , I assume it is not required becuase
 it is probably can be treated as simple ram. Is this assumption
 correct ?

No.  Even if it does work like simple ram (which is not what I'd expect for 
the cpld, especially since you describe nvram as being something separate), 
you need something to indicate that the ram is there, and what (if anything) 
its dedicated hardware purpose is.

 2. The NVRAM/CPLD  is using CS2 , which is configured for 2 MB space.
 The 2 MB is divided to two 1 MB slices. 1 MB is dedicated for NVRAM
 (though the NVRAM is only 128 KB) and 1 MB is dedicated for CPLD. The
 division of CS2 into two regions is done in CPLD.
 0xf7e0 - for NVRAM , 0x0010
 0xf7f0 - for CPLD ,  0x0010
 
 Is it correct to be configured as one range as done above  (0x2 0x0
 0xf7e0 0x0020)  ?

If they are both using the same chipselect then they should use the same 
ranges entry.

-Scott

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v6 12/42] powerpc/powernv: Increase PE# capacity

2015-08-05 Thread Gavin Shan
Each PHB maintains an array helping to translate RID (Request
ID) to PE# with the assumption that PE# takes 8 bits, indicating
that we can't have more than 256 PEs. However, pci_dn-pe_number
already had 4-bytes for the PE#.

The patch extends the PE# capacity so that each of them will be
4-bytes long. Then we can use IODA_INVALID_PE to check one entry
in phb-pe_rmap[] is valid or not.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/pci-ioda.c | 8 ++--
 arch/powerpc/platforms/powernv/pci.h  | 7 +++
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 57ba8fd..3094c61 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -786,7 +786,7 @@ static int pnv_ioda_deconfigure_pe(struct pnv_phb *phb, 
struct pnv_ioda_pe *pe)
 
/* Clear the reverse map */
for (rid = pe-rid; rid  rid_end; rid++)
-   phb-ioda.pe_rmap[rid] = 0;
+   phb-ioda.pe_rmap[rid] = IODA_INVALID_PE;
 
/* Release from all parents PELT-V */
while (parent) {
@@ -3134,7 +3134,7 @@ static void __init pnv_pci_init_ioda_phb(struct 
device_node *np,
unsigned long size, pemap_off;
const __be64 *prop64;
const __be32 *prop32;
-   int len;
+   int len, i;
u64 phb_id;
void *aux;
long rc;
@@ -3201,6 +3201,10 @@ static void __init pnv_pci_init_ioda_phb(struct 
device_node *np,
if (prop32)
phb-ioda.reserved_pe = be32_to_cpup(prop32);
 
+   /* Invalidate RID to PE# mapping */
+   for (i = 0; i  ARRAY_SIZE(phb-ioda.pe_rmap); ++i)
+   phb-ioda.pe_rmap[i] = IODA_INVALID_PE;
+
/* Parse 64-bit MMIO range */
pnv_ioda_parse_m64_window(phb);
 
diff --git a/arch/powerpc/platforms/powernv/pci.h 
b/arch/powerpc/platforms/powernv/pci.h
index 1dc9578..6f8568e 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -175,11 +175,10 @@ struct pnv_phb {
struct list_headpe_list;
struct mutexpe_list_mutex;
 
-   /* Reverse map of PEs, will have to extend if
-* we are to support more than 256 PEs, indexed
-* bus { bus, devfn }
+   /* Reverse map of PEs, indexed by
+* { bus, devfn }
 */
-   unsigned char   pe_rmap[0x1];
+   int pe_rmap[0x1];
 
/* 32-bit TCE tables allocation */
unsigned long   dma32_segcount;
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v6 21/42] powerpc/powernv: Remove DMA32 list of PEs

2015-08-05 Thread Gavin Shan
Every PHB maintains a list of PEs based on their DMA32 weight. After
patch powerpc/powernv: Create PEs dynamically, the list is useless
and it's safe to remove it.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/pci-ioda.c | 18 --
 arch/powerpc/platforms/powernv/pci.h  |  6 --
 2 files changed, 24 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 37847a3..84b771e 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -938,20 +938,6 @@ out:
return 0;
 }
 
-static void pnv_ioda_link_pe_by_weight(struct pnv_phb *phb,
-  struct pnv_ioda_pe *pe)
-{
-   struct pnv_ioda_pe *lpe;
-
-   list_for_each_entry(lpe, phb-ioda.pe_dma_list, dma_link) {
-   if (lpe-dma32_weight  pe-dma32_weight) {
-   list_add_tail(pe-dma_link, lpe-dma_link);
-   return;
-   }
-   }
-   list_add_tail(pe-dma_link, phb-ioda.pe_dma_list);
-}
-
 static unsigned int pnv_ioda_dma_weight(struct pci_dev *dev)
 {
struct pci_controller *hose = pci_bus_to_host(dev-bus);
@@ -1169,9 +1155,6 @@ static struct pnv_ioda_pe *pnv_ioda_setup_bus_PE(struct 
pci_bus *bus, bool all)
/* Put PE to the list */
list_add_tail(pe-list, phb-ioda.pe_list);
 
-   /* Link the PE */
-   pnv_ioda_link_pe_by_weight(phb, pe);
-
return pe;
 }
 
@@ -3313,7 +3296,6 @@ static void __init pnv_pci_init_ioda_phb(struct 
device_node *np,
phb-ioda.root_pe_idx = IODA_INVALID_PE;
}
 
-   INIT_LIST_HEAD(phb-ioda.pe_dma_list);
INIT_LIST_HEAD(phb-ioda.pe_list);
mutex_init(phb-ioda.pe_list_mutex);
 
diff --git a/arch/powerpc/platforms/powernv/pci.h 
b/arch/powerpc/platforms/powernv/pci.h
index a160491..f8e6022 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -83,7 +83,6 @@ struct pnv_ioda_pe {
struct list_headslaves;
 
/* Link in list of PE#s */
-   struct list_headdma_link;
struct list_headlist;
 };
 
@@ -185,11 +184,6 @@ struct pnv_phb {
/* 32-bit TCE tables allocation */
unsigned long   dma32_segcount;
 
-   /* Sorted list of used PE's, sorted at
-* boot for resource allocation purposes
-*/
-   struct list_headpe_dma_list;
-
/* TCE cache invalidate registers (physical and
 * remapped)
 */
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v6 37/42] powerpc/powernv: Select OF_DYNAMIC

2015-08-05 Thread Gavin Shan
The device tree nodes will be changed dynamically on PCI hotplug
events on PowerNV platform. This enables CONFIG_OF_DYNAMIC on
PowerNV platform to support that.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/platforms/powernv/Kconfig 
b/arch/powerpc/platforms/powernv/Kconfig
index 604190c..e7b1ad7 100644
--- a/arch/powerpc/platforms/powernv/Kconfig
+++ b/arch/powerpc/platforms/powernv/Kconfig
@@ -18,6 +18,7 @@ config PPC_POWERNV
select CPU_FREQ_GOV_ONDEMAND
select CPU_FREQ_GOV_CONSERVATIVE
select PPC_DOORBELL
+   select OF_DYNAMIC
default y
 
 config OPAL_PRD
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v6 26/42] powerpc/powernv: Simplify pnv_eeh_reset()

2015-08-05 Thread Gavin Shan
This simplifies pnv_eeh_reset() by avoiding the unnecessary nested
if statement. No logicial changes introduced by this.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/eeh-powernv.c | 65 +---
 1 file changed, 31 insertions(+), 34 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c 
b/arch/powerpc/platforms/powernv/eeh-powernv.c
index 7be2ebf..95332e9 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -1086,7 +1086,9 @@ void pnv_pci_reset_secondary_bus(struct pci_dev *dev)
 static int pnv_eeh_reset(struct eeh_pe *pe, int option)
 {
struct pci_controller *hose = pe-phb;
+   struct pnv_phb *phb = hose-private_data;
struct pci_bus *bus;
+   int64_t rc;
int ret;
 
/*
@@ -1103,44 +1105,39 @@ static int pnv_eeh_reset(struct eeh_pe *pe, int option)
 * reset. The side effect is that EEH core has to clear the frozen
 * state explicitly after BAR restore.
 */
-   if (pe-type  EEH_PE_PHB) {
-   ret = pnv_eeh_phb_reset(hose, option);
-   } else {
-   struct pnv_phb *phb;
-   s64 rc;
+   if (pe-type  EEH_PE_PHB)
+   return pnv_eeh_phb_reset(hose, option);
 
-   /*
-* The frozen PE might be caused by PAPR error injection
-* registers, which are expected to be cleared after hitting
-* frozen PE as stated in the hardware spec. Unfortunately,
-* that's not true on P7IOC. So we have to clear it manually
-* to avoid recursive EEH errors during recovery.
-*/
-   phb = hose-private_data;
-   if (phb-model == PNV_PHB_MODEL_P7IOC 
-   (option == EEH_RESET_HOT ||
-   option == EEH_RESET_FUNDAMENTAL)) {
-   rc = opal_pci_reset(phb-opal_id,
-   OPAL_RESET_PHB_ERROR,
-   OPAL_ASSERT_RESET);
-   if (rc != OPAL_SUCCESS) {
-   pr_warn(%s: Failure %lld clearing 
-   error injection registers\n,
-   __func__, rc);
-   return -EIO;
-   }
+   /*
+* The frozen PE might be caused by PAPR error injection
+* registers, which are expected to be cleared after hitting
+* frozen PE as stated in the hardware spec. Unfortunately,
+* that's not true on P7IOC. So we have to clear it manually
+* to avoid recursive EEH errors during recovery.
+*/
+   phb = hose-private_data;
+   if (phb-model == PNV_PHB_MODEL_P7IOC 
+   (option == EEH_RESET_HOT ||
+   option == EEH_RESET_FUNDAMENTAL)) {
+   rc = opal_pci_reset(phb-opal_id,
+   OPAL_RESET_PHB_ERROR,
+   OPAL_ASSERT_RESET);
+   if (rc != OPAL_SUCCESS) {
+   pr_warn(%s: Error %lld clearing errinjct registers\n,
+   __func__, rc);
+   return -EIO;
}
-
-   bus = eeh_pe_bus_get(pe);
-   if (pe-type  EEH_PE_VF)
-   ret = pnv_eeh_vf_pe_reset(pe, option);
-   else if (pci_is_root_bus(bus) ||
-   pci_is_root_bus(bus-parent))
-   ret = pnv_eeh_root_reset(hose, option);
-   else
-   ret = pnv_eeh_bridge_reset(bus-self, option);
}
 
+   bus = eeh_pe_bus_get(pe);
+   if (pe-type  EEH_PE_VF)
+   ret = pnv_eeh_vf_pe_reset(pe, option);
+   else if (pci_is_root_bus(bus) ||
+pci_is_root_bus(bus-parent))
+   ret = pnv_eeh_root_reset(hose, option);
+   else
+   ret = pnv_eeh_bridge_reset(bus-self, option);
+
return ret;
 }
 
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v6 29/42] powerpc/pci: Don't scan empty slot

2015-08-05 Thread Gavin Shan
In hotplug case, function pcibios_add_pci_devices() is called to
rescan the specified PCI bus, which might not have any child devices.
Access to the PCI bus's child device node will cause kernel crash
without exception.

This adds condition of skipping scanning PCI bus without child devices
in order to avoid kernel crash.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/kernel/pci-hotplug.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/pci-hotplug.c 
b/arch/powerpc/kernel/pci-hotplug.c
index 59c4361..c307d9a 100644
--- a/arch/powerpc/kernel/pci-hotplug.c
+++ b/arch/powerpc/kernel/pci-hotplug.c
@@ -92,7 +92,8 @@ void pcibios_add_pci_devices(struct pci_bus * bus)
if (mode == PCI_PROBE_DEVTREE) {
/* use ofdt-based probe */
of_rescan_bus(dn, bus);
-   } else if (mode == PCI_PROBE_NORMAL) {
+   } else if (mode == PCI_PROBE_NORMAL 
+  dn-child  PCI_DN(dn-child)) {
/*
 * Use legacy probe. In the partial hotplug case, we
 * probably have grandchildren devices unplugged. So
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH V2 4/6] powerpc/powernv: replace the hard coded boundary with gate

2015-08-05 Thread Gavin Shan
On Wed, Aug 05, 2015 at 09:25:01AM +0800, Wei Yang wrote:
Based on the limitation of M64 Window size, when VF BAR size is bigger than
64MB, IOV BAR just round up power of 2 of the total_vfs. While the 64MB is
a magic boundary in code, which is hard to maintain.

This patch replaces the hard coded boundary with gate, which is calculated
from m64_segsize and adds comment to explain the reason for it.

Signed-off-by: Wei Yang weiy...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/pci-ioda.c |   22 +-
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index f5d110c..31dcedc 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -2702,7 +2702,7 @@ static void pnv_pci_ioda_fixup_iov_resources(struct 
pci_dev *pdev)
   struct pnv_phb *phb;
   struct resource *res;
   int i;
-  resource_size_t size;
+  resource_size_t size, gate;
   struct pci_dn *pdn;
   int mul, total_vfs;

@@ -2718,6 +2718,17 @@ static void pnv_pci_ioda_fixup_iov_resources(struct 
pci_dev *pdev)

   total_vfs = pci_sriov_get_totalvfs(pdev);
   mul = phb-ioda.total_pe;
+  /*
+   * If bigger than or equal to half of m64_segsize, just round up power
+   * of two.
+   *
+   * Generally, one M64 BAR maps one IOV BAR. To avoid conflict with
+   * other devices, IOV BAR size is expanded to be (total_pe * VF size).
+   * When VF size is half of m64_segsize , the expanded size would equal
+   * to half of the whole M64 Window size, which will exhaust the M64
+   * Window and limit the system flexibility.
+   */

s/VF size/VF BAR size
s/m64_segsize/M64 segment size
s/M64 Window/M64 space

+  gate = phb-ioda.m64_segsize  1;

   for (i = 0; i  PCI_SRIOV_NUM_BARS; i++) {
   res = pdev-resource[i + PCI_IOV_RESOURCES];
@@ -2732,10 +2743,11 @@ static void pnv_pci_ioda_fixup_iov_resources(struct 
pci_dev *pdev)

   size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);

-  /* bigger than 64M */
-  if (size  (1  26)) {
-  dev_info(pdev-dev, PowerNV: VF BAR%d: %pR IOV size 
is bigger than 64M, roundup power2\n,
-   i, res);
+  /* bigger than or equal to gate */
+  if (size = gate) {
+  dev_info(pdev-dev, PowerNV: VF BAR%d: %pR IOV size 
+  is bigger than %lld, roundup power2\n,
+   i, res, gate);

If I understand the changes correctly, single VF BAR size is still checked 
against
the gate (128MB), not the total VF BAR size. Recap the comments I gave last 
time:

I mean to check the sum of all VF BARs. For example, the VFs attached to its PF 
has two
VF BARs and each of them is 64MB. For this case, the MMIO resource can't be 
allocated
once extending them to 256 VFs. So we have to try single-pe-mode for this 
situation.
So the check becomes as below:

struct pci_controller *hose = pci_bus_to_host(pdev-bus);
struct pnv_phb *phb = hose-private_data;
resource_size_t total_vf_bar_sz = 0;
resource_size_t gate;

/* Some comments to explain the gate */
gate = phb-m64_segsize / 2;
for (i = 0; i  PCI_SRIOV_NUM_BARS; i++) {
total_vf_bar_sz += pci_iov_resource_size(pdev, 
PCI_IOV_RESOURCES + i);

if (total_vf_bar_sz = gate)
/* single-pe-mode */
else
/* shared-mode */

   mul = roundup_pow_of_two(total_vfs);
   pdn-m64_single_mode = true;
   break;
-- 
1.7.9.5


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v3 1/1] KVM: PPC: Book3S: correct width in XER handling

2015-08-05 Thread Sam Bobroff
Ping?

I think I've addressed all the comments in this version. Is there anything else
I need to look at?

Cheers,
Sam.

On Wed, May 27, 2015 at 09:56:57AM +1000, Sam Bobroff wrote:
 In 64 bit kernels, the Fixed Point Exception Register (XER) is a 64
 bit field (e.g. in kvm_regs and kvm_vcpu_arch) and in most places it is
 accessed as such.
 
 This patch corrects places where it is accessed as a 32 bit field by a
 64 bit kernel.  In some cases this is via a 32 bit load or store
 instruction which, depending on endianness, will cause either the
 lower or upper 32 bits to be missed.  In another case it is cast as a
 u32, causing the upper 32 bits to be cleared.
 
 This patch corrects those places by extending the access methods to
 64 bits.
 
 Signed-off-by: Sam Bobroff sam.bobr...@au1.ibm.com
 ---
 
 v3:
 Adjust booke set/get xer to match book3s.
 
 v2:
 
 Also extend kvmppc_book3s_shadow_vcpu.xer to 64 bit.
 
  arch/powerpc/include/asm/kvm_book3s.h |4 ++--
  arch/powerpc/include/asm/kvm_book3s_asm.h |2 +-
  arch/powerpc/include/asm/kvm_booke.h  |4 ++--
  arch/powerpc/kvm/book3s_hv_rmhandlers.S   |6 +++---
  arch/powerpc/kvm/book3s_segment.S |4 ++--
  5 files changed, 10 insertions(+), 10 deletions(-)
 
 diff --git a/arch/powerpc/include/asm/kvm_book3s.h 
 b/arch/powerpc/include/asm/kvm_book3s.h
 index b91e74a..05a875a 100644
 --- a/arch/powerpc/include/asm/kvm_book3s.h
 +++ b/arch/powerpc/include/asm/kvm_book3s.h
 @@ -225,12 +225,12 @@ static inline u32 kvmppc_get_cr(struct kvm_vcpu *vcpu)
   return vcpu-arch.cr;
  }
  
 -static inline void kvmppc_set_xer(struct kvm_vcpu *vcpu, u32 val)
 +static inline void kvmppc_set_xer(struct kvm_vcpu *vcpu, ulong val)
  {
   vcpu-arch.xer = val;
  }
  
 -static inline u32 kvmppc_get_xer(struct kvm_vcpu *vcpu)
 +static inline ulong kvmppc_get_xer(struct kvm_vcpu *vcpu)
  {
   return vcpu-arch.xer;
  }
 diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h 
 b/arch/powerpc/include/asm/kvm_book3s_asm.h
 index 5bdfb5d..c4ccd2d 100644
 --- a/arch/powerpc/include/asm/kvm_book3s_asm.h
 +++ b/arch/powerpc/include/asm/kvm_book3s_asm.h
 @@ -112,7 +112,7 @@ struct kvmppc_book3s_shadow_vcpu {
   bool in_use;
   ulong gpr[14];
   u32 cr;
 - u32 xer;
 + ulong xer;
   ulong ctr;
   ulong lr;
   ulong pc;
 diff --git a/arch/powerpc/include/asm/kvm_booke.h 
 b/arch/powerpc/include/asm/kvm_booke.h
 index 3286f0d..bc6e29e 100644
 --- a/arch/powerpc/include/asm/kvm_booke.h
 +++ b/arch/powerpc/include/asm/kvm_booke.h
 @@ -54,12 +54,12 @@ static inline u32 kvmppc_get_cr(struct kvm_vcpu *vcpu)
   return vcpu-arch.cr;
  }
  
 -static inline void kvmppc_set_xer(struct kvm_vcpu *vcpu, u32 val)
 +static inline void kvmppc_set_xer(struct kvm_vcpu *vcpu, ulong val)
  {
   vcpu-arch.xer = val;
  }
  
 -static inline u32 kvmppc_get_xer(struct kvm_vcpu *vcpu)
 +static inline ulong kvmppc_get_xer(struct kvm_vcpu *vcpu)
  {
   return vcpu-arch.xer;
  }
 diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S 
 b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
 index 4d70df2..d75be59 100644
 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
 +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
 @@ -870,7 +870,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
   blt hdec_soon
  
   ld  r6, VCPU_CTR(r4)
 - lwz r7, VCPU_XER(r4)
 + ld  r7, VCPU_XER(r4)
  
   mtctr   r6
   mtxer   r7
 @@ -1103,7 +1103,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
   mfctr   r3
   mfxer   r4
   std r3, VCPU_CTR(r9)
 - stw r4, VCPU_XER(r9)
 + std r4, VCPU_XER(r9)
  
   /* If this is a page table miss then see if it's theirs or ours */
   cmpwi   r12, BOOK3S_INTERRUPT_H_DATA_STORAGE
 @@ -1675,7 +1675,7 @@ kvmppc_hdsi:
   bl  kvmppc_msr_interrupt
  fast_interrupt_c_return:
  6:   ld  r7, VCPU_CTR(r9)
 - lwz r8, VCPU_XER(r9)
 + ld  r8, VCPU_XER(r9)
   mtctr   r7
   mtxer   r8
   mr  r4, r9
 diff --git a/arch/powerpc/kvm/book3s_segment.S 
 b/arch/powerpc/kvm/book3s_segment.S
 index acee37c..ca8f174 100644
 --- a/arch/powerpc/kvm/book3s_segment.S
 +++ b/arch/powerpc/kvm/book3s_segment.S
 @@ -123,7 +123,7 @@ no_dcbz32_on:
   PPC_LL  r8, SVCPU_CTR(r3)
   PPC_LL  r9, SVCPU_LR(r3)
   lwz r10, SVCPU_CR(r3)
 - lwz r11, SVCPU_XER(r3)
 + PPC_LL  r11, SVCPU_XER(r3)
  
   mtctr   r8
   mtlrr9
 @@ -237,7 +237,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
   mfctr   r8
   mflrr9
  
 - stw r5, SVCPU_XER(r13)
 + PPC_STL r5, SVCPU_XER(r13)
   PPC_STL r6, SVCPU_FAULT_DAR(r13)
   stw r7, SVCPU_FAULT_DSISR(r13)
   PPC_STL r8, SVCPU_CTR(r13)
 -- 
 1.7.10.4
 
 --
 To unsubscribe from this list: send the line unsubscribe kvm-ppc in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 18/42] powerpc/powernv: Allocate PE# in deasending order

2015-08-05 Thread Gavin Shan
The available PE#, represented by a bitmap in the PHB, is allocated
in ascending order. It conflicts with the fact that M64 segments are
assigned in same order. In order to avoid the conflict, the patch
allocates PE# in descending order.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/pci-ioda.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 56b058c..1c950e8 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -161,13 +161,18 @@ static struct pnv_ioda_pe *pnv_ioda_reserve_pe(struct 
pnv_phb *phb, int pe_no)
 static struct pnv_ioda_pe *pnv_ioda_alloc_pe(struct pnv_phb *phb)
 {
unsigned long pe;
+   unsigned long limit = phb-ioda.total_pe_num - 1;
 
do {
pe = find_next_zero_bit(phb-ioda.pe_alloc,
-   phb-ioda.total_pe_num, 0);
-   if (pe = phb-ioda.total_pe_num)
+   phb-ioda.total_pe_num, limit);
+   if (pe  phb-ioda.total_pe_num 
+   !test_and_set_bit(pe, phb-ioda.pe_alloc))
+   break;
+
+   if (--limit = phb-ioda.total_pe_num)
return NULL;
-   } while(test_and_set_bit(pe, phb-ioda.pe_alloc));
+   } while (1);
 
return pnv_ioda_init_pe(phb, pe);
 }
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v6 42/42] pci/hotplug: PowerPC PowerNV PCI hotplug driver

2015-08-05 Thread Gavin Shan
The patch intends to add standalone driver to support PCI hotplug
for PowerPC PowerNV platform, which runs on top of skiboot firmware.
The firmware identified hotpluggable slots and marked their device
tree node with proper ibm,slot-pluggable and ibm,reset-by-firmware.
The driver simply scans device-tree to create/register PCI hotplug slot
accordingly.

If the skiboot firmware doesn't support slot status retrieval, the PCI
slot device node shouldn't have property ibm,reset-by-firmware. In
that case, none of valid PCI slots will be detected from device tree.
The skiboot firmware doesn't export the capability to access attention
LEDs yet and it's something for TBD.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
Acked-by: Bjorn Helgaas bhelg...@google.com
---
 MAINTAINERS|   6 +
 drivers/pci/hotplug/Kconfig|  12 +
 drivers/pci/hotplug/Makefile   |   4 +
 drivers/pci/hotplug/powernv_php.c  | 140 +++
 drivers/pci/hotplug/powernv_php.h  |  92 +
 drivers/pci/hotplug/powernv_php_slot.c | 722 +
 6 files changed, 976 insertions(+)
 create mode 100644 drivers/pci/hotplug/powernv_php.c
 create mode 100644 drivers/pci/hotplug/powernv_php.h
 create mode 100644 drivers/pci/hotplug/powernv_php_slot.c

diff --git a/MAINTAINERS b/MAINTAINERS
index fd60784..3b75c92 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7747,6 +7747,12 @@ L:   linux-...@vger.kernel.org
 S: Supported
 F: Documentation/PCI/pci-error-recovery.txt
 
+PCI HOTPLUG DRIVER FOR POWERNV PLATFORM
+M: Gavin Shan gws...@linux.vnet.ibm.com
+L: linux-...@vger.kernel.org
+S: Supported
+F: drivers/pci/hotplug/powernv_php*
+
 PCI SUBSYSTEM
 M: Bjorn Helgaas bhelg...@google.com
 L: linux-...@vger.kernel.org
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig
index df8caec..ef55dae 100644
--- a/drivers/pci/hotplug/Kconfig
+++ b/drivers/pci/hotplug/Kconfig
@@ -113,6 +113,18 @@ config HOTPLUG_PCI_SHPC
 
  When in doubt, say N.
 
+config HOTPLUG_PCI_POWERNV
+   tristate PowerPC PowerNV PCI Hotplug driver
+   depends on PPC_POWERNV  EEH
+   help
+ Say Y here if you run PowerPC PowerNV platform that supports
+  PCI Hotplug
+
+ To compile this driver as a module, choose M here: the
+ module will be called powernv-php.
+
+ When in doubt, say N.
+
 config HOTPLUG_PCI_RPA
tristate RPA PCI Hotplug driver
depends on PPC_PSERIES  EEH
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile
index b616e75..fd51d65 100644
--- a/drivers/pci/hotplug/Makefile
+++ b/drivers/pci/hotplug/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_HOTPLUG_PCI_PCIE)+= pciehp.o
 obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550)  += cpcihp_zt5550.o
 obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC) += cpcihp_generic.o
 obj-$(CONFIG_HOTPLUG_PCI_SHPC) += shpchp.o
+obj-$(CONFIG_HOTPLUG_PCI_POWERNV)  += powernv-php.o
 obj-$(CONFIG_HOTPLUG_PCI_RPA)  += rpaphp.o
 obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR)+= rpadlpar_io.o
 obj-$(CONFIG_HOTPLUG_PCI_SGI)  += sgi_hotplug.o
@@ -50,6 +51,9 @@ ibmphp-objs   :=  ibmphp_core.o   \
 acpiphp-objs   :=  acpiphp_core.o  \
acpiphp_glue.o
 
+powernv-php-objs   :=  powernv_php.o   \
+   powernv_php_slot.o
+
 rpaphp-objs:=  rpaphp_core.o   \
rpaphp_pci.o\
rpaphp_slot.o
diff --git a/drivers/pci/hotplug/powernv_php.c 
b/drivers/pci/hotplug/powernv_php.c
new file mode 100644
index 000..4cbff7a
--- /dev/null
+++ b/drivers/pci/hotplug/powernv_php.c
@@ -0,0 +1,140 @@
+/*
+ * PCI Hotplug Driver for PowerPC PowerNV platform.
+ *
+ * Copyright Gavin Shan, IBM Corporation 2015.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include linux/module.h
+
+#include asm/opal.h
+#include asm/pnv-pci.h
+
+#include powernv_php.h
+
+#define DRIVER_VERSION 0.1
+#define DRIVER_AUTHOR  Gavin Shan, IBM Corporation
+#define DRIVER_DESCPowerPC PowerNV PCI Hotplug Driver
+
+static struct notifier_block php_msg_nb = {
+   .notifier_call  = powernv_php_msg_handler,
+   .next   = NULL,
+   .priority   = 0,
+};
+
+static int powernv_php_register_one(struct device_node *dn)
+{
+   struct powernv_php_slot *slot;
+   const __be32 *prop32;
+   int ret;
+
+   /* Check if it's hotpluggable slot */
+   prop32 = of_get_property(dn, ibm,slot-pluggable, NULL);
+   if (!prop32 || !of_read_number(prop32, 1))
+   return -ENXIO;
+
+   prop32 = of_get_property(dn, ibm,reset-by-firmware, NULL);
+   if 

[PATCH v6 34/42] powerpc/pci: Delay creating pci_dn

2015-08-05 Thread Gavin Shan
The pci_dn instances are allocated from memblock or bootmem when
creating PCI controller (hoses) in setup_arch(). The PCI hotplug,
which will be supported by proceeding patches, will release PCI
device nodes and their corresponding pci_dn on unplugging event.
The pci_dn instance memory chunks alloed from memblock or bootmem
are hard to reused after being released.

This delays creating pci_dn using core_initcall() so that they can
be allocated from slab. In turn, the memory chunks for them can be
reused after being released without problem. Since the pci_dn and
eeh_dev has same life cycle, the eeh_dev is created when pci_dn is
populated. We needn't create eeh_dev with another initcall. The
time to create PHB PEs is delayed a bit from core_initcall() to
core_initcall_sync().

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/include/asm/eeh.h |  2 +-
 arch/powerpc/include/asm/ppc-pci.h |  1 -
 arch/powerpc/kernel/eeh_dev.c  | 19 
 arch/powerpc/kernel/pci_dn.c   | 20 +++--
 arch/powerpc/platforms/maple/pci.c | 34 ++---
 arch/powerpc/platforms/pasemi/pci.c|  3 ---
 arch/powerpc/platforms/powermac/pci.c  | 40 --
 arch/powerpc/platforms/powernv/pci.c   |  3 ---
 arch/powerpc/platforms/pseries/setup.c |  7 +-
 9 files changed, 69 insertions(+), 60 deletions(-)

diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index ea1f13c4..19b6050 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -272,7 +272,7 @@ void eeh_pe_restore_bars(struct eeh_pe *pe);
 const char *eeh_pe_loc_get(struct eeh_pe *pe);
 struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe);
 
-void *eeh_dev_init(struct pci_dn *pdn, void *data);
+struct eeh_dev *eeh_dev_init(struct pci_dn *pdn, struct pci_controller *phb);
 void eeh_dev_phb_init_dynamic(struct pci_controller *phb);
 int eeh_init(void);
 int __init eeh_ops_register(struct eeh_ops *ops);
diff --git a/arch/powerpc/include/asm/ppc-pci.h 
b/arch/powerpc/include/asm/ppc-pci.h
index ca0c5bf..916775d 100644
--- a/arch/powerpc/include/asm/ppc-pci.h
+++ b/arch/powerpc/include/asm/ppc-pci.h
@@ -40,7 +40,6 @@ void *traverse_pci_dn(struct pci_dn *root,
  void *(*fn)(struct pci_dn *, void *),
  void *data);
 
-extern void pci_devs_phb_init(void);
 extern void pci_devs_phb_init_dynamic(struct pci_controller *phb);
 
 /* From rtas_pci.h */
diff --git a/arch/powerpc/kernel/eeh_dev.c b/arch/powerpc/kernel/eeh_dev.c
index aabba94..7a135c1 100644
--- a/arch/powerpc/kernel/eeh_dev.c
+++ b/arch/powerpc/kernel/eeh_dev.c
@@ -44,14 +44,13 @@
 /**
  * eeh_dev_init - Create EEH device according to OF node
  * @pdn: PCI device node
- * @data: PHB
+ * @phb: PCI controller
  *
  * It will create EEH device according to the given OF node. The function
  * might be called by PCI emunation, DR, PHB hotplug.
  */
-void *eeh_dev_init(struct pci_dn *pdn, void *data)
+struct eeh_dev *eeh_dev_init(struct pci_dn *pdn, struct pci_controller *phb)
 {
-   struct pci_controller *phb = data;
struct eeh_dev *edev;
 
/* Allocate EEH device */
@@ -68,7 +67,7 @@ void *eeh_dev_init(struct pci_dn *pdn, void *data)
edev-phb = phb;
INIT_LIST_HEAD(edev-list);
 
-   return NULL;
+   return edev;
 }
 
 /**
@@ -80,16 +79,8 @@ void *eeh_dev_init(struct pci_dn *pdn, void *data)
  */
 void eeh_dev_phb_init_dynamic(struct pci_controller *phb)
 {
-   struct pci_dn *root = phb-pci_data;
-
/* EEH PE for PHB */
eeh_phb_pe_create(phb);
-
-   /* EEH device for PHB */
-   eeh_dev_init(root, phb);
-
-   /* EEH devices for children OF nodes */
-   traverse_pci_dn(root, eeh_dev_init, phb);
 }
 
 /**
@@ -105,9 +96,7 @@ static int __init eeh_dev_phb_init(void)
list_for_each_entry_safe(phb, tmp, hose_list, list_node)
eeh_dev_phb_init_dynamic(phb);
 
-   pr_info(EEH: devices created\n);
-
return 0;
 }
 
-core_initcall(eeh_dev_phb_init);
+core_initcall_sync(eeh_dev_phb_init);
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
index f0ddde7..53a11e9 100644
--- a/arch/powerpc/kernel/pci_dn.c
+++ b/arch/powerpc/kernel/pci_dn.c
@@ -290,8 +290,11 @@ void *update_dn_pci_info(struct device_node *dn, void 
*data)
const __be32 *regs;
struct device_node *parent;
struct pci_dn *pdn;
+#ifdef CONFIG_EEH
+   struct eeh_dev *edev;
+#endif
 
-   pdn = zalloc_maybe_bootmem(sizeof(*pdn), GFP_KERNEL);
+   pdn = kzalloc(sizeof(*pdn), GFP_KERNEL);
if (pdn == NULL)
return NULL;
dn-data = pdn;
@@ -320,6 +323,15 @@ void *update_dn_pci_info(struct device_node *dn, void 
*data)
/* Extended config space */
pdn-pci_ext_config_space = (type  of_read_number(type, 1) == 1);
 
+   /* Initialize EEH device */
+#ifdef CONFIG_EEH
+   

[PATCH v6 06/42] powerpc/powernv: Simplify pnv_ioda_setup_pe_seg()

2015-08-05 Thread Gavin Shan
The original implementation of pnv_ioda_setup_pe_seg() configures
IO and M32 segments by separate logics, which can be merged by
by caching @seg_bitmap, @seg_size, @win in advance. The patch
shouldn't cause any behavioural changes.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/pci-ioda.c | 68 ++-
 1 file changed, 31 insertions(+), 37 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 78b49a1..488a53e 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -2856,7 +2856,10 @@ static void pnv_ioda_setup_pe_seg(struct pci_controller 
*hose,
struct pci_bus_region region;
struct resource *res;
int i, index;
-   int rc;
+   unsigned int segsize;
+   unsigned long *segmap, *pe_segmap;
+   uint16_t win;
+   int64_t rc;
 
/*
 * NOTE: We only care PCI bus based PE for now. For PCI
@@ -2873,25 +2876,10 @@ static void pnv_ioda_setup_pe_seg(struct pci_controller 
*hose,
if (res-flags  IORESOURCE_IO) {
region.start = res-start - phb-ioda.io_pci_base;
region.end   = res-end - phb-ioda.io_pci_base;
-   index = region.start / phb-ioda.io_segsize;
-
-   while (index  phb-ioda.total_pe 
-  region.start = region.end) {
-   set_bit(index, pe-io_segmap);
-   set_bit(index, phb-ioda.io_segmap);
-   rc = opal_pci_map_pe_mmio_window(phb-opal_id,
-   pe-pe_number, OPAL_IO_WINDOW_TYPE,
-   0, index);
-   if (rc != OPAL_SUCCESS) {
-   pr_err(%s: OPAL error %d when mapping 
IO 
-  segment #%d to PE#%d\n,
-  __func__, rc, index, 
pe-pe_number);
-   break;
-   }
-
-   region.start += phb-ioda.io_segsize;
-   index++;
-   }
+   segsize  = phb-ioda.io_segsize;
+   segmap   = phb-ioda.io_segmap;
+   pe_segmap= pe-io_segmap;
+   win  = OPAL_IO_WINDOW_TYPE;
} else if ((res-flags  IORESOURCE_MEM) 
   !pnv_pci_is_mem_pref_64(res-flags)) {
region.start = res-start -
@@ -2900,25 +2888,31 @@ static void pnv_ioda_setup_pe_seg(struct pci_controller 
*hose,
region.end   = res-end -
   hose-mem_offset[0] -
   phb-ioda.m32_pci_base;
-   index = region.start / phb-ioda.m32_segsize;
-
-   while (index  phb-ioda.total_pe 
-  region.start = region.end) {
-   set_bit(index, pe-m32_segmap);
-   set_bit(index, phb-ioda.m32_segmap);
-   rc = opal_pci_map_pe_mmio_window(phb-opal_id,
-   pe-pe_number, OPAL_M32_WINDOW_TYPE,
-   0, index);
-   if (rc != OPAL_SUCCESS) {
-   pr_err(%s: OPAL error %d when mapping 
M32 
-  segment#%d to PE#%d,
-  __func__, rc, index, 
pe-pe_number);
-   break;
-   }
+   segsize  = phb-ioda.m32_segsize;
+   segmap   = phb-ioda.m32_segmap;
+   pe_segmap= pe-m32_segmap;
+   win  = OPAL_M32_WINDOW_TYPE;
+   } else {
+   continue;
+   }
 
-   region.start += phb-ioda.m32_segsize;
-   index++;
+   index = region.start / phb-ioda.io_segsize;
+   while (index  phb-ioda.total_pe 
+  region.start = region.end) {
+   set_bit(index, segmap);
+   set_bit(index, pe_segmap);
+   rc = opal_pci_map_pe_mmio_window(phb-opal_id,
+   pe-pe_number, win, 0, index);
+   if (rc != OPAL_SUCCESS) {
+   pr_warn(%s: Error %lld mapping (%d) seg#%d to 
PHB#%d-PE#%d\n,
+   __func__, rc, win, index,
+   

[PATCH v6 22/42] powerpc/powernv: Move functions around

2015-08-05 Thread Gavin Shan
The patch moves functions related to releasing PE around so that
we don't need extra declaration for them in subsequent patches.
Also, it fixes warnings from scripts/checkpatch.pl. It doesn't
introduce any behavioural changes.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/pci-ioda.c | 743 +++---
 1 file changed, 377 insertions(+), 366 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 84b771e..d2697a3 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -132,6 +132,295 @@ static inline bool pnv_pci_is_mem_pref_64(unsigned long 
flags)
(IORESOURCE_MEM_64 | IORESOURCE_PREFETCH));
 }
 
+static inline void pnv_pci_ioda2_tce_invalidate_entire(struct pnv_ioda_pe *pe)
+{
+   /* 01xb - invalidate TCEs that match the specified PE# */
+   unsigned long val = (0x4ull  60) | (pe-pe_number  0xFF);
+   struct pnv_phb *phb = pe-phb;
+
+   if (!phb-ioda.tce_inval_reg)
+   return;
+
+   mb(); /* Ensure above stores are visible */
+   __raw_writeq(cpu_to_be64(val), phb-ioda.tce_inval_reg);
+}
+
+#if defined(CONFIG_IOMMU_API) || defined(CONFIG_PCI_IOV)
+static long pnv_pci_ioda2_unset_window(struct iommu_table_group *table_group,
+   int num)
+{
+   struct pnv_ioda_pe *pe = container_of(table_group, struct pnv_ioda_pe,
+   table_group);
+   struct pnv_phb *phb = pe-phb;
+   long ret;
+
+   pe_info(pe, Removing DMA window #%d\n, num);
+
+   ret = opal_pci_map_pe_dma_window(phb-opal_id, pe-pe_number,
+   (pe-pe_number  1) + num,
+   0/* levels */, 0/* table address */,
+   0/* table size */, 0/* page size */);
+   if (ret)
+   pe_warn(pe, Unmapping failed, ret = %ld\n, ret);
+   else
+   pnv_pci_ioda2_tce_invalidate_entire(pe);
+
+   pnv_pci_unlink_table_and_group(table_group-tables[num], table_group);
+
+   return ret;
+}
+#endif /* CONFIG_IOMMU_API || CONFIG_PCI_IOV */
+
+static void pnv_pci_ioda2_set_bypass(struct pnv_ioda_pe *pe, bool enable)
+{
+   uint16_t window_id = (pe-pe_number  1) + 1;
+   int64_t rc;
+
+   pe_info(pe, %sabling 64-bit DMA bypass\n, enable ? En : Dis);
+   if (enable) {
+   phys_addr_t top = memblock_end_of_DRAM();
+
+   top = roundup_pow_of_two(top);
+   rc = opal_pci_map_pe_dma_window_real(pe-phb-opal_id,
+pe-pe_number,
+window_id,
+pe-tce_bypass_base,
+top);
+   } else {
+   rc = opal_pci_map_pe_dma_window_real(pe-phb-opal_id,
+pe-pe_number,
+window_id,
+pe-tce_bypass_base,
+0);
+   }
+   if (rc)
+   pe_err(pe, OPAL error %lld configuring bypass window\n, rc);
+   else
+   pe-tce_bypass_enabled = enable;
+}
+
+#ifdef CONFIG_PCI_IOV
+static void pnv_pci_ioda2_release_dma_pe(struct pci_dev *dev,
+struct pnv_ioda_pe *pe)
+{
+   struct iommu_table*tbl;
+   int64_t   rc;
+
+   tbl = pe-table_group.tables[0];
+   rc = pnv_pci_ioda2_unset_window(pe-table_group, 0);
+   if (rc)
+   pe_warn(pe, OPAL error %ld release DMA window\n, rc);
+
+   pnv_pci_ioda2_set_bypass(pe, false);
+   if (pe-table_group.group) {
+   iommu_group_put(pe-table_group.group);
+   BUG_ON(pe-table_group.group);
+   }
+   pnv_pci_ioda2_table_free_pages(tbl);
+   iommu_free_table(tbl, of_node_full_name(dev-dev.of_node));
+}
+#endif /* CONFIG_PCI_IOV */
+
+static int pnv_ioda_set_one_peltv(struct pnv_phb *phb,
+ struct pnv_ioda_pe *parent,
+ struct pnv_ioda_pe *child,
+ bool is_add)
+{
+   const char *desc = is_add ? adding : removing;
+   uint8_t op = is_add ? OPAL_ADD_PE_TO_DOMAIN :
+ OPAL_REMOVE_PE_FROM_DOMAIN;
+   struct pnv_ioda_pe *slave;
+   long rc;
+
+   /* Parent PE affects child PE */
+   rc = opal_pci_set_peltv(phb-opal_id, parent-pe_number,
+   child-pe_number, op);
+   if (rc != OPAL_SUCCESS) {
+   pe_warn(child, OPAL error %ld %s to parent PELTV\n,
+   rc, desc);
+   return -ENXIO;
+   }
+
+   if (!(child-flags  PNV_IODA_PE_MASTER))
+   return 0;
+
+   

[PATCH v6 35/42] powerpc/pci: Export traverse_pci_device_nodes()

2015-08-05 Thread Gavin Shan
Previously we wouldn't remove pdn because PCI hotplug isn't
supported. update_dn_pci_info() is called at system booting
time to create pdn for PCI device nodes. However, it's going
to be changed later because of PCI hotplug.

This converts update_dn_pci_info() to add_pci_device_node_info(),
traverse_pci_devices() to traverse_pci_device_nodes(). This also
adds remove_pci_device_node_info() which will be used in subsequent
patch at the moment of unplugging PCI devices. All those functions
are exported for PowerNV hotplug driver to use.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/include/asm/pci-bridge.h  |  4 ++-
 arch/powerpc/include/asm/ppc-pci.h |  8 --
 arch/powerpc/kernel/pci_dn.c   | 51 +-
 arch/powerpc/platforms/pseries/setup.c |  2 +-
 4 files changed, 53 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/include/asm/pci-bridge.h 
b/arch/powerpc/include/asm/pci-bridge.h
index 787a879..010eb54 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -237,7 +237,9 @@ extern struct pci_dn *pci_get_pdn_by_devfn(struct pci_bus 
*bus,
 extern struct pci_dn *pci_get_pdn(struct pci_dev *pdev);
 extern struct pci_dn *add_dev_pci_data(struct pci_dev *pdev);
 extern void remove_dev_pci_data(struct pci_dev *pdev);
-extern void *update_dn_pci_info(struct device_node *dn, void *data);
+extern void *add_pci_device_node_info(struct device_node *dn,
+ struct pci_controller *phb);
+extern void remove_pci_device_node_info(struct device_node *np);
 
 static inline int pci_device_from_OF_node(struct device_node *np,
  u8 *bus, u8 *devfn)
diff --git a/arch/powerpc/include/asm/ppc-pci.h 
b/arch/powerpc/include/asm/ppc-pci.h
index 916775d..c87ed42 100644
--- a/arch/powerpc/include/asm/ppc-pci.h
+++ b/arch/powerpc/include/asm/ppc-pci.h
@@ -33,9 +33,11 @@ extern struct pci_dev *isa_bridge_pcidev;/* may be NULL 
if no ISA bus */
 struct device_node;
 struct pci_dn;
 
-typedef void *(*traverse_func)(struct device_node *me, void *data);
-void *traverse_pci_devices(struct device_node *start, traverse_func pre,
-   void *data);
+typedef void *(*traverse_func)(struct device_node *me,
+  struct pci_controller *phb);
+void *traverse_pci_device_nodes(struct device_node *start,
+   traverse_func pre,
+   struct pci_controller *phb);
 void *traverse_pci_dn(struct pci_dn *root,
  void *(*fn)(struct pci_dn *, void *),
  void *data);
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
index 53a11e9..3a38a55 100644
--- a/arch/powerpc/kernel/pci_dn.c
+++ b/arch/powerpc/kernel/pci_dn.c
@@ -283,9 +283,9 @@ void remove_dev_pci_data(struct pci_dev *pdev)
  * Traverse_func that inits the PCI fields of the device node.
  * NOTE: this *must* be done before read/write config to the device.
  */
-void *update_dn_pci_info(struct device_node *dn, void *data)
+void *add_pci_device_node_info(struct device_node *dn,
+  struct pci_controller *phb)
 {
-   struct pci_controller *phb = data;
const __be32 *type = of_get_property(dn, ibm,pci-config-space-type, 
NULL);
const __be32 *regs;
struct device_node *parent;
@@ -342,6 +342,42 @@ void *update_dn_pci_info(struct device_node *dn, void 
*data)
 
return NULL;
 }
+EXPORT_SYMBOL(add_pci_device_node_info);
+
+/**
+ * remove_pci_device_node_info - Remove pci_dn from PCI device node
+ * @dn: PCI device node
+ *
+ * Remove pci_dn from PCI device node. The pci_dn is also removed
+ * from the child list of the parent pci_dn.
+ */
+void remove_pci_device_node_info(struct device_node *np)
+{
+   struct pci_dn *pdn = np ? PCI_DN(np) : NULL;
+#ifdef CONFIG_EEH
+   struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
+#endif
+
+   if (!pdn)
+   return;
+
+#ifdef CONFIG_EEH
+   if (edev) {
+   pdn-edev = NULL;
+   kfree(edev);
+   }
+#endif
+
+   BUG_ON(!list_empty(pdn-child_list));
+   list_del(pdn-list);
+   if (pdn-parent)
+   of_node_put(pdn-parent-node);
+
+   np-data = NULL;
+   kfree(pdn);
+}
+EXPORT_SYMBOL(remove_pci_device_node_info);
+
 
 /*
  * Traverse a device tree stopping each PCI device in the tree.
@@ -361,8 +397,8 @@ void *update_dn_pci_info(struct device_node *dn, void *data)
  * one of these nodes we also assume its siblings are non-pci for
  * performance.
  */
-void *traverse_pci_devices(struct device_node *start, traverse_func pre,
-   void *data)
+void *traverse_pci_device_nodes(struct device_node *start, traverse_func pre,
+   struct pci_controller *phb)
 {
struct device_node *dn, *nextdn;
void *ret;
@@ -377,7 +413,7 @@ void 

Re: [PATCH V2 3/6] powerpc/powernv: use one M64 BAR in Single PE mode for one VF BAR

2015-08-05 Thread Gavin Shan
On Wed, Aug 05, 2015 at 09:25:00AM +0800, Wei Yang wrote:
In current implementation, when VF BAR is bigger than 64MB, it uses 4 M64
BAR in Single PE mode to cover the number of VFs required to be enabled.
By doing so, several VFs would be in one VF Group and leads to interference
between VFs in the same group.

This patch changes the design by using one M64 BAR in Single PE mode for
one VF BAR. This gives absolute isolation for VFs.

Signed-off-by: Wei Yang weiy...@linux.vnet.ibm.com
---
 arch/powerpc/include/asm/pci-bridge.h |5 +-
 arch/powerpc/platforms/powernv/pci-ioda.c |  180 -
 2 files changed, 76 insertions(+), 109 deletions(-)

diff --git a/arch/powerpc/include/asm/pci-bridge.h 
b/arch/powerpc/include/asm/pci-bridge.h
index 712add5..8aeba4c 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -214,10 +214,9 @@ struct pci_dn {
   u16 vfs_expanded;   /* number of VFs IOV BAR expanded */
   u16 num_vfs;/* number of VFs enabled*/
   int offset; /* PE# for the first VF PE */
-#define M64_PER_IOV 4
-  int m64_per_iov;
+  boolm64_single_mode;/* Use M64 BAR in Single Mode */
 #define IODA_INVALID_M64(-1)
-  int m64_wins[PCI_SRIOV_NUM_BARS][M64_PER_IOV];
+  int (*m64_map)[PCI_SRIOV_NUM_BARS];

It can be explicit? For example:

int *m64_map;

/* Initialization */
size_t size = sizeof(*pdn-m64_map) * PCI_SRIOV_NUM_BARS * 
num_of_max_VFs;
pdn-m64_map = kmalloc(size, GFP_KERNEL);
for (i = 0; i  PCI_SRIOV_NUM_BARS; i++)
for (j = 0; j  num_of_max_VFs; j++)
pdn-m64_map[i * PCI_SRIOV_NUM_BARS + j] = 
PNV_INVALID_M64;

/* Destroy */
int step = 1;

if (!pdn-m64_single_mode)
step = phb-ioda.total_pe;
for (i = 0; i  PCI_SRIOV_NUM_BARS * num_of_max_VFs; i += step)
if (pdn-m64_map[i] == PNV_INVALID_M64)
continue;

/* Unmap the window */


 #endif /* CONFIG_PCI_IOV */
 #endif
   struct list_head child_list;
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 7192e62..f5d110c 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1148,29 +1148,36 @@ static void pnv_pci_ioda_setup_PEs(void)
 }

 #ifdef CONFIG_PCI_IOV
-static int pnv_pci_vf_release_m64(struct pci_dev *pdev)
+static int pnv_pci_vf_release_m64(struct pci_dev *pdev, u16 num_vfs)
 {
   struct pci_bus*bus;
   struct pci_controller *hose;
   struct pnv_phb*phb;
   struct pci_dn *pdn;
   inti, j;
+  intm64_bars;

   bus = pdev-bus;
   hose = pci_bus_to_host(bus);
   phb = hose-private_data;
   pdn = pci_get_pdn(pdev);

+  if (pdn-m64_single_mode)
+  m64_bars = num_vfs;
+  else
+  m64_bars = 1;
+
   for (i = 0; i  PCI_SRIOV_NUM_BARS; i++)
-  for (j = 0; j  M64_PER_IOV; j++) {
-  if (pdn-m64_wins[i][j] == IODA_INVALID_M64)
+  for (j = 0; j  m64_bars; j++) {
+  if (pdn-m64_map[j][i] == IODA_INVALID_M64)
   continue;
   opal_pci_phb_mmio_enable(phb-opal_id,
-  OPAL_M64_WINDOW_TYPE, pdn-m64_wins[i][j], 0);
-  clear_bit(pdn-m64_wins[i][j], 
phb-ioda.m64_bar_alloc);
-  pdn-m64_wins[i][j] = IODA_INVALID_M64;
+  OPAL_M64_WINDOW_TYPE, pdn-m64_map[j][i], 0);
+  clear_bit(pdn-m64_map[j][i], phb-ioda.m64_bar_alloc);
+  pdn-m64_map[j][i] = IODA_INVALID_M64;
   }

+  kfree(pdn-m64_map);
   return 0;
 }

@@ -1187,8 +1194,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, 
u16 num_vfs)
   inttotal_vfs;
   resource_size_tsize, start;
   intpe_num;
-  intvf_groups;
-  intvf_per_group;
+  intm64_bars;

   bus = pdev-bus;
   hose = pci_bus_to_host(bus);
@@ -1196,26 +1202,26 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, 
u16 num_vfs)
   pdn = pci_get_pdn(pdev);
   total_vfs = pci_sriov_get_totalvfs(pdev);

-  /* Initialize the m64_wins to IODA_INVALID_M64 */
-  for (i = 0; i  PCI_SRIOV_NUM_BARS; i++)
-  for (j = 0; j  M64_PER_IOV; j++)
-  pdn-m64_wins[i][j] = IODA_INVALID_M64;
+  if (pdn-m64_single_mode)
+  m64_bars = num_vfs;
+  else
+  m64_bars = 1;
+
+  pdn-m64_map = kmalloc(sizeof(*pdn-m64_map) * m64_bars, GFP_KERNEL);
+  if (!pdn-m64_map)
+

[PATCH v6 40/42] drivers/of: Return allocated memory chunk from of_fdt_unflatten_tree()

2015-08-05 Thread Gavin Shan
This changes of_fdt_unflatten_tree() so that it returns the allocated
memory chunk for unflattened device-tree, which can be released once
it's obsoleted.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 drivers/of/fdt.c   | 11 ++-
 include/linux/of_fdt.h |  2 +-
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 074870a..8e1ba7e 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -408,7 +408,7 @@ static void *unflatten_dt_node(const void *blob,
  * @dt_alloc: An allocator that provides a virtual address to memory
  * for the resulting tree
  */
-static void __unflatten_device_tree(const void *blob,
+static void *__unflatten_device_tree(const void *blob,
 struct device_node *dad,
 struct device_node **mynodes,
 void * (*dt_alloc)(u64 size, u64 align))
@@ -421,7 +421,7 @@ static void __unflatten_device_tree(const void *blob,
 
if (!blob) {
pr_debug(No device tree pointer\n);
-   return;
+   return NULL;
}
 
pr_debug(Unflattening device tree:\n);
@@ -431,7 +431,7 @@ static void __unflatten_device_tree(const void *blob,
 
if (fdt_check_header(blob)) {
pr_err(Invalid device tree blob header\n);
-   return;
+   return NULL;
}
 
/* First pass, scan for size */
@@ -458,6 +458,7 @@ static void __unflatten_device_tree(const void *blob,
   be32_to_cpup(mem + size));
 
pr_debug( - unflatten_device_tree()\n);
+   return mem;
 }
 
 static void *kernel_tree_alloc(u64 size, u64 align)
@@ -473,11 +474,11 @@ static void *kernel_tree_alloc(u64 size, u64 align)
  * pointers of the nodes so the normal device-tree walking functions
  * can be used.
  */
-void of_fdt_unflatten_tree(const unsigned long *blob,
+void *of_fdt_unflatten_tree(const unsigned long *blob,
struct device_node *dad,
struct device_node **mynodes)
 {
-   __unflatten_device_tree(blob, dad, mynodes, kernel_tree_alloc);
+   return __unflatten_device_tree(blob, dad, mynodes, kernel_tree_alloc);
 }
 EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree);
 
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index 3644960..00db279 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -37,7 +37,7 @@ extern bool of_fdt_is_big_endian(const void *blob,
 unsigned long node);
 extern int of_fdt_match(const void *blob, unsigned long node,
const char *const *compat);
-extern void of_fdt_unflatten_tree(const unsigned long *blob,
+extern void *of_fdt_unflatten_tree(const unsigned long *blob,
   struct device_node *dad,
   struct device_node **mynodes);
 
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v6 25/42] powerpc/powernv: Use PCI slot reset infrastructure

2015-08-05 Thread Gavin Shan
The skiboot firmware might provide the capability of resetting PCI
slot by property ibm,reset-by-firmware on the PCI slot associated
device node. The patch checks on the property and route the reset
to firmware if the property exists. Otherwise, we fail back to the
old path as before.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/eeh-powernv.c | 44 +++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c 
b/arch/powerpc/platforms/powernv/eeh-powernv.c
index 0350dab..7be2ebf 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -843,7 +843,7 @@ out:
return 0;
 }
 
-static int pnv_eeh_bridge_reset(struct pci_dev *dev, int option)
+static int __pnv_eeh_bridge_reset(struct pci_dev *dev, int option)
 {
struct pci_dn *pdn = pci_get_pdn_by_devfn(dev-bus, dev-devfn);
struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
@@ -894,6 +894,48 @@ static int pnv_eeh_bridge_reset(struct pci_dev *dev, int 
option)
return 0;
 }
 
+static int pnv_eeh_bridge_reset(struct pci_dev *pdev, int option)
+{
+   struct pci_controller *hose;
+   struct pnv_phb *phb;
+   struct device_node *dn = pdev ? pci_device_to_OF_node(pdev) : NULL;
+   uint64_t id = (0x1ul  60);
+   uint8_t scope;
+   int64_t rc;
+
+   /*
+* If the firmware can't handle it, we will issue hot reset
+* on the secondary bus despite the requested reset type.
+*/
+   if (!dn || !of_get_property(dn, ibm,reset-by-firmware, NULL))
+   return __pnv_eeh_bridge_reset(pdev, option);
+
+   /* The firmware can handle the request */
+   switch (option) {
+   case EEH_RESET_HOT:
+   scope = OPAL_RESET_PCI_HOT;
+   break;
+   case EEH_RESET_FUNDAMENTAL:
+   scope = OPAL_RESET_PCI_FUNDAMENTAL;
+   break;
+   case EEH_RESET_DEACTIVATE:
+   return 0;
+   default:
+   dev_warn(pdev-dev, %s: Unsupported reset %d\n,
+__func__, option);
+   return -EINVAL;
+   }
+
+   hose = pci_bus_to_host(pdev-bus);
+   phb = hose-private_data;
+   id |= (pdev-bus-number  24) | (pdev-devfn  16) | phb-opal_id;
+   rc = opal_pci_reset(id, scope, OPAL_ASSERT_RESET);
+   if (rc  0)
+   rc = pnv_eeh_poll(id);
+
+   return (rc == OPAL_SUCCESS) ? 0 : -EIO;
+}
+
 static void pnv_eeh_wait_for_pending(struct pci_dn *pdn, int pos,
 u16 mask, bool af_flr_rst)
 {
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v6 27/42] powerpc/powernv: Don't cover root bus in pnv_pci_reset_secondary_bus()

2015-08-05 Thread Gavin Shan
pnv_pci_reset_secondary_bus(), invoked by pcibios_reset_secondary_bus()
on PowerNV platform. The latter can't be called on root bus. So the
former needn't cover root bus as well.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/eeh-powernv.c | 12 ++--
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c 
b/arch/powerpc/platforms/powernv/eeh-powernv.c
index 95332e9..19cb947 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -1059,16 +1059,8 @@ static int pnv_eeh_vf_pe_reset(struct eeh_pe *pe, int 
option)
 
 void pnv_pci_reset_secondary_bus(struct pci_dev *dev)
 {
-   struct pci_controller *hose;
-
-   if (pci_is_root_bus(dev-bus)) {
-   hose = pci_bus_to_host(dev-bus);
-   pnv_eeh_root_reset(hose, EEH_RESET_HOT);
-   pnv_eeh_root_reset(hose, EEH_RESET_DEACTIVATE);
-   } else {
-   pnv_eeh_bridge_reset(dev, EEH_RESET_HOT);
-   pnv_eeh_bridge_reset(dev, EEH_RESET_DEACTIVATE);
-   }
+   pnv_eeh_bridge_reset(dev, EEH_RESET_HOT);
+   pnv_eeh_bridge_reset(dev, EEH_RESET_DEACTIVATE);
 }
 
 /**
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v6 16/42] powerpc/powernv: Helper function pnv_ioda_init_pe()

2015-08-05 Thread Gavin Shan
The patch introduces helper function pnv_ioda_init_pe(), which
initialize PE instance after reserving or allocating PE#, to
simplify the code. The patch doesn't introduce behavioural
changes.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/pci-ioda.c | 20 +---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 9f53682..9cccf2d5 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -132,6 +132,17 @@ static inline bool pnv_pci_is_mem_pref_64(unsigned long 
flags)
(IORESOURCE_MEM_64 | IORESOURCE_PREFETCH));
 }
 
+static struct pnv_ioda_pe *pnv_ioda_init_pe(struct pnv_phb *phb, int pe_no)
+{
+   struct pnv_ioda_pe *pe = phb-ioda.pe_array[pe_no];
+
+   pe-phb = phb;
+   pe-pe_number = pe_no;
+   INIT_LIST_HEAD(pe-list);
+
+   return pe;
+}
+
 static struct pnv_ioda_pe *pnv_ioda_reserve_pe(struct pnv_phb *phb, int pe_no)
 {
if (!(pe_no = 0  pe_no  phb-ioda.total_pe)) {
@@ -144,10 +155,7 @@ static struct pnv_ioda_pe *pnv_ioda_reserve_pe(struct 
pnv_phb *phb, int pe_no)
pr_debug(%s: PE %d was reserved on PHB#%x\n,
 __func__, pe_no, phb-hose-global_number);
 
-   phb-ioda.pe_array[pe_no].phb = phb;
-   phb-ioda.pe_array[pe_no].pe_number = pe_no;
-
-   return phb-ioda.pe_array[pe_no];
+   return pnv_ioda_init_pe(phb, pe_no);
 }
 
 static struct pnv_ioda_pe *pnv_ioda_alloc_pe(struct pnv_phb *phb)
@@ -161,9 +169,7 @@ static struct pnv_ioda_pe *pnv_ioda_alloc_pe(struct pnv_phb 
*phb)
return NULL;
} while(test_and_set_bit(pe, phb-ioda.pe_alloc));
 
-   phb-ioda.pe_array[pe].phb = phb;
-   phb-ioda.pe_array[pe].pe_number = pe;
-   return phb-ioda.pe_array[pe];
+   return pnv_ioda_init_pe(phb, pe);
 }
 
 static void pnv_ioda_free_pe(struct pnv_phb *phb, int pe)
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v6 23/42] powerpc/powernv: Release PEs dynamically

2015-08-05 Thread Gavin Shan
This adds the refcount to PE, which represents number of PCI
devices contained in the PE. When last device leaves from the
PE, the PE together with its consumed resources (IO, DMA, PELTM,
PELTV) are released, to support PCI hotplug.

Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/platforms/powernv/pci-ioda.c | 233 +++---
 arch/powerpc/platforms/powernv/pci.h  |   3 +
 2 files changed, 217 insertions(+), 19 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index d2697a3..13d8a5b 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -132,6 +132,53 @@ static inline bool pnv_pci_is_mem_pref_64(unsigned long 
flags)
(IORESOURCE_MEM_64 | IORESOURCE_PREFETCH));
 }
 
+static void pnv_pci_ioda_release_pe_dma(struct pnv_ioda_pe *pe)
+{
+   struct pnv_phb *phb = pe-phb;
+   struct iommu_table *tbl;
+   int seg;
+   int64_t rc;
+
+   /* No DMA32 segments allocated */
+   if (pe-dma32_seg == PNV_INVALID_SEGMENT ||
+   pe-dma32_segcount = 0) {
+   pe-dma32_seg = PNV_INVALID_SEGMENT;
+   pe-dma32_segcount = 0;
+   return;
+   }
+
+   /* Unlink IOMMU table from group */
+   tbl = pe-table_group.tables[0];
+   pnv_pci_unlink_table_and_group(tbl, pe-table_group);
+   if (pe-table_group.group) {
+   iommu_group_put(pe-table_group.group);
+   BUG_ON(pe-table_group.group);
+   }
+
+   /* Release IOMMU table */
+   free_pages(tbl-it_base,
+   get_order(TCE32_TABLE_SIZE * pe-dma32_segcount));
+   iommu_free_table(tbl,
+   of_node_full_name(pci_bus_to_OF_node(pe-pbus)));
+
+   /* Disable TVE */
+   for (seg = pe-dma32_seg;
+seg  pe-dma32_seg + pe-dma32_segcount;
+seg++) {
+   rc = opal_pci_map_pe_dma_window(phb-opal_id,
+   pe-pe_number, seg, 0, 0ul, 0ul, 0ul);
+   if (rc)
+   pe_warn(pe, Error %ld unmapping DMA32 seg#%d\n,
+   rc, seg);
+   }
+
+   /* Free the DMA32 segments */
+   bitmap_clear(phb-ioda.dma32_segmap,
+   pe-dma32_seg, pe-dma32_segcount);
+   pe-dma32_seg = PNV_INVALID_SEGMENT;
+   pe-dma32_segcount = 0;
+}
+
 static inline void pnv_pci_ioda2_tce_invalidate_entire(struct pnv_ioda_pe *pe)
 {
/* 01xb - invalidate TCEs that match the specified PE# */
@@ -199,13 +246,15 @@ static void pnv_pci_ioda2_set_bypass(struct pnv_ioda_pe 
*pe, bool enable)
pe-tce_bypass_enabled = enable;
 }
 
-#ifdef CONFIG_PCI_IOV
-static void pnv_pci_ioda2_release_dma_pe(struct pci_dev *dev,
-struct pnv_ioda_pe *pe)
+static void pnv_pci_ioda2_release_pe_dma(struct pnv_ioda_pe *pe)
 {
struct iommu_table*tbl;
+   struct device_node*dn;
int64_t   rc;
 
+   if (pe-dma32_seg == PNV_INVALID_SEGMENT)
+   return;
+
tbl = pe-table_group.tables[0];
rc = pnv_pci_ioda2_unset_window(pe-table_group, 0);
if (rc)
@@ -216,10 +265,91 @@ static void pnv_pci_ioda2_release_dma_pe(struct pci_dev 
*dev,
iommu_group_put(pe-table_group.group);
BUG_ON(pe-table_group.group);
}
+
+   if (pe-flags  (PNV_IODA_PE_BUS | PNV_IODA_PE_BUS_ALL))
+   dn = pci_bus_to_OF_node(pe-pbus);
+   else if (pe-flags  PNV_IODA_PE_DEV)
+   dn = pci_device_to_OF_node(pe-pdev);
+#ifdef CONFIG_PCI_IOV
+   else if (pe-flags  PNV_IODA_PE_VF)
+   dn = pci_device_to_OF_node(pe-parent_dev);
+#endif
+   else
+   dn = NULL;
+
pnv_pci_ioda2_table_free_pages(tbl);
-   iommu_free_table(tbl, of_node_full_name(dev-dev.of_node));
+   iommu_free_table(tbl, of_node_full_name(dn));
+   pe-dma32_seg = PNV_INVALID_SEGMENT;
+}
+
+static void pnv_ioda_release_pe_dma(struct pnv_ioda_pe *pe)
+{
+   struct pnv_phb *phb = pe-phb;
+
+   switch (phb-type) {
+   case PNV_PHB_IODA1:
+   pnv_pci_ioda_release_pe_dma(pe);
+   break;
+   case PNV_PHB_IODA2:
+   pnv_pci_ioda2_release_pe_dma(pe);
+   break;
+   default:
+   pr_warn(%s: Cannot release DMA for PHB type %d\n,
+   __func__, phb-type);
+   }
+}
+
+static void pnv_ioda_release_pe_one_seg(struct pnv_ioda_pe *pe, int win)
+{
+   struct pnv_phb *phb = pe-phb;
+   unsigned long *segmap = NULL;
+   unsigned long *pe_segmap = NULL;
+   int segno, limit, mod = 0;
+
+   switch (win) {
+   case OPAL_IO_WINDOW_TYPE:
+   segmap = phb-ioda.io_segmap;
+   pe_segmap = pe-io_segmap;
+   break;
+   case OPAL_M32_WINDOW_TYPE:
+   segmap = 

Re: [PATCH V2 2/6] powerpc/powernv: simplify the calculation of iov resource

2015-08-05 Thread Gavin Shan
On Wed, Aug 05, 2015 at 09:24:59AM +0800, Wei Yang wrote:
The alignment of IOV BAR on PowerNV platform is the total size of the IOV
BAR. No matter whether the IOV BAR is truncated or not, the total size
could be calculated by (vfs_expanded * VF size).


s/VF size/VF BAR size

I think the changelog would be more explicit:

The alignment of IOV BAR on PowerNV platform is the total size of the
IOV BAR, no matter whether the IOV BAR is extended with number of max
VFs or number of max PE number (256). The alignment can be calculated
by (vfs_expaned * VF_BAR_size).

This patch simplifies the pnv_pci_iov_resource_alignment() by removing the
first case.

Signed-off-by: Wei Yang weiy...@linux.vnet.ibm.com

Reviewed-by: Gavin Shan gws...@linux.vnet.ibm.com

---
 arch/powerpc/platforms/powernv/pci-ioda.c |   14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 9b41dba..7192e62 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -2987,12 +2987,16 @@ static resource_size_t 
pnv_pci_iov_resource_alignment(struct pci_dev *pdev,
 int resno)
 {
   struct pci_dn *pdn = pci_get_pdn(pdev);
-  resource_size_t align, iov_align;
-
-  iov_align = resource_size(pdev-resource[resno]);
-  if (iov_align)
-  return iov_align;
+  resource_size_t align;

+  /*
+   * On PowerNV platform, IOV BAR is mapped by M64 BAR to enable the
+   * SR-IOV. While from hardware perspective, the range mapped by M64
+   * BAR should be size aligned.
+   *
+   * This function return the total IOV BAR size if expanded or just the
+   * individual size if not.
+   */
   align = pci_iov_resource_size(pdev, resno);
   if (pdn-vfs_expanded)
   return pdn-vfs_expanded * align;
-- 
1.7.9.5


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH 3/3] PowerPC/mpc85xx: Add hotplug support on E6500 cores

2015-08-05 Thread Scott Wood
On Thu, 2015-08-06 at 12:32 +0800, Chenhui Zhao wrote:
 On Thu, Aug 6, 2015 at 11:16 AM, Scott Wood scottw...@freescale.com 
 wrote:
  On Wed, 2015-08-05 at 19:08 +0800, Chenhui Zhao wrote:
On Sat, Aug 1, 2015 at 8:22 AM, Scott Wood scottw...@freescale.com
wrote:
 On Fri, 2015-07-31 at 17:20 +0800,  b29983@freescale.comwrote:
   + /*
   +  * If both threads are offline, reset core to 
   start.
   +  * When core is up, Thread 0 always gets up 
   first,
   +  * so bind the current logical cpu with Thread 0.
   +  */
   + if (hw_cpu != cpu_first_thread_sibling(hw_cpu)) {
   + int hw_cpu1, hw_cpu2;
   +
   + hw_cpu1 = 
   get_hard_smp_processor_id(primary);
   + hw_cpu2 = 
   get_hard_smp_processor_id(primary +
  1);
   + set_hard_smp_processor_id(primary, 
   hw_cpu2);
   + set_hard_smp_processor_id(primary + 1,
  hw_cpu1);
   + /* get new physical cpu id */
   + hw_cpu = get_hard_smp_processor_id(nr);

 NACK as discussed in http://patchwork.ozlabs.org/patch/454944/

 -Scott
   
You said,
   
There's no need for this. I have booting from a thread1, and 
   having
it
kick its thread0, working locally without messing with the 
   hwid/cpu
mapping.
   
I still have questions here. After a core reset, how can you boot
Thread1
of the core first. As I know, Thread0 boots up first by default.
  
  So the issue isn't that thread1 comes up first, but that you *want* 
  thread1
  to come up first and it won't.  I don't think this remapping is an 
  acceptable
  answer, though.  Instead, if you need only thread1 to come up, start 
  the
  core, have thread0 start thread1, and then send thread0 into whatever 
  waiting
  state it would be in if thread1 had never been offlined.
  
  -Scott
 
 Remapping is a concise solution. what's the harm of it?
 Keeping things simple is good in my opinion.

Remapping is not simple.  Remapping will make debugging more complicated (I 
see an oops on CPU n, which CPU's registers do I dump in the debugger?), 
could expose bugs where smp_processor_id() is used where 
hard_smp_processor_id() is needed, etc.

Having thread0 start thread1 and then go wherever it would have gone if 
thread1 were up the whole time is much more straightforward.

-Scott


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

  1   2   >