Re: [PATCH] powerpc/powernv/prd: Unregister OPAL_MSG_PRD2 notifier during module unload

2021-10-28 Thread Vasant Hegde

On 10/1/21 11:40 AM, Daniel Axtens wrote:

Hi Vasant,


Commit 587164cd, introduced new opal message type (OPAL_MSG_PRD2) and added
opal notifier. But I missed to unregister the notifier during module unload
path. This results in below call trace if you try to unload and load
opal_prd module.

Fixes: 587164cd ("powerpc/powernv: Add new opal message type")


In reviewing this patch, I've become a bit worried the underlying patch
has another issue that we should fix.


Thanks for the review. I have addressed below comments in v2.

-Vasant



[PATCH v2] powerpc/powernv/prd: Unregister OPAL_MSG_PRD2 notifier during module unload

2021-10-28 Thread Vasant Hegde
Commit 587164cd, introduced new opal message type (OPAL_MSG_PRD2) and added
opal notifier. But I missed to unregister the notifier during module unload
path. This results in below call trace if you try to unload and load
opal_prd module.

Also add new notifier_block for OPAL_MSG_PRD2 message.

Sample calltrace (modprobe -r opal_prd; modprobe opal_prd)
  [  213.335261] BUG: Unable to handle kernel data access on read at 
0xc008192200e0
  [  213.335287] Faulting instruction address: 0xc018d1cc
  [  213.335301] Oops: Kernel access of bad area, sig: 11 [#1]
  [  213.335313] LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA PowerNV
  [  213.335736] CPU: 66 PID: 7446 Comm: modprobe Kdump: loaded Tainted: G  
  E 5.14.0prd #759
  [  213.335772] NIP:  c018d1cc LR: c018d2a8 CTR: 
c00cde10
  [  213.335805] REGS: c003c4c0f0a0 TRAP: 0300   Tainted: GE
  (5.14.0prd)
  [  213.335848] MSR:  92009033   CR: 
24224824  XER: 2004
  [  213.335893] CFAR: c018d2a4 DAR: c008192200e0 DSISR: 4000 
IRQMASK: 1
  [  213.335893] GPR00: c018d2a8 c003c4c0f340 c1995300 
c1a5ad08
  [  213.335893] GPR04: c0080e3700d0 c003c4c0f434 c10a8c08 
6e616d65
  [  213.335893] GPR08:  c008192200d0 0001 
c0080e351020
  [  213.335893] GPR12: c00cde10 c00ecb80 c003c4c0fd00 

  [  213.335893] GPR16: 0990 c0080d95 c0080d950990 
c103fd10
  [  213.335893] GPR20: c003c4c0fbc0 0001 c003c4c0fbc0 
c0080e370498
  [  213.335893] GPR24:  c0dab5c8 c1a5ad18 
c1a5ac80
  [  213.335893] GPR28: 0008 0001 c1a5ad00 
c1a5ad00
  [  213.336170] NIP [c018d1cc] notifier_chain_register+0x2c/0xc0
  [  213.336205] LR [c018d2a8] atomic_notifier_chain_register+0x48/0x80
  [  213.336238] Call Trace:
  [  213.336255] [c003c4c0f340] [c2090610] 0xc2090610 
(unreliable)
  [  213.336281] [c003c4c0f3a0] [c018d2b8] 
atomic_notifier_chain_register+0x58/0x80
  [  213.336309] [c003c4c0f3f0] [c00cde8c] 
opal_message_notifier_register+0x7c/0x1e0
  [  213.336345] [c003c4c0f4b0] [c0080e3508ac] 
opal_prd_probe+0x84/0x150 [opal_prd]
  [  213.336382] [c003c4c0f530] [c097acc8] platform_probe+0x78/0x130
  [  213.336416] [c003c4c0f5b0] [c0976520] really_probe+0x110/0x5d0
  [  213.336467] [c003c4c0f630] [c0976b5c] 
__driver_probe_device+0x17c/0x230
  [  213.336512] [c003c4c0f6b0] [c0976c70] 
driver_probe_device+0x60/0x130
  [  213.336556] [c003c4c0f700] [c097746c] 
__driver_attach+0xfc/0x220
  [  213.336592] [c003c4c0f780] [c0972e68] 
bus_for_each_dev+0xa8/0x130
  [  213.336627] [c003c4c0f7e0] [c0975b04] driver_attach+0x34/0x50
  [  213.336661] [c003c4c0f800] [c0974e20] 
bus_add_driver+0x1b0/0x300
  [  213.336696] [c003c4c0f890] [c0978468] 
driver_register+0x98/0x1a0
  [  213.336732] [c003c4c0f900] [c097a878] 
__platform_driver_register+0x38/0x50
  [  213.336768] [c003c4c0f920] [c0080e350dc0] 
opal_prd_driver_init+0x34/0x50 [opal_prd]
  [  213.336804] [c003c4c0f940] [c0012410] 
do_one_initcall+0x60/0x2d0
  [  213.336821] [c003c4c0fa10] [c0262c8c] do_init_module+0x7c/0x320
  [  213.336845] [c003c4c0fa90] [c0266544] load_module+0x3394/0x3650
  [  213.336880] [c003c4c0fc90] [c0266b34] 
__do_sys_finit_module+0xd4/0x160
  [  213.336914] [c003c4c0fdb0] [c0031e00] 
system_call_exception+0x140/0x290
  [  213.336958] [c003c4c0fe10] [c000c764] 
system_call_common+0xf4/0x258

Fixes: 587164cd ("powerpc/powernv: Add new opal message type")
Signed-off-by: Vasant Hegde 
---
 arch/powerpc/platforms/powernv/opal-prd.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/opal-prd.c 
b/arch/powerpc/platforms/powernv/opal-prd.c
index a191f4c60ce7..113bdb151f68 100644
--- a/arch/powerpc/platforms/powernv/opal-prd.c
+++ b/arch/powerpc/platforms/powernv/opal-prd.c
@@ -369,6 +369,12 @@ static struct notifier_block opal_prd_event_nb = {
.priority   = 0,
 };
 
+static struct notifier_block opal_prd_event_nb2 = {
+   .notifier_call  = opal_prd_msg_notifier,
+   .next   = NULL,
+   .priority   = 0,
+};
+
 static int opal_prd_probe(struct platform_device *pdev)
 {
int rc;
@@ -390,9 +396,10 @@ static int opal_prd_probe(struct platform_device *pdev)
return rc;
}
 
-   rc = opal_message_notifier_register(OPAL_MSG_PRD2, &opal_prd_event_nb);
+   rc = opal_message_notifier_register(OPAL_MSG_PRD2, &opal_prd_event_nb2);
if (rc) {
pr_err("Could

[PATCH] powerpc/powernv/prd: Unregister OPAL_MSG_PRD2 notifier during module unload

2021-09-28 Thread Vasant Hegde
Commit 587164cd, introduced new opal message type (OPAL_MSG_PRD2) and added
opal notifier. But I missed to unregister the notifier during module unload
path. This results in below call trace if you try to unload and load
opal_prd module.

Sample calltrace (modprobe -r opal_prd; modprobe opal_prd)
  [  213.335261] BUG: Unable to handle kernel data access on read at 
0xc008192200e0
  [  213.335287] Faulting instruction address: 0xc018d1cc
  [  213.335301] Oops: Kernel access of bad area, sig: 11 [#1]
  [  213.335313] LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA PowerNV
  [  213.335736] CPU: 66 PID: 7446 Comm: modprobe Kdump: loaded Tainted: G  
  E 5.14.0prd #759
  [  213.335772] NIP:  c018d1cc LR: c018d2a8 CTR: 
c00cde10
  [  213.335805] REGS: c003c4c0f0a0 TRAP: 0300   Tainted: GE
  (5.14.0prd)
  [  213.335848] MSR:  92009033   CR: 
24224824  XER: 2004
  [  213.335893] CFAR: c018d2a4 DAR: c008192200e0 DSISR: 4000 
IRQMASK: 1
  [  213.335893] GPR00: c018d2a8 c003c4c0f340 c1995300 
c1a5ad08
  [  213.335893] GPR04: c0080e3700d0 c003c4c0f434 c10a8c08 
6e616d65
  [  213.335893] GPR08:  c008192200d0 0001 
c0080e351020
  [  213.335893] GPR12: c00cde10 c00ecb80 c003c4c0fd00 

  [  213.335893] GPR16: 0990 c0080d95 c0080d950990 
c103fd10
  [  213.335893] GPR20: c003c4c0fbc0 0001 c003c4c0fbc0 
c0080e370498
  [  213.335893] GPR24:  c0dab5c8 c1a5ad18 
c1a5ac80
  [  213.335893] GPR28: 0008 0001 c1a5ad00 
c1a5ad00
  [  213.336170] NIP [c018d1cc] notifier_chain_register+0x2c/0xc0
  [  213.336205] LR [c018d2a8] atomic_notifier_chain_register+0x48/0x80
  [  213.336238] Call Trace:
  [  213.336255] [c003c4c0f340] [c2090610] 0xc2090610 
(unreliable)
  [  213.336281] [c003c4c0f3a0] [c018d2b8] 
atomic_notifier_chain_register+0x58/0x80
  [  213.336309] [c003c4c0f3f0] [c00cde8c] 
opal_message_notifier_register+0x7c/0x1e0
  [  213.336345] [c003c4c0f4b0] [c0080e3508ac] 
opal_prd_probe+0x84/0x150 [opal_prd]
  [  213.336382] [c003c4c0f530] [c097acc8] platform_probe+0x78/0x130
  [  213.336416] [c003c4c0f5b0] [c0976520] really_probe+0x110/0x5d0
  [  213.336467] [c003c4c0f630] [c0976b5c] 
__driver_probe_device+0x17c/0x230
  [  213.336512] [c003c4c0f6b0] [c0976c70] 
driver_probe_device+0x60/0x130
  [  213.336556] [c003c4c0f700] [c097746c] 
__driver_attach+0xfc/0x220
  [  213.336592] [c003c4c0f780] [c0972e68] 
bus_for_each_dev+0xa8/0x130
  [  213.336627] [c003c4c0f7e0] [c0975b04] driver_attach+0x34/0x50
  [  213.336661] [c003c4c0f800] [c0974e20] 
bus_add_driver+0x1b0/0x300
  [  213.336696] [c003c4c0f890] [c0978468] 
driver_register+0x98/0x1a0
  [  213.336732] [c003c4c0f900] [c097a878] 
__platform_driver_register+0x38/0x50
  [  213.336768] [c003c4c0f920] [c0080e350dc0] 
opal_prd_driver_init+0x34/0x50 [opal_prd]
  [  213.336804] [c003c4c0f940] [c0012410] 
do_one_initcall+0x60/0x2d0
  [  213.336821] [c003c4c0fa10] [c0262c8c] do_init_module+0x7c/0x320
  [  213.336845] [c003c4c0fa90] [c0266544] load_module+0x3394/0x3650
  [  213.336880] [c003c4c0fc90] [c0266b34] 
__do_sys_finit_module+0xd4/0x160
  [  213.336914] [c003c4c0fdb0] [c0031e00] 
system_call_exception+0x140/0x290
  [  213.336958] [c003c4c0fe10] [c000c764] 
system_call_common+0xf4/0x258

Fixes: 587164cd ("powerpc/powernv: Add new opal message type")
Signed-off-by: Vasant Hegde 
---
 arch/powerpc/platforms/powernv/opal-prd.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/powerpc/platforms/powernv/opal-prd.c 
b/arch/powerpc/platforms/powernv/opal-prd.c
index a191f4c60ce7..83305615db9e 100644
--- a/arch/powerpc/platforms/powernv/opal-prd.c
+++ b/arch/powerpc/platforms/powernv/opal-prd.c
@@ -393,6 +393,7 @@ static int opal_prd_probe(struct platform_device *pdev)
rc = opal_message_notifier_register(OPAL_MSG_PRD2, &opal_prd_event_nb);
if (rc) {
pr_err("Couldn't register PRD2 event notifier\n");
+   opal_message_notifier_unregister(OPAL_MSG_PRD, 
&opal_prd_event_nb);
return rc;
}
 
@@ -401,6 +402,8 @@ static int opal_prd_probe(struct platform_device *pdev)
pr_err("failed to register miscdev\n");
opal_message_notifier_unregister(OPAL_MSG_PRD,
&opal_prd_event_nb);
+   opal_message_notifier_unregister(OPAL_MSG_PRD2,
+   &opal_prd_event_nb);

Re: [PATCH] powerpc/powernv/flash: Check OPAL flash calls exist before using

2021-09-14 Thread Vasant Hegde

On 9/15/21 11:53 AM, Michael Ellerman wrote:

Vasant Hegde  writes:

Currently only FSP based powernv systems supports firmware update
interfaces. Hence check that the token OPAL_FLASH_VALIDATE exists
before initalising the flash driver.

Signed-off-by: Vasant Hegde 
---
  arch/powerpc/platforms/powernv/opal-flash.c | 4 
  1 file changed, 4 insertions(+)

diff --git a/arch/powerpc/platforms/powernv/opal-flash.c 
b/arch/powerpc/platforms/powernv/opal-flash.c
index 7e7d38b17420..05490fc22fae 100644
--- a/arch/powerpc/platforms/powernv/opal-flash.c
+++ b/arch/powerpc/platforms/powernv/opal-flash.c
@@ -520,6 +520,10 @@ void __init opal_flash_update_init(void)
  {
int ret;
  
+	/* Firmware update is not supported by firmware */

+   if (!opal_check_token(OPAL_FLASH_VALIDATE))
+   return;
+




Michael,


That will mean the following files no longer appear on BMC systems:

   /sys/firmware/opal/image
   /sys/firmware/opal/validate_flash
   /sys/firmware/opal/manage_flash
   /sys/firmware/opal/update_flash

Presumably those files don't actually work correctly, but are we sure
their mere existence isn't used by anything at all?


That's correct. We never used these files/interfaces on BMC based systems.



We've had trouble in the past where removing sysfs files breaks tools
unexpectedly, see smt_snooze_delay.


AFAIK only update_flash uses these interfaces on baremetal systems.
This change shouldn't break update_flash as these interfaces never used/worked
on BMC based powernv systems.

-Vasant



Re: [PATCH] powerpc/powernv/flash: Check OPAL flash calls exist before using

2021-09-14 Thread Vasant Hegde

On 9/15/21 11:53 AM, Michael Ellerman wrote:

Vasant Hegde  writes:

Currently only FSP based powernv systems supports firmware update
interfaces. Hence check that the token OPAL_FLASH_VALIDATE exists
before initalising the flash driver.

Signed-off-by: Vasant Hegde 
---
  arch/powerpc/platforms/powernv/opal-flash.c | 4 
  1 file changed, 4 insertions(+)

diff --git a/arch/powerpc/platforms/powernv/opal-flash.c 
b/arch/powerpc/platforms/powernv/opal-flash.c
index 7e7d38b17420..05490fc22fae 100644
--- a/arch/powerpc/platforms/powernv/opal-flash.c
+++ b/arch/powerpc/platforms/powernv/opal-flash.c
@@ -520,6 +520,10 @@ void __init opal_flash_update_init(void)
  {
int ret;
  
+	/* Firmware update is not supported by firmware */

+   if (!opal_check_token(OPAL_FLASH_VALIDATE))
+   return;
+




Michael,


That will mean the following files no longer appear on BMC systems:

   /sys/firmware/opal/image
   /sys/firmware/opal/validate_flash
   /sys/firmware/opal/manage_flash
   /sys/firmware/opal/update_flash

Presumably those files don't actually work correctly, but are we sure
their mere existence isn't used by anything at all?


That's correct. We never used these files/interfaces on BMC based systems.



We've had trouble in the past where removing sysfs files breaks tools
unexpectedly, see smt_snooze_delay.


AFAIK only update_flash uses these interfaces on baremetal systems.
This change shouldn't break update_flash as these interfaces never used/worked
on BMC based powernv systems.

-Vasant



[PATCH trivial v2] powerpc/powernv/dump: Fix typo in comment

2021-09-14 Thread Vasant Hegde
Signed-off-by: Vasant Hegde 
---
 arch/powerpc/platforms/powernv/opal-dump.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/opal-dump.c 
b/arch/powerpc/platforms/powernv/opal-dump.c
index 00c5a59d82d9..717d1d30ade5 100644
--- a/arch/powerpc/platforms/powernv/opal-dump.c
+++ b/arch/powerpc/platforms/powernv/opal-dump.c
@@ -419,7 +419,7 @@ void __init opal_platform_dump_init(void)
int rc;
int dump_irq;
 
-   /* ELOG not supported by firmware */
+   /* Dump not supported by firmware */
if (!opal_check_token(OPAL_DUMP_READ))
return;
 
-- 
2.31.1



[PATCH trivial] powerpc/powernv/dump: Fix typo is comment

2021-09-14 Thread Vasant Hegde
Signed-off-by: Vasant Hegde 
---
 arch/powerpc/platforms/powernv/opal-dump.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/opal-dump.c 
b/arch/powerpc/platforms/powernv/opal-dump.c
index 00c5a59d82d9..717d1d30ade5 100644
--- a/arch/powerpc/platforms/powernv/opal-dump.c
+++ b/arch/powerpc/platforms/powernv/opal-dump.c
@@ -419,7 +419,7 @@ void __init opal_platform_dump_init(void)
int rc;
int dump_irq;
 
-   /* ELOG not supported by firmware */
+   /* Dump not supported by firmware */
if (!opal_check_token(OPAL_DUMP_READ))
return;
 
-- 
2.31.1



[PATCH] powerpc/powernv/flash: Check OPAL flash calls exist before using

2021-09-14 Thread Vasant Hegde
Currently only FSP based powernv systems supports firmware update
interfaces. Hence check that the token OPAL_FLASH_VALIDATE exists
before initalising the flash driver.

Signed-off-by: Vasant Hegde 
---
 arch/powerpc/platforms/powernv/opal-flash.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/powerpc/platforms/powernv/opal-flash.c 
b/arch/powerpc/platforms/powernv/opal-flash.c
index 7e7d38b17420..05490fc22fae 100644
--- a/arch/powerpc/platforms/powernv/opal-flash.c
+++ b/arch/powerpc/platforms/powernv/opal-flash.c
@@ -520,6 +520,10 @@ void __init opal_flash_update_init(void)
 {
int ret;
 
+   /* Firmware update is not supported by firmware */
+   if (!opal_check_token(OPAL_FLASH_VALIDATE))
+   return;
+
/* Allocate validate image buffer */
validate_flash_data.buf = kzalloc(VALIDATE_BUF_SIZE, GFP_KERNEL);
if (!validate_flash_data.buf) {
-- 
2.31.1



Re: [PATCH] powerpc/powernv/elog: Reduce elog message severity

2020-10-17 Thread Vasant Hegde

On 10/9/20 10:34 AM, Michael Ellerman wrote:

Vasant Hegde  writes:

OPAL interrupts kernel whenever it has new error log. Kernel calls
interrupt handler (elog_event()) to retrieve event. elog_event makes
OPAL API call (opal_get_elog_size()) to retrieve elog info.

In some case before kernel makes opal_get_elog_size() call, it gets interrupt
again. So second time when elog_event() calls opal_get_elog_size API OPAL
returns error.


Can you give more detail there? Do you have a stack trace?


I observe below log in dmesg
  [  615.708709] ELOG: OPAL log info read failed

That means elog_event called twice for same error log event.
I don't have stack trace.



We use IRQF_ONESHOT for elog_event(), which (I thought) meant it
shouldn't be called again until it has completed.


Yes. I thought so.. But once in a while we get above message (mostly when we 
have multiple event bits are set).


-Vasant




So I'm unclear how you're seeing the behaviour you describe.

cheers


Its safe to ignore this error. Hence reduce the severity
of log message.

CC: Mahesh Salgaonkar 
Signed-off-by: Vasant Hegde 
---
  arch/powerpc/platforms/powernv/opal-elog.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/opal-elog.c 
b/arch/powerpc/platforms/powernv/opal-elog.c
index 62ef7ad995da..67f435bb1ec4 100644
--- a/arch/powerpc/platforms/powernv/opal-elog.c
+++ b/arch/powerpc/platforms/powernv/opal-elog.c
@@ -247,7 +247,7 @@ static irqreturn_t elog_event(int irq, void *data)
  
  	rc = opal_get_elog_size(&id, &size, &type);

if (rc != OPAL_SUCCESS) {
-   pr_err("ELOG: OPAL log info read failed\n");
+   pr_debug("ELOG: OPAL log info read failed\n");
return IRQ_HANDLED;
}
  
--

2.26.2




[PATCH] powerpc/powernv/dump: Handle multiple writes to ack attribute

2020-10-17 Thread Vasant Hegde
Even though we use self removing sysfs helper, we still need
to make sure we do the final kobject delete conditionally.
sysfs_remove_file_self() will handle parallel calls to remove
the sysfs attribute file and returns true only in the caller
that removed the attribute file. The other parallel callers
are returned false. Do the final kobject delete checking
the return value of sysfs_remove_file_self().

Cc: Aneesh Kumar K.V 
Cc: Mahesh Salgaonkar 
Signed-off-by: Vasant Hegde 
---
 arch/powerpc/platforms/powernv/opal-dump.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-dump.c 
b/arch/powerpc/platforms/powernv/opal-dump.c
index 0e6693bacb7e..00c5a59d82d9 100644
--- a/arch/powerpc/platforms/powernv/opal-dump.c
+++ b/arch/powerpc/platforms/powernv/opal-dump.c
@@ -88,9 +88,14 @@ static ssize_t dump_ack_store(struct dump_obj *dump_obj,
  const char *buf,
  size_t count)
 {
-   dump_send_ack(dump_obj->id);
-   sysfs_remove_file_self(&dump_obj->kobj, &attr->attr);
-   kobject_put(&dump_obj->kobj);
+   /*
+* Try to self remove this attribute. If we are successful,
+* delete the kobject itself.
+*/
+   if (sysfs_remove_file_self(&dump_obj->kobj, &attr->attr)) {
+   dump_send_ack(dump_obj->id);
+   kobject_put(&dump_obj->kobj);
+   }
return count;
 }
 
-- 
2.26.2



[PATCH v2] powerpc/powernv/dump: Fix race while processing OPAL dump

2020-10-17 Thread Vasant Hegde
Every dump reported by OPAL is exported to userspace through a sysfs
interface and notified using kobject_uevent(). The userspace daemon
(opal_errd) then reads the dump and acknowledges that the dump is
saved safely to disk. Once acknowledged the kernel removes the
respective sysfs file entry causing respective resources to be
released including kobject.

However it's possible the userspace daemon may already be scanning
dump entries when a new sysfs dump entry is created by the kernel.
User daemon may read this new entry and ack it even before kernel can
notify userspace about it through kobject_uevent() call. If that
happens then we have a potential race between
dump_ack_store->kobject_put() and kobject_uevent which can lead to
use-after-free of a kernfs object resulting in a kernel crash.

This patch fixes this race by protecting the sysfs file
creation/notification by holding a reference count on kobject until we
safely send kobject_uevent().

The function create_dump_obj() returns the dump object which if used
by caller function will end up in use-after-free problem again.
However, the return value of create_dump_obj() function isn't being
used today and there is no need as well. Hence change it to return
void to make this fix complete.

Fixes: c7e64b9c ("powerpc/powernv Platform dump interface")
CC: Mahesh Salgaonkar 
Signed-off-by: Vasant Hegde 
---
 arch/powerpc/platforms/powernv/opal-dump.c | 41 +++---
 1 file changed, 29 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-dump.c 
b/arch/powerpc/platforms/powernv/opal-dump.c
index 543c816fa99e..0e6693bacb7e 100644
--- a/arch/powerpc/platforms/powernv/opal-dump.c
+++ b/arch/powerpc/platforms/powernv/opal-dump.c
@@ -318,15 +318,14 @@ static ssize_t dump_attr_read(struct file *filep, struct 
kobject *kobj,
return count;
 }
 
-static struct dump_obj *create_dump_obj(uint32_t id, size_t size,
-   uint32_t type)
+static void create_dump_obj(uint32_t id, size_t size, uint32_t type)
 {
struct dump_obj *dump;
int rc;
 
dump = kzalloc(sizeof(*dump), GFP_KERNEL);
if (!dump)
-   return NULL;
+   return;
 
dump->kobj.kset = dump_kset;
 
@@ -346,21 +345,39 @@ static struct dump_obj *create_dump_obj(uint32_t id, 
size_t size,
rc = kobject_add(&dump->kobj, NULL, "0x%x-0x%x", type, id);
if (rc) {
kobject_put(&dump->kobj);
-   return NULL;
+   return;
}
 
+   /*
+* As soon as the sysfs file for this dump is created/activated there is
+* a chance the opal_errd daemon (or any userspace) might read and
+* acknowledge the dump before kobject_uevent() is called. If that
+* happens then there is a potential race between
+* dump_ack_store->kobject_put() and kobject_uevent() which leads to a
+* use-after-free of a kernfs object resulting in a kernel crash.
+*
+* To avoid that, we need to take a reference on behalf of the bin file,
+* so that our reference remains valid while we call kobject_uevent().
+* We then drop our reference before exiting the function, leaving the
+* bin file to drop the last reference (if it hasn't already).
+*/
+
+   /* Take a reference for the bin file */
+   kobject_get(&dump->kobj);
rc = sysfs_create_bin_file(&dump->kobj, &dump->dump_attr);
-   if (rc) {
+   if (rc == 0) {
+   kobject_uevent(&dump->kobj, KOBJ_ADD);
+
+   pr_info("%s: New platform dump. ID = 0x%x Size %u\n",
+   __func__, dump->id, dump->size);
+   } else {
+   /* Drop reference count taken for bin file */
kobject_put(&dump->kobj);
-   return NULL;
}
 
-   pr_info("%s: New platform dump. ID = 0x%x Size %u\n",
-   __func__, dump->id, dump->size);
-
-   kobject_uevent(&dump->kobj, KOBJ_ADD);
-
-   return dump;
+   /* Drop our reference */
+   kobject_put(&dump->kobj);
+   return;
 }
 
 static irqreturn_t process_dump(int irq, void *data)
-- 
2.26.2



Re: [PATCH] powerpc/powernv/dump: Fix race while processing OPAL dump

2020-10-17 Thread Vasant Hegde

On 10/9/20 10:36 AM, Michael Ellerman wrote:

Vasant Hegde  writes:

diff --git a/arch/powerpc/platforms/powernv/opal-dump.c 
b/arch/powerpc/platforms/powernv/opal-dump.c
index 543c816fa99e..7e6eeedec32b 100644
--- a/arch/powerpc/platforms/powernv/opal-dump.c
+++ b/arch/powerpc/platforms/powernv/opal-dump.c
@@ -346,21 +345,39 @@ static struct dump_obj *create_dump_obj(uint32_t id, 
size_t size,
rc = kobject_add(&dump->kobj, NULL, "0x%x-0x%x", type, id);
if (rc) {
kobject_put(&dump->kobj);
-   return NULL;
+   return;
}
  
+	/*

+* As soon as the sysfs file for this dump is created/activated there is
+* a chance the opal_errd daemon (or any userspace) might read and
+* acknowledge the dump before kobject_uevent() is called. If that
+* happens then there is a potential race between
+* dump_ack_store->kobject_put() and kobject_uevent() which leads to a
+* use-after-free of a kernfs object resulting in a kernel crash.
+*
+* To avoid that, we need to take a reference on behalf of the bin file,
+* so that our reference remains valid while we call kobject_uevent().
+* We then drop our reference before exiting the function, leaving the
+* bin file to drop the last reference (if it hasn't already).
+*/
+
+   /* Take a reference for the bin file */
+   kobject_get(&dump->kobj);
rc = sysfs_create_bin_file(&dump->kobj, &dump->dump_attr);
if (rc) {
kobject_put(&dump->kobj);
-   return NULL;
+   /* Drop reference count taken for bin file */
+   kobject_put(&dump->kobj);
+   return;
}
  
  	pr_info("%s: New platform dump. ID = 0x%x Size %u\n",

__func__, dump->id, dump->size);
  
  	kobject_uevent(&dump->kobj, KOBJ_ADD);

-
-   return dump;
+   /* Drop reference count taken for bin file */
+   kobject_put(&dump->kobj);
  }


I think this would be better if it was reworked along the lines of:

aea948bb80b4 ("powerpc/powernv/elog: Fix race while processing OPAL error log 
event.")


Sure. Will fix it in v2.

-Vasant


[PATCH] powerpc/powernv/elog: Reduce elog message severity

2020-10-07 Thread Vasant Hegde
OPAL interrupts kernel whenever it has new error log. Kernel calls
interrupt handler (elog_event()) to retrieve event. elog_event makes
OPAL API call (opal_get_elog_size()) to retrieve elog info.

In some case before kernel makes opal_get_elog_size() call, it gets interrupt
again. So second time when elog_event() calls opal_get_elog_size API OPAL
returns error. Its safe to ignore this error. Hence reduce the severity
of log message.

CC: Mahesh Salgaonkar 
Signed-off-by: Vasant Hegde 
---
 arch/powerpc/platforms/powernv/opal-elog.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/opal-elog.c 
b/arch/powerpc/platforms/powernv/opal-elog.c
index 62ef7ad995da..67f435bb1ec4 100644
--- a/arch/powerpc/platforms/powernv/opal-elog.c
+++ b/arch/powerpc/platforms/powernv/opal-elog.c
@@ -247,7 +247,7 @@ static irqreturn_t elog_event(int irq, void *data)
 
rc = opal_get_elog_size(&id, &size, &type);
if (rc != OPAL_SUCCESS) {
-   pr_err("ELOG: OPAL log info read failed\n");
+   pr_debug("ELOG: OPAL log info read failed\n");
return IRQ_HANDLED;
}
 
-- 
2.26.2



[PATCH] powerpc/powernv/dump: Fix race while processing OPAL dump

2020-10-07 Thread Vasant Hegde
Every dump reported by OPAL is exported to userspace through a sysfs
interface and notified using kobject_uevent(). The userspace daemon
(opal_errd) then reads the dump and acknowledges that the dump is
saved safely to disk. Once acknowledged the kernel removes the
respective sysfs file entry causing respective resources to be
released including kobject.

However it's possible the userspace daemon may already be scanning
dump entries when a new sysfs dump entry is created by the kernel.
User daemon may read this new entry and ack it even before kernel can
notify userspace about it through kobject_uevent() call. If that
happens then we have a potential race between
dump_ack_store->kobject_put() and kobject_uevent which can lead to
use-after-free of a kernfs object resulting in a kernel crash.

This patch fixes this race by protecting the sysfs file
creation/notification by holding a reference count on kobject until we
safely send kobject_uevent().

The function create_dump_obj() returns the dump object which if used
by caller function will end up in use-after-free problem again.
However, the return value of create_dump_obj() function isn't being
used today and there is no need as well. Hence change it to return
void to make this fix complete.

Fixes: c7e64b9c ("powerpc/powernv Platform dump interface")
CC: Mahesh Salgaonkar 
Signed-off-by: Vasant Hegde 
---
 arch/powerpc/platforms/powernv/opal-dump.c | 31 +-
 1 file changed, 24 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-dump.c 
b/arch/powerpc/platforms/powernv/opal-dump.c
index 543c816fa99e..7e6eeedec32b 100644
--- a/arch/powerpc/platforms/powernv/opal-dump.c
+++ b/arch/powerpc/platforms/powernv/opal-dump.c
@@ -318,15 +318,14 @@ static ssize_t dump_attr_read(struct file *filep, struct 
kobject *kobj,
return count;
 }
 
-static struct dump_obj *create_dump_obj(uint32_t id, size_t size,
-   uint32_t type)
+static void create_dump_obj(uint32_t id, size_t size, uint32_t type)
 {
struct dump_obj *dump;
int rc;
 
dump = kzalloc(sizeof(*dump), GFP_KERNEL);
if (!dump)
-   return NULL;
+   return;
 
dump->kobj.kset = dump_kset;
 
@@ -346,21 +345,39 @@ static struct dump_obj *create_dump_obj(uint32_t id, 
size_t size,
rc = kobject_add(&dump->kobj, NULL, "0x%x-0x%x", type, id);
if (rc) {
kobject_put(&dump->kobj);
-   return NULL;
+   return;
}
 
+   /*
+* As soon as the sysfs file for this dump is created/activated there is
+* a chance the opal_errd daemon (or any userspace) might read and
+* acknowledge the dump before kobject_uevent() is called. If that
+* happens then there is a potential race between
+* dump_ack_store->kobject_put() and kobject_uevent() which leads to a
+* use-after-free of a kernfs object resulting in a kernel crash.
+*
+* To avoid that, we need to take a reference on behalf of the bin file,
+* so that our reference remains valid while we call kobject_uevent().
+* We then drop our reference before exiting the function, leaving the
+* bin file to drop the last reference (if it hasn't already).
+*/
+
+   /* Take a reference for the bin file */
+   kobject_get(&dump->kobj);
rc = sysfs_create_bin_file(&dump->kobj, &dump->dump_attr);
if (rc) {
kobject_put(&dump->kobj);
-   return NULL;
+   /* Drop reference count taken for bin file */
+   kobject_put(&dump->kobj);
+   return;
}
 
pr_info("%s: New platform dump. ID = 0x%x Size %u\n",
__func__, dump->id, dump->size);
 
kobject_uevent(&dump->kobj, KOBJ_ADD);
-
-   return dump;
+   /* Drop reference count taken for bin file */
+   kobject_put(&dump->kobj);
 }
 
 static irqreturn_t process_dump(int irq, void *data)
-- 
2.26.2



Re: [PATCH v2] powernv/elog: Fix the race while processing OPAL error log event.

2020-10-05 Thread Vasant Hegde

On 10/6/20 5:55 AM, Oliver O'Halloran wrote:

On Mon, Oct 5, 2020 at 3:12 PM Mahesh Salgaonkar  wrote:


Every error log reported by OPAL is exported to userspace through a sysfs
interface and notified using kobject_uevent(). The userspace daemon
(opal_errd) then reads the error log and acknowledges it error log is saved
safely to disk. Once acknowledged the kernel removes the respective sysfs
file entry causing respective resources getting released including kobject.

However there are chances where user daemon may already be scanning elog
entries while new sysfs elog entry is being created by kernel. User daemon
may read this new entry and ack it even before kernel can notify userspace
about it through kobject_uevent() call. If that happens then we have a
potential race between elog_ack_store->kobject_put() and kobject_uevent
which can lead to use-after-free issue of a kernfs object resulting into a
kernel crash. This patch fixes this race by protecting a sysfs file
creation/notification by holding an additional reference count on kobject
until we safely send kobject_uevent().

Reported-by: Oliver O'Halloran 
Signed-off-by: Mahesh Salgaonkar 
Signed-off-by: Aneesh Kumar K.V 
---
Change in v2:
- Instead of mutex and use extra reference count on kobject to avoid the
   race.
---
  arch/powerpc/platforms/powernv/opal-elog.c |   15 +++
  1 file changed, 15 insertions(+)

diff --git a/arch/powerpc/platforms/powernv/opal-elog.c 
b/arch/powerpc/platforms/powernv/opal-elog.c
index 62ef7ad995da..230f102e87c0 100644
--- a/arch/powerpc/platforms/powernv/opal-elog.c
+++ b/arch/powerpc/platforms/powernv/opal-elog.c
@@ -222,13 +222,28 @@ static struct elog_obj *create_elog_obj(uint64_t id, 
size_t size, uint64_t type)
 return NULL;
 }

+   /*
+* As soon as sysfs file for this elog is created/activated there is
+* chance opal_errd daemon might read and acknowledge this elog before
+* kobject_uevent() is called. If that happens then we have a potential
+* race between elog_ack_store->kobject_put() and kobject_uevent which
+* leads to use-after-free issue of a kernfs object resulting into
+* kernel crash. To avoid this race take an additional reference count
+* on kobject until we safely send kobject_uevent().
+*/
+
+   kobject_get(&elog->kobj);  /* extra reference count */
 rc = sysfs_create_bin_file(&elog->kobj, &elog->raw_attr);
 if (rc) {
+   kobject_put(&elog->kobj);
+   /* Drop the extra reference count  */
 kobject_put(&elog->kobj);
 return NULL;
 }

 kobject_uevent(&elog->kobj, KOBJ_ADD);
+   /* Drop the extra reference count  */
+   kobject_put(&elog->kobj);


Makes sense,

Reviewed-by: Oliver O'Halloran 


Reviewed-by: Vasant Hegde 





 return elog;


Does the returned value actually get used anywhere? We'd have a
similar use-after-free problem if it does. This should probably return
an error code rather than the object itself.


No one is using it today. May be we should just make it void function.

-Vasant


[PATCH v2] powerpc/pseries: Do not initiate shutdown when system is running on UPS

2020-08-19 Thread Vasant Hegde
As per PAPR we have to look for both EPOW sensor value and event modifier to
identify type of event and take appropriate action.

Sensor value = 3 (EPOW_SYSTEM_SHUTDOWN) schedule system to be shutdown after
  OS defined delay (default 10 mins).

EPOW Event Modifier for sensor value = 3:
   We have to initiate immediate shutdown for most of the event modifier except
   value = 2 (system running on UPS).

Checking with firmware document its clear that we have to wait for predefined
time before initiating shutdown. If power is restored within time we should
cancel the shutdown process. I think commit 79872e35 accidently enabled
immediate poweroff for EPOW_SHUTDOWN_ON_UPS event.

We have user space tool (rtas_errd) on LPAR to monitor for EPOW_SHUTDOWN_ON_UPS.
Once it gets event it initiates shutdown after predefined time. Also starts
monitoring for any new EPOW events. If it receives "Power restored" event
before predefined time it will cancel the shutdown. Otherwise after
predefined time it will shutdown the system.

Fixes: 79872e35 (powerpc/pseries: All events of EPOW_SYSTEM_SHUTDOWN must 
initiate shutdown)
Cc: sta...@vger.kernel.org # v4.0+
Cc: Tyrel Datwyler 
Cc: Michael Ellerman 
Signed-off-by: Vasant Hegde 
---
Changes in v2:
  - Updated patch description based on mpe, Tyrel comment.

-Vasant
 arch/powerpc/platforms/pseries/ras.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/powerpc/platforms/pseries/ras.c 
b/arch/powerpc/platforms/pseries/ras.c
index f3736fcd98fc..13c86a292c6d 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -184,7 +184,6 @@ static void handle_system_shutdown(char event_modifier)
case EPOW_SHUTDOWN_ON_UPS:
pr_emerg("Loss of system power detected. System is running on"
 " UPS/battery. Check RTAS error log for details\n");
-   orderly_poweroff(true);
break;
 
case EPOW_SHUTDOWN_LOSS_OF_CRITICAL_FUNCTIONS:
-- 
2.26.2



Re: [PATCH] powerpc/pseries: Do not initiate shutdown when system is running on UPS

2020-08-18 Thread Vasant Hegde

On 8/19/20 1:05 AM, Tyrel Datwyler wrote:

On 8/18/20 3:54 AM, Vasant Hegde wrote:

As per PAPR specification whenever system is running on UPS we have to
wait for predefined time (default 10mins) before initiating shutdown.


The wording in PAPR seems a little unclear. It states for an
EPOW_SYSTEM_SHUTDOWN action code that an EPOW error should be logged followed by
scheduling a shutdown to begin after an OS defined delay interval (with 10
minutes the suggested default).

However, the modifier code descriptions seems to imply that a normal shutdown is
the only one that should happen with no additional delay.

For EPOW sensor value = 3 (EPOW_SYSTEM_SHUTDOWN)
0x01 = Normal system shutdown with no additional delay
0x02 = Loss of utility power, system is running on UPS/Battery
0x03 = Loss of system critical functions, system should be shutdown
0x04 = Ambient temperature too high

For 0x03-0x04 we also do an orderly_poweroff().

Not sure if it really matters, but I was curious and this is just what I gleaned
from glancing at PAPR.


Correct. PAPR is bit confusing. But we know for sure that when running on UPS we 
don't need to shutdown immediately.


For values 0x03 and 0x04 I think its ok to initiate shutdown (that's the same 
behaviour exists for long time). I can double check with firmware folks.


-Vasant



-Tyrel



We have user space tool (rtas_errd) to monitor for EPOW events and
initiate shutdown after predefined time. Hence do not initiate shutdown
whenever we get EPOW_SHUTDOWN_ON_UPS event.

Fixes: 79872e35 (powerpc/pseries: All events of EPOW_SYSTEM_SHUTDOWN must 
initiate shutdown)
Cc: sta...@vger.kernel.org # v4.0+
Cc: Michael Ellerman 
Signed-off-by: Vasant Hegde 
---
  arch/powerpc/platforms/pseries/ras.c | 1 -
  1 file changed, 1 deletion(-)

diff --git a/arch/powerpc/platforms/pseries/ras.c 
b/arch/powerpc/platforms/pseries/ras.c
index f3736fcd98fc..13c86a292c6d 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -184,7 +184,6 @@ static void handle_system_shutdown(char event_modifier)
case EPOW_SHUTDOWN_ON_UPS:
pr_emerg("Loss of system power detected. System is running on"
 " UPS/battery. Check RTAS error log for details\n");
-   orderly_poweroff(true);
break;

case EPOW_SHUTDOWN_LOSS_OF_CRITICAL_FUNCTIONS:







[PATCH] powerpc/pseries: Do not initiate shutdown when system is running on UPS

2020-08-18 Thread Vasant Hegde
As per PAPR specification whenever system is running on UPS we have to
wait for predefined time (default 10mins) before initiating shutdown.

We have user space tool (rtas_errd) to monitor for EPOW events and
initiate shutdown after predefined time. Hence do not initiate shutdown
whenever we get EPOW_SHUTDOWN_ON_UPS event.

Fixes: 79872e35 (powerpc/pseries: All events of EPOW_SYSTEM_SHUTDOWN must 
initiate shutdown)
Cc: sta...@vger.kernel.org # v4.0+
Cc: Michael Ellerman 
Signed-off-by: Vasant Hegde 
---
 arch/powerpc/platforms/pseries/ras.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/powerpc/platforms/pseries/ras.c 
b/arch/powerpc/platforms/pseries/ras.c
index f3736fcd98fc..13c86a292c6d 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -184,7 +184,6 @@ static void handle_system_shutdown(char event_modifier)
case EPOW_SHUTDOWN_ON_UPS:
pr_emerg("Loss of system power detected. System is running on"
 " UPS/battery. Check RTAS error log for details\n");
-   orderly_poweroff(true);
break;
 
case EPOW_SHUTDOWN_LOSS_OF_CRITICAL_FUNCTIONS:
-- 
2.26.2



Re: [PATCH v3] powerpc/smp: Use nid as fallback for package_id

2019-12-16 Thread Vasant Hegde

On 12/16/19 7:51 PM, Srikar Dronamraju wrote:

Package_id is to find out all cores that are part of the same chip. On
PowerNV machines, package_id defaults to chip_id. However ibm,chip_id
property is not present in device-tree of PowerVM Lpars. Hence lscpu
output shows one core per socket and multiple cores.

To overcome this, use nid as the package_id on PowerVM Lpars.

Before the patch.
---
Architecture:ppc64le
Byte Order:  Little Endian
CPU(s):  128
On-line CPU(s) list: 0-127
Thread(s) per core:  8
Core(s) per socket:  1   <--
Socket(s):   16  <--
NUMA node(s):2
Model:   2.2 (pvr 004e 0202)
Model name:  POWER9 (architected), altivec supported
Hypervisor vendor:   pHyp
Virtualization type: para
L1d cache:   32K
L1i cache:   32K
L2 cache:512K
L3 cache:10240K
NUMA node0 CPU(s):   0-63
NUMA node1 CPU(s):   64-127
  #
  # cat /sys/devices/system/cpu/cpu0/topology/physical_package_id
  -1
  #

After the patch
---
Architecture:ppc64le
Byte Order:  Little Endian
CPU(s):  128
On-line CPU(s) list: 0-127
Thread(s) per core:  8  <--
Core(s) per socket:  8  <--
Socket(s):   2
NUMA node(s):2
Model:   2.2 (pvr 004e 0202)
Model name:  POWER9 (architected), altivec supported
Hypervisor vendor:   pHyp
Virtualization type: para
L1d cache:   32K
L1i cache:   32K
L2 cache:512K
L3 cache:10240K
NUMA node0 CPU(s):   0-63
NUMA node1 CPU(s):   64-127
  #
  # cat /sys/devices/system/cpu/cpu0/topology/physical_package_id
  0
  #
Now lscpu output is more in line with the system configuration.

Signed-off-by: Srikar Dronamraju 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Michael Ellerman 
Cc: Vasant Hegde 
Cc: Vaidyanathan Srinivasan 


Looks good to me.

Reviewed-by: Vasant Hegde 

-Vasant



[PATCH] powerpc/powernv/prd: Allow copying partial data to user space

2019-10-22 Thread Vasant Hegde
Allow copying partial data to user space. So that opal-prd daemon
can read message size, reallocate memory and make read call to
get rest of the data.

Cc: Jeremy Kerr 
Cc: Vaidyanathan Srinivasan 
Signed-off-by: Vasant Hegde 
---
 arch/powerpc/platforms/powernv/opal-prd.c | 27 ---
 1 file changed, 9 insertions(+), 18 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-prd.c 
b/arch/powerpc/platforms/powernv/opal-prd.c
index 45f4223a790f..dac9d18293d8 100644
--- a/arch/powerpc/platforms/powernv/opal-prd.c
+++ b/arch/powerpc/platforms/powernv/opal-prd.c
@@ -153,20 +153,15 @@ static __poll_t opal_prd_poll(struct file *file,
 static ssize_t opal_prd_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
 {
-   struct opal_prd_msg_queue_item *item;
+   struct opal_prd_msg_queue_item *item = NULL;
unsigned long flags;
-   ssize_t size, err;
+   ssize_t size;
int rc;
 
/* we need at least a header's worth of data */
if (count < sizeof(item->msg))
return -EINVAL;
 
-   if (*ppos)
-   return -ESPIPE;
-
-   item = NULL;
-
for (;;) {
 
spin_lock_irqsave(&opal_prd_msg_queue_lock, flags);
@@ -190,27 +185,23 @@ static ssize_t opal_prd_read(struct file *file, char 
__user *buf,
}
 
size = be16_to_cpu(item->msg.size);
-   if (size > count) {
-   err = -EINVAL;
+   rc = simple_read_from_buffer(buf, count, ppos, &item->msg, size);
+   if (rc < 0)
goto err_requeue;
-   }
-
-   rc = copy_to_user(buf, &item->msg, size);
-   if (rc) {
-   err = -EFAULT;
+   if (*ppos < size)
goto err_requeue;
-   }
 
+   /* Reset position */
+   *ppos = 0;
kfree(item);
-
-   return size;
+   return rc;
 
 err_requeue:
/* eep! re-queue at the head of the list */
spin_lock_irqsave(&opal_prd_msg_queue_lock, flags);
list_add(&item->list, &opal_prd_msg_queue);
spin_unlock_irqrestore(&opal_prd_msg_queue_lock, flags);
-   return err;
+   return rc;
 }
 
 static ssize_t opal_prd_write(struct file *file, const char __user *buf,
-- 
2.21.0



Re: [PATCH] powerpc/powernv/prd: Validate whether address to be mapped is part of system RAM

2019-10-02 Thread Vasant Hegde

On 10/3/19 10:26 AM, Jeremy Kerr wrote:

Hi Vasant,


Correct. We will have `ibm,prd-label` property. That's not the issue.


It sure sounds like the issue - someone has represented a range that
should be mapped by HBRT, but isn't appropriate for mapping by HBRT.


Here issueis HBRT is loaded into NVDIMM memory.


OK. How about we just don't do that?


Yes. Hostboot will fix that. It will make sure that HBRT is loaded into regular 
memory.




It sounds like we're just trying to work around an invalid
representation of the mappings.


Its not workaround. Its additional check. So that we don't mmap() if HBRT is not 
in system RAM

and throw proper error.. So that debugging becomes easy.

-Vasant



Re: [PATCH] powerpc/powernv/prd: Validate whether address to be mapped is part of system RAM

2019-10-02 Thread Vasant Hegde

On 10/3/19 7:17 AM, Jeremy Kerr wrote:

Hi Vasant,


Jeremy,




Add check to validate whether requested page is part of system RAM
or not before mmap() and error out if its not part of system RAM.


opal_prd_range_is_valid() will return false if the reserved memory range
does not have an ibm,prd-label property. If this you're getting invalid
memory mapped through the PRD interface, that means the device tree is
incorrectly describing those ranges.


Correct. We will have `ibm,prd-label` property. That's not the issue. Here issue
is HBRT is loaded into NVDIMM memory.


Copy-pasting Vaidy's explanation from internal bugzilla here:

--
The root-cause of the problem seem to be in HBRT using NVDIMM area/addresses for 
firmware operation.


Linux maps the required address for HBRT to read, write and execute. This all 
works fine for normal RAM addresses.  However NVDIMM is not normal RAM, it is 
device memory which can be used as RAM or through other layers and subsystem.


Linux kernel memory manager set page table attributes as 0b10 non-idempotent I/O 
instead of normal RAM 0b00 since this is a special type of device memory 
initialized and used by a firmware device driver.  This prevented instruction 
execution from that mapped page.  Since instruction could not be fetched, 
opal-prd application could not complete init and start.


--

Hostboot should detect NVDIMM areas and avoid using those areas for any firmware 
purposes including HBRT. Hostboot will fix this issue.


In this patch we are adding additional check to make sure mmap() fails 
gracefully and we log proper error log. That way opal-prd will fail to start 
instead of looping forever .


-Vasant



[PATCH] powerpc/powernv/prd: Validate whether address to be mapped is part of system RAM

2019-10-02 Thread Vasant Hegde
Add check to validate whether requested page is part of system RAM
or not before mmap() and error out if its not part of system RAM.

cat /proc/iomem:
-
-27 : System RAM
28-2f : namespace0.0
2000-2027 : System RAM
2028-202f : namespace1.0
6-6003fbfff : pciex@600c3c000
60040-6007f7fff : pciex@600c3c010



Sample dmesg output with this fix:
--
[  160.371911] opal-prd: mmap: Requested page is not part of system RAM (addr : 
0x202ffcfc, size : 0x0057)
[  160.665366] opal-prd: mmap: Requested page is not part of system RAM (addr : 
0x202ffcfc, size : 0x0057)
[  160.914627] opal-prd: mmap: Requested page is not part of system RAM (addr : 
0x202ffcfc, size : 0x0057)
[  161.165253] opal-prd: mmap: Requested page is not part of system RAM (addr : 
0x202ffcfc, size : 0x0057)
[  161.414604] opal-prd: mmap: Requested page is not part of system RAM (addr : 
0x202ffcfc, size : 0x0057)

CC: Aneesh Kumar K.V 
CC: Jeremy Kerr 
CC: Vaidyanathan Srinivasan 
Signed-off-by: Vasant Hegde 
---
 arch/powerpc/platforms/powernv/opal-prd.c | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/opal-prd.c 
b/arch/powerpc/platforms/powernv/opal-prd.c
index 45f4223a790f..0f88752302a2 100644
--- a/arch/powerpc/platforms/powernv/opal-prd.c
+++ b/arch/powerpc/platforms/powernv/opal-prd.c
@@ -3,7 +3,7 @@
  * OPAL Runtime Diagnostics interface driver
  * Supported on POWERNV platform
  *
- * Copyright IBM Corporation 2015
+ * Copyright IBM Corporation 2015-2019
  */
 
 #define pr_fmt(fmt) "opal-prd: " fmt
@@ -47,6 +47,20 @@ static bool opal_prd_range_is_valid(uint64_t addr, uint64_t 
size)
if (addr + size < addr)
return false;
 
+   /*
+* Check if region is in system RAM and error out if the address
+* belongs to special devices like NVDIMM. phys_mem_access_prot()
+* routine will change ATT bits to non cachable if page is not in
+* RAM, causing HBRT to not fetch and execute in the mapped memory
+* and fail. Page permissions can be left at default since all
+* firmware component should be in system RAM only.
+*/
+   if (!page_is_ram(addr >> PAGE_SHIFT)) {
+   pr_warn("mmap: Requested page is not part of system RAM "
+   "(addr : 0x%016llx, size : 0x%016llx)\n", addr, size);
+   return false;
+   }
+
parent = of_find_node_by_path("/reserved-memory");
if (!parent)
return false;
-- 
2.21.0



[PATCH v4 1/2] powerpc/powernv: Enhance opal message read interface

2019-08-25 Thread Vasant Hegde
Use "opal-msg-size" device tree property to allocate memory for "opal_msg".

Cc: Mahesh Salgaonkar 
Cc: Jeremy Kerr 
Signed-off-by: Vasant Hegde 
---
 arch/powerpc/platforms/powernv/opal.c | 32 ++-
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index aba443be7daa..afa494849477 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -58,6 +58,8 @@ static DEFINE_SPINLOCK(opal_write_lock);
 static struct atomic_notifier_head opal_msg_notifier_head[OPAL_MSG_TYPE_MAX];
 static uint32_t opal_heartbeat;
 static struct task_struct *kopald_tsk;
+static struct opal_msg *opal_msg;
+static uint32_t opal_msg_size;
 
 void opal_configure_cores(void)
 {
@@ -271,14 +273,9 @@ static void opal_message_do_notify(uint32_t msg_type, void 
*msg)
 static void opal_handle_message(void)
 {
s64 ret;
-   /*
-* TODO: pre-allocate a message buffer depending on opal-msg-size
-* value in /proc/device-tree.
-*/
-   static struct opal_msg msg;
u32 type;
 
-   ret = opal_get_msg(__pa(&msg), sizeof(msg));
+   ret = opal_get_msg(__pa(opal_msg), opal_msg_size);
/* No opal message pending. */
if (ret == OPAL_RESOURCE)
return;
@@ -290,14 +287,14 @@ static void opal_handle_message(void)
return;
}
 
-   type = be32_to_cpu(msg.msg_type);
+   type = be32_to_cpu(opal_msg->msg_type);
 
/* Sanity check */
if (type >= OPAL_MSG_TYPE_MAX) {
pr_warn_once("%s: Unknown message type: %u\n", __func__, type);
return;
}
-   opal_message_do_notify(type, (void *)&msg);
+   opal_message_do_notify(type, (void *)opal_msg);
 }
 
 static irqreturn_t opal_message_notify(int irq, void *data)
@@ -306,10 +303,25 @@ static irqreturn_t opal_message_notify(int irq, void 
*data)
return IRQ_HANDLED;
 }
 
-static int __init opal_message_init(void)
+static int __init opal_message_init(struct device_node *opal_node)
 {
int ret, i, irq;
 
+   ret = of_property_read_u32(opal_node, "opal-msg-size", &opal_msg_size);
+   if (ret) {
+   pr_notice("%s: Failed to read opal-msg-size property\n",
+ __func__);
+   opal_msg_size = sizeof(struct opal_msg);
+   }
+
+   opal_msg = kmalloc(opal_msg_size, GFP_KERNEL);
+   if (!opal_msg) {
+   opal_msg_size = sizeof(struct opal_msg);
+   /* Try to allocate fixed message size */
+   opal_msg = kmalloc(opal_msg_size, GFP_KERNEL);
+   BUG_ON(opal_msg == NULL);
+   }
+
for (i = 0; i < OPAL_MSG_TYPE_MAX; i++)
ATOMIC_INIT_NOTIFIER_HEAD(&opal_msg_notifier_head[i]);
 
@@ -910,7 +922,7 @@ static int __init opal_init(void)
}
 
/* Initialise OPAL messaging system */
-   opal_message_init();
+   opal_message_init(opal_node);
 
/* Initialise OPAL asynchronous completion interface */
opal_async_comp_init();
-- 
2.21.0



[PATCH v4 2/2] powerpc/powernv: Add new opal message type

2019-08-25 Thread Vasant Hegde
We have OPAL_MSG_PRD message type to pass prd related messages from OPAL
to `opal-prd`. It can handle messages upto 64 bytes. We have a requirement
to send bigger than 64 bytes of data from OPAL to `opal-prd`. Lets add new
message type (OPAL_MSG_PRD2) to pass bigger data.

Cc: Jeremy Kerr 
Signed-off-by: Vasant Hegde 
---
 arch/powerpc/include/asm/opal-api.h   | 1 +
 arch/powerpc/platforms/powernv/opal-prd.c | 9 -
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/opal-api.h 
b/arch/powerpc/include/asm/opal-api.h
index 383242eb0dea..1cad413e1e0e 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -453,6 +453,7 @@ enum opal_msg_type {
OPAL_MSG_DPO= 5,
OPAL_MSG_PRD= 6,
OPAL_MSG_OCC= 7,
+   OPAL_MSG_PRD2   = 8,
OPAL_MSG_TYPE_MAX,
 };
 
diff --git a/arch/powerpc/platforms/powernv/opal-prd.c 
b/arch/powerpc/platforms/powernv/opal-prd.c
index e072bf157d62..50a735d77192 100644
--- a/arch/powerpc/platforms/powernv/opal-prd.c
+++ b/arch/powerpc/platforms/powernv/opal-prd.c
@@ -342,7 +342,7 @@ static int opal_prd_msg_notifier(struct notifier_block *nb,
int msg_size, item_size;
unsigned long flags;
 
-   if (msg_type != OPAL_MSG_PRD)
+   if (msg_type != OPAL_MSG_PRD && msg_type != OPAL_MSG_PRD2)
return 0;
 
/* Calculate total size of the message and item we need to store. The
@@ -393,6 +393,13 @@ static int opal_prd_probe(struct platform_device *pdev)
return rc;
}
 
+   rc = opal_message_notifier_register(OPAL_MSG_PRD2, &opal_prd_event_nb);
+   if (rc) {
+   pr_err("%s: Couldn't register event notifier (%d)\n",
+  __func__, OPAL_MSG_PRD2);
+   return rc;
+   }
+
rc = misc_register(&opal_prd_dev);
if (rc) {
pr_err("failed to register miscdev\n");
-- 
2.21.0



Re: [PATCH v3 1/2] powerpc/powernv: Enhance opal message read interface

2019-08-22 Thread Vasant Hegde

On 8/22/19 9:06 PM, Vasant Hegde wrote:

On 8/22/19 11:21 AM, Oliver O'Halloran wrote:

On Wed, 2019-08-21 at 13:43 +0530, Vasant Hegde wrote:

Use "opal-msg-size" device tree property to allocate memory for "opal_msg".

Cc: Mahesh Salgaonkar 
Cc: Jeremy Kerr 
Signed-off-by: Vasant Hegde 
---
Changes in v3:
   - Call BUG_ON, if we fail to allocate memory during init.

-Vasant

  arch/powerpc/platforms/powernv/opal.c | 29 ++-
  1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c

index aba443be7daa..4f1f68f568bf 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -58,6 +58,8 @@ static DEFINE_SPINLOCK(opal_write_lock);
  static struct atomic_notifier_head opal_msg_notifier_head[OPAL_MSG_TYPE_MAX];
  static uint32_t opal_heartbeat;
  static struct task_struct *kopald_tsk;
+static struct opal_msg *opal_msg;
+static uint64_t opal_msg_size;
  void opal_configure_cores(void)
  {
@@ -271,14 +273,9 @@ static void opal_message_do_notify(uint32_t msg_type, 
void *msg)

  static void opal_handle_message(void)
  {
  s64 ret;
-    /*
- * TODO: pre-allocate a message buffer depending on opal-msg-size
- * value in /proc/device-tree.
- */
-    static struct opal_msg msg;
  u32 type;
-    ret = opal_get_msg(__pa(&msg), sizeof(msg));
+    ret = opal_get_msg(__pa(opal_msg), opal_msg_size);
  /* No opal message pending. */
  if (ret == OPAL_RESOURCE)
  return;
@@ -290,14 +287,14 @@ static void opal_handle_message(void)
  return;
  }
-    type = be32_to_cpu(msg.msg_type);
+    type = be32_to_cpu(opal_msg->msg_type);
  /* Sanity check */
  if (type >= OPAL_MSG_TYPE_MAX) {
  pr_warn_once("%s: Unknown message type: %u\n", __func__, type);
  return;
  }
-    opal_message_do_notify(type, (void *)&msg);
+    opal_message_do_notify(type, (void *)opal_msg);
  }
  static irqreturn_t opal_message_notify(int irq, void *data)
@@ -306,9 +303,21 @@ static irqreturn_t opal_message_notify(int irq, void *data)
  return IRQ_HANDLED;
  }
-static int __init opal_message_init(void)
+static int __init opal_message_init(struct device_node *opal_node)
  {
  int ret, i, irq;



+    const __be32 *val;
+
+    val = of_get_property(opal_node, "opal-msg-size", NULL);
+    if (val)
+    opal_msg_size = be32_to_cpup(val);


Use of_property_read_u32()


Yes. Will fix it.




+
+    /* If opal-msg-size property is not available then use default size */
+    if (!opal_msg_size)
+    opal_msg_size = sizeof(struct opal_msg);
+
+    opal_msg = kmalloc(opal_msg_size, GFP_KERNEL);



+    BUG_ON(opal_msg == NULL);


Seems questionable. Why not fall back to using a staticly allocated
struct opal_msg? Or re-try the allocation with the size limited to
sizeof(struct opal_msg)?


If we are not able to allocate memory during init then we have bigger problem.
No point in continuing. Hence added BUG_ON().
May be I can retry allocation with fixed size before calling BUG_ON().
How about something like below :

+   /* If opal-msg-size property is not available then use default size */
+   if (!opal_msg_size)
+   opal_msg_size = sizeof(struct opal_msg);
+
+   opal_msg = kmalloc(opal_msg_size, GFP_KERNEL);
+   if (!opal_msg) {


Just to be clear I will adjust `opal_msg_size` size here.

-Vasant


+   opal_msg = kmalloc(sizeof(struct opal_msg), GFP_KERNEL);
+   BUG_ON(opal_msg == NULL);
+   }


-Vasant





Re: [PATCH v3 1/2] powerpc/powernv: Enhance opal message read interface

2019-08-22 Thread Vasant Hegde

On 8/22/19 11:21 AM, Oliver O'Halloran wrote:

On Wed, 2019-08-21 at 13:43 +0530, Vasant Hegde wrote:

Use "opal-msg-size" device tree property to allocate memory for "opal_msg".

Cc: Mahesh Salgaonkar 
Cc: Jeremy Kerr 
Signed-off-by: Vasant Hegde 
---
Changes in v3:
   - Call BUG_ON, if we fail to allocate memory during init.

-Vasant

  arch/powerpc/platforms/powernv/opal.c | 29 ++-
  1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index aba443be7daa..4f1f68f568bf 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -58,6 +58,8 @@ static DEFINE_SPINLOCK(opal_write_lock);
  static struct atomic_notifier_head opal_msg_notifier_head[OPAL_MSG_TYPE_MAX];
  static uint32_t opal_heartbeat;
  static struct task_struct *kopald_tsk;
+static struct opal_msg *opal_msg;
+static uint64_t opal_msg_size;
  
  void opal_configure_cores(void)

  {
@@ -271,14 +273,9 @@ static void opal_message_do_notify(uint32_t msg_type, void 
*msg)
  static void opal_handle_message(void)
  {
s64 ret;
-   /*
-* TODO: pre-allocate a message buffer depending on opal-msg-size
-* value in /proc/device-tree.
-*/
-   static struct opal_msg msg;
u32 type;
  
-	ret = opal_get_msg(__pa(&msg), sizeof(msg));

+   ret = opal_get_msg(__pa(opal_msg), opal_msg_size);
/* No opal message pending. */
if (ret == OPAL_RESOURCE)
return;
@@ -290,14 +287,14 @@ static void opal_handle_message(void)
return;
}
  
-	type = be32_to_cpu(msg.msg_type);

+   type = be32_to_cpu(opal_msg->msg_type);
  
  	/* Sanity check */

if (type >= OPAL_MSG_TYPE_MAX) {
pr_warn_once("%s: Unknown message type: %u\n", __func__, type);
return;
}
-   opal_message_do_notify(type, (void *)&msg);
+   opal_message_do_notify(type, (void *)opal_msg);
  }
  
  static irqreturn_t opal_message_notify(int irq, void *data)

@@ -306,9 +303,21 @@ static irqreturn_t opal_message_notify(int irq, void *data)
return IRQ_HANDLED;
  }
  
-static int __init opal_message_init(void)

+static int __init opal_message_init(struct device_node *opal_node)
  {
int ret, i, irq;



+   const __be32 *val;
+
+   val = of_get_property(opal_node, "opal-msg-size", NULL);
+   if (val)
+   opal_msg_size = be32_to_cpup(val);


Use of_property_read_u32()


Yes. Will fix it.




+
+   /* If opal-msg-size property is not available then use default size */
+   if (!opal_msg_size)
+   opal_msg_size = sizeof(struct opal_msg);
+
+   opal_msg = kmalloc(opal_msg_size, GFP_KERNEL);



+   BUG_ON(opal_msg == NULL);


Seems questionable. Why not fall back to using a staticly allocated
struct opal_msg? Or re-try the allocation with the size limited to
sizeof(struct opal_msg)?


If we are not able to allocate memory during init then we have bigger problem.
No point in continuing. Hence added BUG_ON().
May be I can retry allocation with fixed size before calling BUG_ON().
How about something like below :

+   /* If opal-msg-size property is not available then use default size */
+   if (!opal_msg_size)
+   opal_msg_size = sizeof(struct opal_msg);
+
+   opal_msg = kmalloc(opal_msg_size, GFP_KERNEL);
+   if (!opal_msg) {
+   opal_msg = kmalloc(sizeof(struct opal_msg), GFP_KERNEL);
+   BUG_ON(opal_msg == NULL);
+   }


-Vasant



[PATCH v3 2/2] powerpc/powernv: Add new opal message type

2019-08-21 Thread Vasant Hegde
We have OPAL_MSG_PRD message type to pass prd related messages from OPAL
to `opal-prd`. It can handle messages upto 64 bytes. We have a requirement
to send bigger than 64 bytes of data from OPAL to `opal-prd`. Lets add new
message type (OPAL_MSG_PRD2) to pass bigger data.

Cc: Jeremy Kerr 
Signed-off-by: Vasant Hegde 
---
 arch/powerpc/include/asm/opal-api.h   | 1 +
 arch/powerpc/platforms/powernv/opal-prd.c | 9 -
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/opal-api.h 
b/arch/powerpc/include/asm/opal-api.h
index 383242eb0dea..1cad413e1e0e 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -453,6 +453,7 @@ enum opal_msg_type {
OPAL_MSG_DPO= 5,
OPAL_MSG_PRD= 6,
OPAL_MSG_OCC= 7,
+   OPAL_MSG_PRD2   = 8,
OPAL_MSG_TYPE_MAX,
 };
 
diff --git a/arch/powerpc/platforms/powernv/opal-prd.c 
b/arch/powerpc/platforms/powernv/opal-prd.c
index e072bf157d62..50a735d77192 100644
--- a/arch/powerpc/platforms/powernv/opal-prd.c
+++ b/arch/powerpc/platforms/powernv/opal-prd.c
@@ -342,7 +342,7 @@ static int opal_prd_msg_notifier(struct notifier_block *nb,
int msg_size, item_size;
unsigned long flags;
 
-   if (msg_type != OPAL_MSG_PRD)
+   if (msg_type != OPAL_MSG_PRD && msg_type != OPAL_MSG_PRD2)
return 0;
 
/* Calculate total size of the message and item we need to store. The
@@ -393,6 +393,13 @@ static int opal_prd_probe(struct platform_device *pdev)
return rc;
}
 
+   rc = opal_message_notifier_register(OPAL_MSG_PRD2, &opal_prd_event_nb);
+   if (rc) {
+   pr_err("%s: Couldn't register event notifier (%d)\n",
+  __func__, OPAL_MSG_PRD2);
+   return rc;
+   }
+
rc = misc_register(&opal_prd_dev);
if (rc) {
pr_err("failed to register miscdev\n");
-- 
2.21.0



[PATCH v3 1/2] powerpc/powernv: Enhance opal message read interface

2019-08-21 Thread Vasant Hegde
Use "opal-msg-size" device tree property to allocate memory for "opal_msg".

Cc: Mahesh Salgaonkar 
Cc: Jeremy Kerr 
Signed-off-by: Vasant Hegde 
---
Changes in v3:
  - Call BUG_ON, if we fail to allocate memory during init.

-Vasant

 arch/powerpc/platforms/powernv/opal.c | 29 ++-
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index aba443be7daa..4f1f68f568bf 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -58,6 +58,8 @@ static DEFINE_SPINLOCK(opal_write_lock);
 static struct atomic_notifier_head opal_msg_notifier_head[OPAL_MSG_TYPE_MAX];
 static uint32_t opal_heartbeat;
 static struct task_struct *kopald_tsk;
+static struct opal_msg *opal_msg;
+static uint64_t opal_msg_size;
 
 void opal_configure_cores(void)
 {
@@ -271,14 +273,9 @@ static void opal_message_do_notify(uint32_t msg_type, void 
*msg)
 static void opal_handle_message(void)
 {
s64 ret;
-   /*
-* TODO: pre-allocate a message buffer depending on opal-msg-size
-* value in /proc/device-tree.
-*/
-   static struct opal_msg msg;
u32 type;
 
-   ret = opal_get_msg(__pa(&msg), sizeof(msg));
+   ret = opal_get_msg(__pa(opal_msg), opal_msg_size);
/* No opal message pending. */
if (ret == OPAL_RESOURCE)
return;
@@ -290,14 +287,14 @@ static void opal_handle_message(void)
return;
}
 
-   type = be32_to_cpu(msg.msg_type);
+   type = be32_to_cpu(opal_msg->msg_type);
 
/* Sanity check */
if (type >= OPAL_MSG_TYPE_MAX) {
pr_warn_once("%s: Unknown message type: %u\n", __func__, type);
return;
}
-   opal_message_do_notify(type, (void *)&msg);
+   opal_message_do_notify(type, (void *)opal_msg);
 }
 
 static irqreturn_t opal_message_notify(int irq, void *data)
@@ -306,9 +303,21 @@ static irqreturn_t opal_message_notify(int irq, void *data)
return IRQ_HANDLED;
 }
 
-static int __init opal_message_init(void)
+static int __init opal_message_init(struct device_node *opal_node)
 {
int ret, i, irq;
+   const __be32 *val;
+
+   val = of_get_property(opal_node, "opal-msg-size", NULL);
+   if (val)
+   opal_msg_size = be32_to_cpup(val);
+
+   /* If opal-msg-size property is not available then use default size */
+   if (!opal_msg_size)
+   opal_msg_size = sizeof(struct opal_msg);
+
+   opal_msg = kmalloc(opal_msg_size, GFP_KERNEL);
+   BUG_ON(opal_msg == NULL);
 
for (i = 0; i < OPAL_MSG_TYPE_MAX; i++)
ATOMIC_INIT_NOTIFIER_HEAD(&opal_msg_notifier_head[i]);
@@ -910,7 +919,7 @@ static int __init opal_init(void)
}
 
/* Initialise OPAL messaging system */
-   opal_message_init();
+   opal_message_init(opal_node);
 
/* Initialise OPAL asynchronous completion interface */
opal_async_comp_init();
-- 
2.21.0



Re: [PATCH v2 1/2] powerpc/powernv: Enhance opal message read interface

2019-06-23 Thread Vasant Hegde

On 06/05/2019 05:16 PM, Vasant Hegde wrote:

Use "opal-msg-size" device tree property to allocate memory for "opal_msg".



Michael,

   Can you please look into this patchset?

Thanks
-Vasant


Cc: Mahesh Salgaonkar 
Cc: Jeremy Kerr 
Signed-off-by: Vasant Hegde 
---
  arch/powerpc/platforms/powernv/opal.c | 30 --
  1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index 98c5d94b17fb..e6ea32f3b3c8 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -58,6 +58,8 @@ static DEFINE_SPINLOCK(opal_write_lock);
  static struct atomic_notifier_head opal_msg_notifier_head[OPAL_MSG_TYPE_MAX];
  static uint32_t opal_heartbeat;
  static struct task_struct *kopald_tsk;
+static struct opal_msg *opal_msg;
+static uint64_t opal_msg_size;

  void opal_configure_cores(void)
  {
@@ -264,14 +266,9 @@ static void opal_message_do_notify(uint32_t msg_type, void 
*msg)
  static void opal_handle_message(void)
  {
s64 ret;
-   /*
-* TODO: pre-allocate a message buffer depending on opal-msg-size
-* value in /proc/device-tree.
-*/
-   static struct opal_msg msg;
u32 type;

-   ret = opal_get_msg(__pa(&msg), sizeof(msg));
+   ret = opal_get_msg(__pa(opal_msg), opal_msg_size);
/* No opal message pending. */
if (ret == OPAL_RESOURCE)
return;
@@ -283,14 +280,14 @@ static void opal_handle_message(void)
return;
}

-   type = be32_to_cpu(msg.msg_type);
+   type = be32_to_cpu(opal_msg->msg_type);

/* Sanity check */
if (type >= OPAL_MSG_TYPE_MAX) {
pr_warn_once("%s: Unknown message type: %u\n", __func__, type);
return;
}
-   opal_message_do_notify(type, (void *)&msg);
+   opal_message_do_notify(type, (void *)opal_msg);
  }

  static irqreturn_t opal_message_notify(int irq, void *data)
@@ -299,9 +296,22 @@ static irqreturn_t opal_message_notify(int irq, void *data)
return IRQ_HANDLED;
  }

-static int __init opal_message_init(void)
+static int __init opal_message_init(struct device_node *opal_node)
  {
int ret, i, irq;
+   const __be32 *val;
+
+   val = of_get_property(opal_node, "opal-msg-size", NULL);
+   if (val)
+   opal_msg_size = be32_to_cpup(val);
+
+   /* If opal-msg-size property is not available then use default size */
+   if (!opal_msg_size)
+   opal_msg_size = sizeof(struct opal_msg);
+
+   opal_msg = kmalloc(opal_msg_size, GFP_KERNEL);
+   if (!opal_msg)
+   return -ENOMEM;

for (i = 0; i < OPAL_MSG_TYPE_MAX; i++)
ATOMIC_INIT_NOTIFIER_HEAD(&opal_msg_notifier_head[i]);
@@ -903,7 +913,7 @@ static int __init opal_init(void)
}

/* Initialise OPAL messaging system */
-   opal_message_init();
+   opal_message_init(opal_node);

/* Initialise OPAL asynchronous completion interface */
opal_async_comp_init();





[PATCH v2 2/2] powerpc/powernv: Add new opal message type

2019-06-05 Thread Vasant Hegde
We have OPAL_MSG_PRD message type to pass prd related messages from OPAL
to `opal-prd`. It can handle messages upto 64 bytes. We have a requirement
to send bigger than 64 bytes of data from OPAL to `opal-prd`. Lets add new
message type (OPAL_MSG_PRD2) to pass bigger data.

Cc: Jeremy Kerr 
Signed-off-by: Vasant Hegde 
---
 arch/powerpc/include/asm/opal-api.h   | 1 +
 arch/powerpc/platforms/powernv/opal-prd.c | 9 -
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/opal-api.h 
b/arch/powerpc/include/asm/opal-api.h
index 09a8553833d1..428b5ef7db7b 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -453,6 +453,7 @@ enum opal_msg_type {
OPAL_MSG_DPO= 5,
OPAL_MSG_PRD= 6,
OPAL_MSG_OCC= 7,
+   OPAL_MSG_PRD2   = 8,
OPAL_MSG_TYPE_MAX,
 };
 
diff --git a/arch/powerpc/platforms/powernv/opal-prd.c 
b/arch/powerpc/platforms/powernv/opal-prd.c
index e072bf157d62..50a735d77192 100644
--- a/arch/powerpc/platforms/powernv/opal-prd.c
+++ b/arch/powerpc/platforms/powernv/opal-prd.c
@@ -342,7 +342,7 @@ static int opal_prd_msg_notifier(struct notifier_block *nb,
int msg_size, item_size;
unsigned long flags;
 
-   if (msg_type != OPAL_MSG_PRD)
+   if (msg_type != OPAL_MSG_PRD && msg_type != OPAL_MSG_PRD2)
return 0;
 
/* Calculate total size of the message and item we need to store. The
@@ -393,6 +393,13 @@ static int opal_prd_probe(struct platform_device *pdev)
return rc;
}
 
+   rc = opal_message_notifier_register(OPAL_MSG_PRD2, &opal_prd_event_nb);
+   if (rc) {
+   pr_err("%s: Couldn't register event notifier (%d)\n",
+  __func__, OPAL_MSG_PRD2);
+   return rc;
+   }
+
rc = misc_register(&opal_prd_dev);
if (rc) {
pr_err("failed to register miscdev\n");
-- 
2.14.3



[PATCH v2 1/2] powerpc/powernv: Enhance opal message read interface

2019-06-05 Thread Vasant Hegde
Use "opal-msg-size" device tree property to allocate memory for "opal_msg".

Cc: Mahesh Salgaonkar 
Cc: Jeremy Kerr 
Signed-off-by: Vasant Hegde 
---
 arch/powerpc/platforms/powernv/opal.c | 30 --
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index 98c5d94b17fb..e6ea32f3b3c8 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -58,6 +58,8 @@ static DEFINE_SPINLOCK(opal_write_lock);
 static struct atomic_notifier_head opal_msg_notifier_head[OPAL_MSG_TYPE_MAX];
 static uint32_t opal_heartbeat;
 static struct task_struct *kopald_tsk;
+static struct opal_msg *opal_msg;
+static uint64_t opal_msg_size;
 
 void opal_configure_cores(void)
 {
@@ -264,14 +266,9 @@ static void opal_message_do_notify(uint32_t msg_type, void 
*msg)
 static void opal_handle_message(void)
 {
s64 ret;
-   /*
-* TODO: pre-allocate a message buffer depending on opal-msg-size
-* value in /proc/device-tree.
-*/
-   static struct opal_msg msg;
u32 type;
 
-   ret = opal_get_msg(__pa(&msg), sizeof(msg));
+   ret = opal_get_msg(__pa(opal_msg), opal_msg_size);
/* No opal message pending. */
if (ret == OPAL_RESOURCE)
return;
@@ -283,14 +280,14 @@ static void opal_handle_message(void)
return;
}
 
-   type = be32_to_cpu(msg.msg_type);
+   type = be32_to_cpu(opal_msg->msg_type);
 
/* Sanity check */
if (type >= OPAL_MSG_TYPE_MAX) {
pr_warn_once("%s: Unknown message type: %u\n", __func__, type);
return;
}
-   opal_message_do_notify(type, (void *)&msg);
+   opal_message_do_notify(type, (void *)opal_msg);
 }
 
 static irqreturn_t opal_message_notify(int irq, void *data)
@@ -299,9 +296,22 @@ static irqreturn_t opal_message_notify(int irq, void *data)
return IRQ_HANDLED;
 }
 
-static int __init opal_message_init(void)
+static int __init opal_message_init(struct device_node *opal_node)
 {
int ret, i, irq;
+   const __be32 *val;
+
+   val = of_get_property(opal_node, "opal-msg-size", NULL);
+   if (val)
+   opal_msg_size = be32_to_cpup(val);
+
+   /* If opal-msg-size property is not available then use default size */
+   if (!opal_msg_size)
+   opal_msg_size = sizeof(struct opal_msg);
+
+   opal_msg = kmalloc(opal_msg_size, GFP_KERNEL);
+   if (!opal_msg)
+   return -ENOMEM;
 
for (i = 0; i < OPAL_MSG_TYPE_MAX; i++)
ATOMIC_INIT_NOTIFIER_HEAD(&opal_msg_notifier_head[i]);
@@ -903,7 +913,7 @@ static int __init opal_init(void)
}
 
/* Initialise OPAL messaging system */
-   opal_message_init();
+   opal_message_init(opal_node);
 
/* Initialise OPAL asynchronous completion interface */
opal_async_comp_init();
-- 
2.14.3



[PATCH 2/2] powerpc/powernv: Add new opal message type

2019-04-09 Thread Vasant Hegde
We have OPAL_MSG_PRD message type to pass prd related messages from OPAL
to `opal-prd`. It can handle messages upto 64 bytes. We have a requirement
to send bigger than 64 bytes of data from OPAL to `opal-prd`. Lets add new
message type (OPAL_MSG_PRD2) to pass bigger data.

Cc: Jeremy Kerr 
Signed-off-by: Vasant Hegde 
---
 arch/powerpc/include/asm/opal-api.h   | 1 +
 arch/powerpc/platforms/powernv/opal-prd.c | 9 -
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/opal-api.h 
b/arch/powerpc/include/asm/opal-api.h
index 821ed4fa95ad..79272e145281 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -455,6 +455,7 @@ enum opal_msg_type {
OPAL_MSG_DPO= 5,
OPAL_MSG_PRD= 6,
OPAL_MSG_OCC= 7,
+   OPAL_MSG_PRD2   = 8,
OPAL_MSG_TYPE_MAX,
 };
 
diff --git a/arch/powerpc/platforms/powernv/opal-prd.c 
b/arch/powerpc/platforms/powernv/opal-prd.c
index 4070bb4e9da4..ef9a19de7cca 100644
--- a/arch/powerpc/platforms/powernv/opal-prd.c
+++ b/arch/powerpc/platforms/powernv/opal-prd.c
@@ -350,7 +350,7 @@ static int opal_prd_msg_notifier(struct notifier_block *nb,
int msg_size, item_size;
unsigned long flags;
 
-   if (msg_type != OPAL_MSG_PRD)
+   if (msg_type != OPAL_MSG_PRD && msg_type != OPAL_MSG_PRD2)
return 0;
 
/* Calculate total size of the message and item we need to store. The
@@ -401,6 +401,13 @@ static int opal_prd_probe(struct platform_device *pdev)
return rc;
}
 
+   rc = opal_message_notifier_register(OPAL_MSG_PRD2, &opal_prd_event_nb);
+   if (rc) {
+   pr_err("%s: Couldn't register event notifier (%d)\n",
+  __func__, OPAL_MSG_PRD2);
+   return rc;
+   }
+
rc = misc_register(&opal_prd_dev);
if (rc) {
pr_err("failed to register miscdev\n");
-- 
2.14.3



[PATCH 1/2] powerpc/powernv: Enhance opal message read interface

2019-04-09 Thread Vasant Hegde
Use "opal-msg-size" device tree property to allocate memory for "opal_msg".

Also replace `reserved` field in "struct opal_msg" with `size`. So that
opal_get_msg() user can get actual message size.

Cc: Mahesh Salgaonkar 
Cc: Jeremy Kerr 
Signed-off-by: Vasant Hegde 
---
 arch/powerpc/include/asm/opal-api.h   |  2 +-
 arch/powerpc/platforms/powernv/opal.c | 30 --
 2 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/include/asm/opal-api.h 
b/arch/powerpc/include/asm/opal-api.h
index 870fb7b239ea..821ed4fa95ad 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -460,7 +460,7 @@ enum opal_msg_type {
 
 struct opal_msg {
__be32 msg_type;
-   __be32 reserved;
+   __be32 size;
__be64 params[8];
 };
 
diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index 2b0eca104f86..52fb52c2ca4b 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -62,6 +62,8 @@ static DEFINE_SPINLOCK(opal_write_lock);
 static struct atomic_notifier_head opal_msg_notifier_head[OPAL_MSG_TYPE_MAX];
 static uint32_t opal_heartbeat;
 static struct task_struct *kopald_tsk;
+static struct opal_msg *opal_msg;
+static uint64_t opal_msg_size;
 
 void opal_configure_cores(void)
 {
@@ -268,14 +270,9 @@ static void opal_message_do_notify(uint32_t msg_type, void 
*msg)
 static void opal_handle_message(void)
 {
s64 ret;
-   /*
-* TODO: pre-allocate a message buffer depending on opal-msg-size
-* value in /proc/device-tree.
-*/
-   static struct opal_msg msg;
u32 type;
 
-   ret = opal_get_msg(__pa(&msg), sizeof(msg));
+   ret = opal_get_msg(__pa(opal_msg), opal_msg_size);
/* No opal message pending. */
if (ret == OPAL_RESOURCE)
return;
@@ -287,14 +284,14 @@ static void opal_handle_message(void)
return;
}
 
-   type = be32_to_cpu(msg.msg_type);
+   type = be32_to_cpu(opal_msg->msg_type);
 
/* Sanity check */
if (type >= OPAL_MSG_TYPE_MAX) {
pr_warn_once("%s: Unknown message type: %u\n", __func__, type);
return;
}
-   opal_message_do_notify(type, (void *)&msg);
+   opal_message_do_notify(type, (void *)opal_msg);
 }
 
 static irqreturn_t opal_message_notify(int irq, void *data)
@@ -303,9 +300,22 @@ static irqreturn_t opal_message_notify(int irq, void *data)
return IRQ_HANDLED;
 }
 
-static int __init opal_message_init(void)
+static int __init opal_message_init(struct device_node *opal_node)
 {
int ret, i, irq;
+   const __be32 *val;
+
+   val = of_get_property(opal_node, "opal-msg-size", NULL);
+   if (val)
+   opal_msg_size = be32_to_cpup(val);
+
+   /* If opal-msg-size property is not available then use default size */
+   if (!opal_msg_size)
+   opal_msg_size = sizeof(struct opal_msg);
+
+   opal_msg = kmalloc(opal_msg_size, GFP_KERNEL);
+   if (!opal_msg)
+   return -ENOMEM;
 
for (i = 0; i < OPAL_MSG_TYPE_MAX; i++)
ATOMIC_INIT_NOTIFIER_HEAD(&opal_msg_notifier_head[i]);
@@ -886,7 +896,7 @@ static int __init opal_init(void)
}
 
/* Initialise OPAL messaging system */
-   opal_message_init();
+   opal_message_init(opal_node);
 
/* Initialise OPAL asynchronous completion interface */
opal_async_comp_init();
-- 
2.14.3



Re: [PATCH] powerpc/rtasd: Improve unknown error logging

2018-10-09 Thread Vasant Hegde

On 10/10/2018 10:53 AM, Oliver O'Halloran wrote:

Currently when we get an unknown RTAS event it prints the type as
"Unknown" and no other useful information. Add the raw type code to the
log message so that we have something to work off.


Yeah. Useful one.

Reviewed-by: Vasant Hegde 

-Vasant



Signed-off-by: Oliver O'Halloran 
---
  arch/powerpc/kernel/rtasd.c | 6 --
  1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c
index 44d66c33d59d..6fafc82c04b0 100644
--- a/arch/powerpc/kernel/rtasd.c
+++ b/arch/powerpc/kernel/rtasd.c
@@ -150,8 +150,10 @@ static void printk_log_rtas(char *buf, int len)
} else {
struct rtas_error_log *errlog = (struct rtas_error_log *)buf;

-   printk(RTAS_DEBUG "event: %d, Type: %s, Severity: %d\n",
-  error_log_cnt, rtas_event_type(rtas_error_type(errlog)),
+   printk(RTAS_DEBUG "event: %d, Type: %s (%d), Severity: %d\n",
+  error_log_cnt,
+  rtas_event_type(rtas_error_type(errlog)),
+  rtas_error_type(errlog),
   rtas_error_severity(errlog));
}
  }





Re: [PATCH v2] powerpc/powernv: Make possible for user to force a full ipl cec reboot

2018-09-04 Thread Vasant Hegde

On 09/03/2018 03:56 PM, Vaibhav Jain wrote:

Ever since fast reboot is enabled by default in opal,
opal_cec_reboot() will use fast-reset instead of full IPL to perform
system reboot. This leaves the user with no direct way to force a full
IPL reboot except changing an nvram setting that persistently disables
fast-reset for all subsequent reboots.

This patch provides a more direct way for the user to force a one-shot
full IPL reboot by passing the command line argument 'full' to the
reboot command. So the user will be able to tweak the reboot behavior
via:



.../...



  /* Argument to OPAL_PCI_TCE_KILL */
diff --git a/arch/powerpc/platforms/powernv/setup.c 
b/arch/powerpc/platforms/powernv/setup.c
index ae023622..650484e0940b 100644
--- a/arch/powerpc/platforms/powernv/setup.c
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -224,7 +224,22 @@ static void  __noreturn pnv_restart(char *cmd)
pnv_prepare_going_down();

while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
-   rc = opal_cec_reboot();
+   /* See if we need to do a full IPL reboot */
+   if (cmd && strcmp(cmd, "full") == 0)
+   rc = opal_cec_reboot2(OPAL_REBOOT_FULL_IPL, NULL);
+   else
+   rc = OPAL_UNSUPPORTED;


As discussed offline, please handle OPAL_SUCCESS case well.

-Vasant



Re: [PATCH v2 3/3] powerpc/powernv: Always stop secondaries before reboot/shutdown

2018-04-02 Thread Vasant Hegde

On 04/01/2018 04:06 PM, Nicholas Piggin wrote:

Currently powernv reboot and shutdown requests just leave secondaries
to do their own things. This is undesirable because they can trigger
any number of watchdogs while waiting for reboot, but also we don't
know what else they might be doing -- they might be causing trouble,
trampling memory, etc.

The opal scheduled flash update code already ran into watchdog problems
due to flashing taking a long time, and it was fixed with 2196c6f1ed
("powerpc/powernv: Return secondary CPUs to firmware before FW update"),
which returns secondaries to opal. It's been found that regular reboots
can take over 10 seconds, which can result in the hard lockup watchdog
firing,

   reboot: Restarting system
   [  360.038896709,5] OPAL: Reboot request...
   Watchdog CPU:0 Hard LOCKUP
   Watchdog CPU:44 detected Hard LOCKUP other CPUS:16
   Watchdog CPU:16 Hard LOCKUP
   watchdog: BUG: soft lockup - CPU#16 stuck for 3s! [swapper/16:0]

This patch removes the special case for flash update, and calls
smp_send_stop in all cases before calling reboot/shutdown.

smp_send_stop could return CPUs to OPAL, the main reason not to is
that the request could come from a NMI that interrupts OPAL code,
so re-entry to OPAL can cause a number of problems. Putting
secondaries into simple spin loops improves the chances of a
successful reboot.

Cc: Vasant Hegde 


Nick,

Patch looks good to me. We have tested this patchset on FSP based system and 
everything looks fine.


Reviewed-by:  Vasant Hegde 

-Vasant


Signed-off-by: Nicholas Piggin 
---
  arch/powerpc/include/asm/opal.h |  2 +-
  arch/powerpc/platforms/powernv/opal-flash.c | 28 +---
  arch/powerpc/platforms/powernv/setup.c  | 15 +--
  3 files changed, 7 insertions(+), 38 deletions(-)

diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index dde60089d0d4..7159e1a6a61a 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -325,7 +325,7 @@ struct rtc_time;
  extern unsigned long opal_get_boot_time(void);
  extern void opal_nvram_init(void);
  extern void opal_flash_update_init(void);
-extern void opal_flash_term_callback(void);
+extern void opal_flash_update_print_message(void);
  extern int opal_elog_init(void);
  extern void opal_platform_dump_init(void);
  extern void opal_sys_param_init(void);
diff --git a/arch/powerpc/platforms/powernv/opal-flash.c 
b/arch/powerpc/platforms/powernv/opal-flash.c
index 1cb0b895a236..b37015101bf6 100644
--- a/arch/powerpc/platforms/powernv/opal-flash.c
+++ b/arch/powerpc/platforms/powernv/opal-flash.c
@@ -303,26 +303,9 @@ static int opal_flash_update(int op)
return rc;
  }

-/* Return CPUs to OPAL before starting FW update */
-static void flash_return_cpu(void *info)
-{
-   int cpu = smp_processor_id();
-
-   if (!cpu_online(cpu))
-   return;
-
-   /* Disable IRQ */
-   hard_irq_disable();
-
-   /* Return the CPU to OPAL */
-   opal_return_cpu();
-}
-
  /* This gets called just before system reboots */
-void opal_flash_term_callback(void)
+void opal_flash_update_print_message(void)
  {
-   struct cpumask mask;
-
if (update_flash_data.status != FLASH_IMG_READY)
return;

@@ -333,15 +316,6 @@ void opal_flash_term_callback(void)

/* Small delay to help getting the above message out */
msleep(500);
-
-   /* Return secondary CPUs to firmware */
-   cpumask_copy(&mask, cpu_online_mask);
-   cpumask_clear_cpu(smp_processor_id(), &mask);
-   if (!cpumask_empty(&mask))
-   smp_call_function_many(&mask,
-  flash_return_cpu, NULL, false);
-   /* Hard disable interrupts */
-   hard_irq_disable();
  }

  /*
diff --git a/arch/powerpc/platforms/powernv/setup.c 
b/arch/powerpc/platforms/powernv/setup.c
index 5f963286232f..ef8c9ce53a61 100644
--- a/arch/powerpc/platforms/powernv/setup.c
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -201,17 +201,12 @@ static void pnv_prepare_going_down(void)
 */
opal_event_shutdown();

-   /* Soft disable interrupts */
-   local_irq_disable();
+   /* Print flash update message if one is scheduled. */
+   opal_flash_update_print_message();

-   /*
-* Return secondary CPUs to firwmare if a flash update
-* is pending otherwise we will get all sort of error
-* messages about CPU being stuck etc.. This will also
-* have the side effect of hard disabling interrupts so
-* past this point, the kernel is effectively dead.
-*/
-   opal_flash_term_callback();
+   smp_send_stop();
+
+   hard_irq_disable();
  }

  static void  __noreturn pnv_restart(char *cmd)





Re: [PATCH] powerpc/powernv/nvram: opal_nvram_write handle unknown OPAL errors

2018-03-28 Thread Vasant Hegde

On 03/27/2018 01:08 PM, Nicholas Piggin wrote:

On Tue, 27 Mar 2018 12:47:31 +0530
Vasant Hegde  wrote:


On 03/26/2018 08:32 PM, Nicholas Piggin wrote:

opal_nvram_write currently just assumes success if it encounters an
error other than OPAL_BUSY or OPAL_BUSY_EVENT. Have it return -EIO
on other errors instead.

Signed-off-by: Nicholas Piggin 
---
   arch/powerpc/platforms/powernv/opal-nvram.c | 2 ++
   1 file changed, 2 insertions(+)

diff --git a/arch/powerpc/platforms/powernv/opal-nvram.c 
b/arch/powerpc/platforms/powernv/opal-nvram.c
index 9db4398ded5d..13bf625dc3e8 100644
--- a/arch/powerpc/platforms/powernv/opal-nvram.c
+++ b/arch/powerpc/platforms/powernv/opal-nvram.c
@@ -59,6 +59,8 @@ static ssize_t opal_nvram_write(char *buf, size_t count, 
loff_t *index)
if (rc == OPAL_BUSY_EVENT)
opal_poll_events(NULL);


Current code does continuous poller here. May be we have small breathing time
here. What you say?


Yeah that's probably not a bad idea. I cc'ed skiboot list -- what's a
reasonable delay between retries?


I think it depends on individual API. Like in case of dump retrival I've 20ms 
delay... as FSP takes time to copy data to host memory. But may be here we can 
have smaller delay.



Linux has a bunch of similar kind of
loops if you grep for opal_poll_events and OPAL_BUSY. It would be good
to convert them all to a standard form with a standard delay as
recommended by OPAL, and where specific calls have different delay
for a good reason, that would be documented in the OPAL API docs.


Yes. We should update API documentation.

-Vasant



Re: [RFC PATCH] powerpc/xmon: Use OPAL_DEBUG to debug srest in OPAL

2018-03-28 Thread Vasant Hegde

On 03/27/2018 12:58 PM, Nicholas Piggin wrote:

On Tue, 27 Mar 2018 12:42:32 +0530
Vasant Hegde  wrote:


On 03/26/2018 08:39 PM, Nicholas Piggin wrote:

xmon can be entered via sreset NMI (from a management sreset, or an
NMI IPI), which can interrupt OPAL. Add checks to xmon to see if pc
or sp are within OPAL memory, and if so, then use OPAL_DEBUG to
print the opal stack and return the Linux stack, which can then be
dumped by xmon


Nick,


OPAL uses FSP/cronus interface for many of debug interface (like OPAL assert,
getting opal console, triggering FSP R/R etc). May be in future we may add new
debug capability.


It would be good to ensure an API could accommodate them, or at least
not get in the way.


Agree.




Once secureboot is enabled none of these interface work and we have limited 
debug
capability.

Here you are using very generic API name (OPAL_DEBUG). May be we should have 
generic
interface (exported via debugfs?) here rather than SRESET specific one.


OPAL_DEBUG here actually uses the sub-function OPAL_DEBUG_DUMP_STACK (1),
but I didn't bring that constant across from skiboot which I should have.


Nick,

May be we should define sub-function usage.  Also current API limits number of 
arguments

and its type. may be we should have argument 2 as "void *" ?
something like :
  s64 opal_debug(u32 debug_type, void *data, u64 dsize);

That way individual sub-function can parse/use based on its need.



But I don't think this is SRESET specific. If Linux has any way to get
an r1 for a CPU in OPAL, then it can use this function. If it does not,
then it simply can't use it.

I haven't really followed what's happening with secure boot, but presumably
we can still get NMIs (at least machine check, even if all system reset
sources are suppressed).


AFAIK secureboot won't block us here. It mostly blocks external entity (like 
FSP/cronus) from
accessing host memory. (like they can't directly read, write to host memory, 
SCOM operations

are restricted etc).

-Vasant



Re: [PATCH] powerpc/powernv/nvram: opal_nvram_write handle unknown OPAL errors

2018-03-27 Thread Vasant Hegde

On 03/26/2018 08:32 PM, Nicholas Piggin wrote:

opal_nvram_write currently just assumes success if it encounters an
error other than OPAL_BUSY or OPAL_BUSY_EVENT. Have it return -EIO
on other errors instead.

Signed-off-by: Nicholas Piggin 
---
  arch/powerpc/platforms/powernv/opal-nvram.c | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/arch/powerpc/platforms/powernv/opal-nvram.c 
b/arch/powerpc/platforms/powernv/opal-nvram.c
index 9db4398ded5d..13bf625dc3e8 100644
--- a/arch/powerpc/platforms/powernv/opal-nvram.c
+++ b/arch/powerpc/platforms/powernv/opal-nvram.c
@@ -59,6 +59,8 @@ static ssize_t opal_nvram_write(char *buf, size_t count, 
loff_t *index)
if (rc == OPAL_BUSY_EVENT)
opal_poll_events(NULL);


Current code does continuous poller here. May be we have small breathing time 
here. What you say?




}
+   if (rc)
+   return -EIO;


Good catch. Thanks!

Reviewed-by: Vasant Hegde 

-Vasant



Re: [RFC PATCH] powerpc/xmon: Use OPAL_DEBUG to debug srest in OPAL

2018-03-27 Thread Vasant Hegde

On 03/26/2018 08:39 PM, Nicholas Piggin wrote:

xmon can be entered via sreset NMI (from a management sreset, or an
NMI IPI), which can interrupt OPAL. Add checks to xmon to see if pc
or sp are within OPAL memory, and if so, then use OPAL_DEBUG to
print the opal stack and return the Linux stack, which can then be
dumped by xmon


Nick,


OPAL uses FSP/cronus interface for many of debug interface (like OPAL assert, 
getting opal console, triggering FSP R/R etc). May be in future we may add new 
debug capability.

Once secureboot is enabled none of these interface work and we have limited 
debug
capability.

Here you are using very generic API name (OPAL_DEBUG). May be we should have 
generic
interface (exported via debugfs?) here rather than SRESET specific one.

-Vasant




The OPAL side of this, with sample xmon output is here:

https://lists.ozlabs.org/pipermail/skiboot/2018-March/010856.html

This could be plumed into the oops printing code as well.

Thanks,
Nick
---
  arch/powerpc/include/asm/opal.h|  4 
  arch/powerpc/platforms/powernv/opal-wrappers.S |  1 +
  arch/powerpc/platforms/powernv/opal.c  |  5 +
  arch/powerpc/xmon/xmon.c   | 27 ++
  4 files changed, 37 insertions(+)

diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 12e70fb58700..afcc0c5ed5b0 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -27,6 +27,8 @@ extern struct kobject *opal_kobj;
  /* /ibm,opal */
  extern struct device_node *opal_node;

+bool in_opal_text_heap_stack(u64 address);
+
  /* API functions */
  int64_t opal_invalid_call(void);
  int64_t opal_npu_destroy_context(uint64_t phb_id, uint64_t pid, uint64_t bdf);
@@ -289,6 +291,8 @@ int opal_sensor_group_clear(u32 group_hndl, int token);

  s64 opal_signal_system_reset(s32 cpu);

+s64 opal_debug(u32 debug_type, u64 r1);
+
  /* Internal functions */
  extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
   int depth, void *data);
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S 
b/arch/powerpc/platforms/powernv/opal-wrappers.S
index 1b2936ba6040..78b9ae003553 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -323,3 +323,4 @@ OPAL_CALL(opal_sensor_group_clear,  
OPAL_SENSOR_GROUP_CLEAR);
  OPAL_CALL(opal_npu_spa_setup, OPAL_NPU_SPA_SETUP);
  OPAL_CALL(opal_npu_spa_clear_cache,   OPAL_NPU_SPA_CLEAR_CACHE);
  OPAL_CALL(opal_npu_tl_set,OPAL_NPU_TL_SET);
+OPAL_CALL(opal_debug,  167);
diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index c15182765ff5..0b7ff5fb18f8 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -64,6 +64,11 @@ static struct atomic_notifier_head 
opal_msg_notifier_head[OPAL_MSG_TYPE_MAX];
  static uint32_t opal_heartbeat;
  static struct task_struct *kopald_tsk;

+bool in_opal_text_heap_stack(u64 address)
+{
+   return (address >= opal.base && address < opal.base + opal.size);
+}
+
  void opal_configure_cores(void)
  {
u64 reinit_flags = 0;
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 82e1a3ee6e0f..ade1adcc1ab8 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -452,6 +452,15 @@ static inline int unrecoverable_excp(struct pt_regs *regs)
  #endif
  }

+static bool in_opal(unsigned long addr)
+{
+   if (firmware_has_feature(FW_FEATURE_OPAL))
+   if (in_opal_text_heap_stack(addr))
+   return true;
+
+   return false;
+}
+
  static int xmon_core(struct pt_regs *regs, int fromipi)
  {
int cmd = 0;
@@ -510,6 +519,9 @@ static int xmon_core(struct pt_regs *regs, int fromipi)

xmon_fault_jmp[cpu] = recurse_jmp;

+   if (in_opal(regs->nip))
+   printf("xmon: cpu 0x%x stopped in OPAL!\n", cpu);
+
bp = NULL;
if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT))
bp = at_breakpoint(regs->nip);
@@ -1484,8 +1496,23 @@ static void xmon_show_stack(unsigned long sp, unsigned 
long lr,
unsigned long marker;
struct pt_regs regs;

+   if (in_opal(sp)) {
+   struct debug_struct {
+   unsigned long nip;
+   unsigned long r1;
+   unsigned long r1_caller;
+   } db;
+   printf("SP is in OPAL, calling OPAL to dump stack\n");
+   db.nip = cpu_to_be64(pc);
+   db.r1 = cpu_to_be64(sp);
+   opal_debug(1, (unsigned long)&db);
+   sp = be64_to_cpu(db.r1_caller);
+   }
+
while (max_to_print--) {
if (!is_kernel_addr(sp)) {
+   if (in_opal(pc) && in_opal(sp))
+   

Re: [PATCH] powerpc/powernv : Drop reference added by kset_find_obj()

2016-08-22 Thread Vasant Hegde

On 08/22/2016 12:17 PM, Mukesh Ojha wrote:

In a situation, where Linux kernel gets notified about duplicate error log
from OPAL, it is been observed that kernel fails to remove sysfs entries
(/sys/firmware/opal/elog/0x) of such error logs. This is because,
we currently search the error log/dump kobject in the kset list via
'kset_find_obj()' routine. Which eventually increment the reference count
by one, once it founds the kobject.

So, unless we decrement the reference count by one after it found the kobject,
we would not be able to release the kobject properly later.

This patch adds the 'kobject_put()' which was missing earlier.

Signed-off-by: Mukesh Ojha 



I've reviewed and tested this patch. Looks good to me.

Reviewed-by: Vasant Hegde 

-Vasant



Cc: sta...@vger.kernel.org
---
  arch/powerpc/platforms/powernv/opal-dump.c | 7 ++-
  arch/powerpc/platforms/powernv/opal-elog.c | 7 ++-
  2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-dump.c 
b/arch/powerpc/platforms/powernv/opal-dump.c
index 2ee9643..4c82782 100644
--- a/arch/powerpc/platforms/powernv/opal-dump.c
+++ b/arch/powerpc/platforms/powernv/opal-dump.c
@@ -370,6 +370,7 @@ static irqreturn_t process_dump(int irq, void *data)
uint32_t dump_id, dump_size, dump_type;
struct dump_obj *dump;
char name[22];
+   struct kobject *kobj;

rc = dump_read_info(&dump_id, &dump_size, &dump_type);
if (rc != OPAL_SUCCESS)
@@ -381,8 +382,12 @@ static irqreturn_t process_dump(int irq, void *data)
 * that gracefully and not create two conflicting
 * entries.
 */
-   if (kset_find_obj(dump_kset, name))
+   kobj = kset_find_obj(dump_kset, name);
+   if (kobj) {
+   /* Drop reference added by kset_find_obj() */
+   kobject_put(kobj);
return 0;
+   }

dump = create_dump_obj(dump_id, dump_size, dump_type);
if (!dump)
diff --git a/arch/powerpc/platforms/powernv/opal-elog.c 
b/arch/powerpc/platforms/powernv/opal-elog.c
index 37f959b..f2344cb 100644
--- a/arch/powerpc/platforms/powernv/opal-elog.c
+++ b/arch/powerpc/platforms/powernv/opal-elog.c
@@ -247,6 +247,7 @@ static irqreturn_t elog_event(int irq, void *data)
uint64_t elog_type;
int rc;
char name[2+16+1];
+   struct kobject *kobj;

rc = opal_get_elog_size(&id, &size, &type);
if (rc != OPAL_SUCCESS) {
@@ -269,8 +270,12 @@ static irqreturn_t elog_event(int irq, void *data)
 * that gracefully and not create two conflicting
 * entries.
 */
-   if (kset_find_obj(elog_kset, name))
+   kobj = kset_find_obj(elog_kset, name);
+   if (kobj) {
+   /* Drop reference added by kset_find_obj() */
+   kobject_put(kobj);
return IRQ_HANDLED;
+   }

create_elog_obj(log_id, elog_size, elog_type);





Re: [PATCH] powerpc/mm: Allow user space to map rtas_rmo_buf

2016-01-21 Thread Vasant Hegde
On 01/22/2016 10:59 AM, Michael Ellerman wrote:
> On Thu, 2016-01-21 at 21:45 +0530, Vasant Hegde wrote:
> 
>> With commit 90a545e9 (restrict /dev/mem to idle io memory ranges) mapping
>> rtas_rmo_buf from user space is failing. Hence we are not able to make
>> RTAS syscall.
>>
>> This patch calls page_is_rtas_user_buf before calling iomem_is_exclusive
>> in  devmem_is_allowed(). This will allow user space to map rtas_rmo_buf
>> and we are able to make RTAS syscall.

Michael,

> 
> Thanks for the patch.
> 
> I'll put it in my fixes branch for next week.

Thanks!

> 
> 
> Having said that, why the  is librtas mapping /dev/mem in
> the first place? Unless there is a very good reason, and probably even if 
> there
> is, we should fix that to use a sane API.

We use rtas system call. We use /dev/mem interface to map the RTAS memory region
(allocated by kernel and information is passed to user space via procfs) so that
we can read/write to RTAS memory.

I do not have historical information. May be Nathan has more information on 
this.

-Vasant

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

[PATCH] powerpc/mm: Allow user space to map rtas_rmo_buf

2016-01-21 Thread Vasant Hegde
With commit 90a545e9 (restrict /dev/mem to idle io memory ranges) mapping
rtas_rmo_buf from user space is failing. Hence we are not able to make
RTAS syscall.

This patch calls page_is_rtas_user_buf before calling iomem_is_exclusive
in  devmem_is_allowed(). This will allow user space to map rtas_rmo_buf
and we are able to make RTAS syscall.

Reported-by: Bharata B Rao 
CC: Dan Williams 
CC: Nathan Fontenot 
CC: Michael Ellerman 
Signed-off-by: Vasant Hegde 
---
 arch/powerpc/mm/mem.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 22d94c3..d0f0a51 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -560,12 +560,12 @@ subsys_initcall(add_system_ram_resources);
  */
 int devmem_is_allowed(unsigned long pfn)
 {
+   if (page_is_rtas_user_buf(pfn))
+   return 1;
if (iomem_is_exclusive(PFN_PHYS(pfn)))
return 0;
if (!page_is_ram(pfn))
return 1;
-   if (page_is_rtas_user_buf(pfn))
-   return 1;
return 0;
 }
 #endif /* CONFIG_STRICT_DEVMEM */
-- 
2.1.0

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

Re: [PATCH v5] powerpc/pseries: Limit EPOW reset event warnings

2015-11-26 Thread Vasant Hegde
On 11/18/2015 02:12 PM, Vipin K Parashar wrote:
> Kernel prints respective warnings about various EPOW events for
> user information/action after parsing EPOW interrupts. At times
> below EPOW reset event warning is seen to be flooding kernel log
> over a period of time.
> 
> May 25 03:46:34 alp kernel: Non critical power or cooling issue cleared
> May 25 03:46:52 alp kernel: Non critical power or cooling issue cleared
> May 25 03:53:48 alp kernel: Non critical power or cooling issue cleared
> May 25 03:55:46 alp kernel: Non critical power or cooling issue cleared
> May 25 03:56:34 alp kernel: Non critical power or cooling issue cleared
> May 25 03:59:04 alp kernel: Non critical power or cooling issue cleared
> May 25 04:02:01 alp kernel: Non critical power or cooling issue cleared
> 

@Michael,
 I think above log is raising some concern. We have been asked by multiple
people on this. Hence I think we should avoid these duplicate messages.


> These EPOW reset events are spurious in nature and are triggered by
> firmware witout an actual EPOW event being reset. This patch avoids these

s/witout/without/

> multiple EPOW reset warnings by using a counter variable. This variable
> is incremented every time an EPOW event is reported. Upon receiving a EPOW
> reset event the same variable is checked to filer out spurious events and
> decremented accordingly.
> 
> This patch also improves log messages to better describe EPOW event being
> reported. Merged adjacent log messages into single one to reduce number of
> lines printed per event.
> 
> Signed-off-by: Kamalesh Babulal 
> Signed-off-by: Vipin K Parashar 
> ---
> v5 changes:
>- Used num_epow_events counter variable to count number of epow_events
>- Improved log messages to better describe epow event.
>- Merged adjacent warnings into single lines.
> 
> v4 changes:
>- Changed the approach to depth counter to match the EPOW events and
>  EPOW reset.
>- Converted pr_err() ot pr_info() for non-critical errors.
>- Merged adjacent warnings into single line across the file.
>- Fixed grammar in the warnings to make is short.
> 
> v3 changes:
>- Limit warning printed by EPOW RESET event, by guarding it with bool flag.
>  Instead of rate limiting all the EPOW events.
> 
> v2 changes:
>- Merged multiple adjacent pr_err/pr_emerg into single line to reduce 
> multi-line
>  warnings, based on Michael's comments.
> 
>  arch/powerpc/platforms/pseries/ras.c | 54 
> 
>  1 file changed, 30 insertions(+), 24 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/pseries/ras.c 
> b/arch/powerpc/platforms/pseries/ras.c
> index 3b6647e..bbe2856 100644
> --- a/arch/powerpc/platforms/pseries/ras.c
> +++ b/arch/powerpc/platforms/pseries/ras.c
> @@ -40,6 +40,8 @@ static int ras_check_exception_token;
>  #define EPOW_SENSOR_TOKEN9
>  #define EPOW_SENSOR_INDEX0
>  
> +static int num_epow_events;
> +
>  static irqreturn_t ras_epow_interrupt(int irq, void *dev_id);
>  static irqreturn_t ras_error_interrupt(int irq, void *dev_id);
>  
> @@ -82,32 +84,30 @@ static void handle_system_shutdown(char event_modifier)
>  {
>   switch (event_modifier) {
>   case EPOW_SHUTDOWN_NORMAL:
> - pr_emerg("Firmware initiated power off");
> + pr_emerg("Power off requested\n");

Why are you changing this  message? These are FW initiated Power off and helps
us to identify who initiated shutdown request.

>   orderly_poweroff(true);
>   break;
>  
>   case EPOW_SHUTDOWN_ON_UPS:
> - pr_emerg("Loss of power reported by firmware, system is "
> - "running on UPS/battery");
> - pr_emerg("Check RTAS error log for details");
> + pr_emerg("Loss of system power detected. System is running on"
> +  " UPS/battery. Check RTAS error log for details\n");
>   orderly_poweroff(true);
>   break;
>  
>   case EPOW_SHUTDOWN_LOSS_OF_CRITICAL_FUNCTIONS:
> - pr_emerg("Loss of system critical functions reported by "
> - "firmware");
> - pr_emerg("Check RTAS error log for details");
> + pr_emerg("Loss of system critical functions detected. Check"
> +  " RTAS error log for details\n");
>   orderly_poweroff(true);
>   break;
>  
>   case EPOW_SHUTDOWN_AMBIENT_TEMPERATURE_TOO_HIGH:
> - pr_emerg("Ambient temperature too high reported by firmware");
> - pr_emerg("Check RTAS error log for details");
> + pr_emerg("High ambient temperature detected. Check RTAS"
> +  " error log for details\n");
>   orderly_poweroff(true);
>   break;
>  
>   default:
> - pr_err("Unknown power/cooling shutdown event (modifier %d)",
> + pr_err("Unknown power/cooling shutdown event (modifier = %d)\n",
> 

Re: [PATCH] leds: powernv: Implement brightness_set_blocking op

2015-11-23 Thread Vasant Hegde
On 11/20/2015 09:11 PM, Jacek Anaszewski wrote:
> Since brightness setting can sleep for this driver, implement
> brightness_set_blocking op, instead of brightness_set.
> It makes this driver compatible with LED triggers.

Hello  Jacek,

Thanks for the patch. Looks good.. I will test this patch later this week and
update you the results.

I assume this patch is on top of LED git tree.

-Vasant

> 
> Signed-off-by: Jacek Anaszewski 
> Cc: Vasant Hegde 
> ---
>  drivers/leds/leds-powernv.c |   16 ++--
>  1 file changed, 10 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/leds/leds-powernv.c b/drivers/leds/leds-powernv.c
> index 1e75e1f..dd76f34 100644
> --- a/drivers/leds/leds-powernv.c
> +++ b/drivers/leds/leds-powernv.c
> @@ -77,7 +77,7 @@ static int powernv_get_led_type(const char *led_type_desc)
>   * This function is called from work queue task context when ever it gets
>   * scheduled. This function can sleep at opal_async_wait_response call.
>   */
> -static void powernv_led_set(struct powernv_led_data *powernv_led,
> +static int powernv_led_set(struct powernv_led_data *powernv_led,
>   enum led_brightness value)
>  {
>   int rc, token;
> @@ -99,7 +99,7 @@ static void powernv_led_set(struct powernv_led_data 
> *powernv_led,
>   if (token != -ERESTARTSYS)
>   dev_err(dev, "%s: Couldn't get OPAL async token\n",
>   __func__);
> - return;
> + return token;
>   }
>  
>   rc = opal_leds_set_ind(token, powernv_led->loc_code,
> @@ -125,6 +125,7 @@ static void powernv_led_set(struct powernv_led_data 
> *powernv_led,
>  
>  out_token:
>   opal_async_release_token(token);
> + return rc;
>  }
>  
>  /*
> @@ -173,20 +174,23 @@ static enum led_brightness powernv_led_get(struct 
> powernv_led_data *powernv_led)
>   * LED classdev 'brightness_get' function. This schedules work
>   * to update LED state.
>   */
> -static void powernv_brightness_set(struct led_classdev *led_cdev,
> +static int powernv_brightness_set(struct led_classdev *led_cdev,
>  enum led_brightness value)
>  {
>   struct powernv_led_data *powernv_led =
>   container_of(led_cdev, struct powernv_led_data, cdev);
>   struct powernv_led_common *powernv_led_common = powernv_led->common;
> + int rc;
>  
>   /* Do not modify LED in unload path */
>   if (powernv_led_common->led_disabled)
> - return;
> + return 0;
>  
>   mutex_lock(&powernv_led_common->lock);
> - powernv_led_set(powernv_led, value);
> + rc = powernv_led_set(powernv_led, value);
>   mutex_unlock(&powernv_led_common->lock);
> +
> + return rc;
>  }
>  
>  /* LED classdev 'brightness_get' function */
> @@ -227,7 +231,7 @@ static int powernv_led_create(struct device *dev,
>   return -ENOMEM;
>   }
>  
> - powernv_led->cdev.brightness_set = powernv_brightness_set;
> + powernv_led->cdev.brightness_set_blocking = powernv_brightness_set;
>   powernv_led->cdev.brightness_get = powernv_brightness_get;
>   powernv_led->cdev.brightness = LED_OFF;
>   powernv_led->cdev.max_brightness = LED_FULL;
> 

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

Re: [PATCH] rtas: Validate rtas entry before calling enter_rtas

2015-10-16 Thread Vasant Hegde
On 10/16/2015 11:49 PM, Denis Kirjanov wrote:
> On 10/16/15, Vasant Hegde  wrote:
>> On 10/16/2015 04:02 PM, Denis Kirjanov wrote:
>>> On 10/16/15, Vasant Hegde  wrote:
>>>> Currently we do not validate rtas entry before calling enter_rtas().
>>>> This
>>>> is resulting in a kernel oops (see below) when user space calls rtas
>>>> system
>>>> call on PowerNV platform. We hit below oops when we ran trinity (system
>>>> call
>>>> fuzzer) on PowerNV. This patch adds code to validate rtas entry before
>>>> making
>>>> enter_rtas() call.
>>>
>>> Hi,
>>> have you figured out why we have null entry?
>>
>> Denis,

Denis,

>>
>> Yes... On PowerNV platform we don't have RTAS.. Hence it's not initialized.
> But why do we have CONFIG_PPC_RTAS on OPAL machines then?


Sorry. I should have elaborated little bit..

Today we use single config to build kernel for both PowerNV and PAPR guest. So
that same ISO can be used in different environment (PAPR LPAR, PowerNV host,
guest). I believe most distro also following this method. Hence we need this
validation.

-Vasant

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

Re: [PATCH] rtas: Validate rtas entry before calling enter_rtas

2015-10-16 Thread Vasant Hegde
On 10/16/2015 04:02 PM, Denis Kirjanov wrote:
> On 10/16/15, Vasant Hegde  wrote:
>> Currently we do not validate rtas entry before calling enter_rtas(). This
>> is resulting in a kernel oops (see below) when user space calls rtas system
>> call on PowerNV platform. We hit below oops when we ran trinity (system call
>> fuzzer) on PowerNV. This patch adds code to validate rtas entry before
>> making
>> enter_rtas() call.
> 
> Hi,
> have you figured out why we have null entry?

Denis,

Yes... On PowerNV platform we don't have RTAS.. Hence it's not initialized.

-Vasant

> 
> Thanks!
>>
>> dmesg:
>> -
>> [22061.541428] Oops: Exception in kernel mode, sig: 4 [#1]
>> [22061.541446] SMP NR_CPUS=1024 NUMA PowerNV
>> [22061.541453] Modules linked in: rfcomm bnep nfnetlink scsi_transport_iscsi
>> hidp nfc af_802154 ieee802154 bluetooth rfkill pppoe pppox ppp_generic slhc
>> irda crc_ccitt af_key sctp libcrc32c atm appletalk ipx p8023 psnap p8022
>> ipt_MASQUERADE nf_nat_masquerade_ipv4 xt_CHECKSUM tun ip6t_rpfilter
>> ip6t_REJECT nf_reject_ipv6 nf_conntrack_ipv6 nf_defrag_ipv6 xt_conntrack
>> ebtable_nat ebtable_broute bridge stp llc ebtable_filter ebtables
>> ip6table_mangle ip6table_security ip6table_raw ip6table_filter ip6_tables
>> iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack
>> iptable_mangle iptable_security iptable_raw windfarm_smu_sat ses enclosure
>> windfarm_pid shpchp i2c_opal i2c_core kvm_hv kvm_pr dm_multipath kvm lpfc
>> tg3 ptp pps_core scsi_transport_fc
>> [22061.541561] CPU: 40 PID: 57748 Comm: trinity-c11 Not tainted
>> 3.18.17-340.el7_1.pkvm3_1_0.2400.1.ppc64le #1
>> [22061.541566] task: c4294b80 ti: c007e1a78000 task.ti:
>> c007e1a78000
>> [22061.541570] NIP:  LR: 9c14 CTR:
>> c0423140
>> [22061.541573] REGS: c007e1a7b920 TRAP: 0e40   Not tainted
>> (3.18.17-340.el7_1.pkvm3_1_0.2400.1.ppc64le)
>>  [22061.541577] MSR: 10081000   CR:   XER: 
>> 
>>  [22061.541585] CFAR: c0009c0c SOFTE: 0
>>  GPR00: 90001031 c007e1a7bba0 c12b1d00 
>> 01338840
>>  GPR04:   10001000 
>> 90001033
>>  GPR08: 4000 80002933 3fff9e9d0068 
>> 
>>  GPR12: 00ff c7db7c00  
>> 
>>  GPR16:    
>> 
>>  GPR20:    
>> 
>>  GPR24:  dc58 0001 
>> c01ee716e000
>>  GPR28:  c1338840 3fff9db3 
>> 
>>  [22061.541629] NIP []   (null)
>>  [22061.541637] LR [9c14] 0x9c14
>>  [22061.541640] Call Trace:
>>  [22061.541649] [c007e1a7bba0] [c041a7f4]
>> avc_has_perm_noaudit+0x54/0x110 (unreliable)
>>  [22061.541657] [c007e1a7bd80] [c002ddc0] 
>> ppc_rtas+0x150/0x2d0
>>  [22061.541662] [c007e1a7be30] [c0009358] 
>> syscall_exit+0x0/0x98
>>  [22061.541666] Instruction dump:
>>  [22061.541669]      
>>  
>>  [22061.541675]     6000 6000
>> 6000 6000
>>  [22061.541688] ---[ end trace 6f9bf0b3d32096aa ]---
>>
>> Reported-by: NAGESWARA R. SASTRY 
>> Signed-off-by: Vasant Hegde 
>> ---
>>  arch/powerpc/kernel/rtas.c |3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
>> index 84bf934..5a753fa 100644
>> --- a/arch/powerpc/kernel/rtas.c
>> +++ b/arch/powerpc/kernel/rtas.c
>> @@ -1043,6 +1043,9 @@ asmlinkage int ppc_rtas(struct rtas_args __user
>> *uargs)
>>  if (!capable(CAP_SYS_ADMIN))
>>  return -EPERM;
>>
>> +if (!rtas.entry)
>> +return -EINVAL;
>> +
>>  if (copy_from_user(&args, uargs, 3 * sizeof(u32)) != 0)
>>  return -EFAULT;
>>
>>
>> ___
>> Linuxppc-dev mailing list
>> Linuxppc-dev@lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/linuxppc-dev
> 

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

[PATCH] rtas: Validate rtas entry before calling enter_rtas

2015-10-16 Thread Vasant Hegde
Currently we do not validate rtas entry before calling enter_rtas(). This
is resulting in a kernel oops (see below) when user space calls rtas system
call on PowerNV platform. We hit below oops when we ran trinity (system call
fuzzer) on PowerNV. This patch adds code to validate rtas entry before making
enter_rtas() call.

dmesg:
-
[22061.541428] Oops: Exception in kernel mode, sig: 4 [#1]
[22061.541446] SMP NR_CPUS=1024 NUMA PowerNV
[22061.541453] Modules linked in: rfcomm bnep nfnetlink scsi_transport_iscsi 
hidp nfc af_802154 ieee802154 bluetooth rfkill pppoe pppox ppp_generic slhc 
irda crc_ccitt af_key sctp libcrc32c atm appletalk ipx p8023 psnap p8022 
ipt_MASQUERADE nf_nat_masquerade_ipv4 xt_CHECKSUM tun ip6t_rpfilter ip6t_REJECT 
nf_reject_ipv6 nf_conntrack_ipv6 nf_defrag_ipv6 xt_conntrack ebtable_nat 
ebtable_broute bridge stp llc ebtable_filter ebtables ip6table_mangle 
ip6table_security ip6table_raw ip6table_filter ip6_tables iptable_nat 
nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle 
iptable_security iptable_raw windfarm_smu_sat ses enclosure windfarm_pid shpchp 
i2c_opal i2c_core kvm_hv kvm_pr dm_multipath kvm lpfc tg3 ptp pps_core 
scsi_transport_fc
[22061.541561] CPU: 40 PID: 57748 Comm: trinity-c11 Not tainted 
3.18.17-340.el7_1.pkvm3_1_0.2400.1.ppc64le #1
[22061.541566] task: c4294b80 ti: c007e1a78000 task.ti: 
c007e1a78000
[22061.541570] NIP:  LR: 9c14 CTR: c0423140
[22061.541573] REGS: c007e1a7b920 TRAP: 0e40   Not tainted  
(3.18.17-340.el7_1.pkvm3_1_0.2400.1.ppc64le)
[22061.541577] MSR: 10081000   CR:   XER: 

[22061.541585] CFAR: c0009c0c SOFTE: 0
GPR00: 90001031 c007e1a7bba0 c12b1d00 
01338840
GPR04:   10001000 
90001033
GPR08: 4000 80002933 3fff9e9d0068 

GPR12: 00ff c7db7c00  

GPR16:    

GPR20:    

GPR24:  dc58 0001 
c01ee716e000
GPR28:  c1338840 3fff9db3 

[22061.541629] NIP []   (null)
[22061.541637] LR [9c14] 0x9c14
[22061.541640] Call Trace:
[22061.541649] [c007e1a7bba0] [c041a7f4] 
avc_has_perm_noaudit+0x54/0x110 (unreliable)
[22061.541657] [c007e1a7bd80] [c002ddc0] 
ppc_rtas+0x150/0x2d0
[22061.541662] [c007e1a7be30] [c0009358] 
syscall_exit+0x0/0x98
[22061.541666] Instruction dump:
[22061.541669]       
 
[22061.541675]     6000 6000 
6000 6000
[22061.541688] ---[ end trace 6f9bf0b3d32096aa ]---

Reported-by: NAGESWARA R. SASTRY 
Signed-off-by: Vasant Hegde 
---
 arch/powerpc/kernel/rtas.c |3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 84bf934..5a753fa 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -1043,6 +1043,9 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
 
+   if (!rtas.entry)
+   return -EINVAL;
+
if (copy_from_user(&args, uargs, 3 * sizeof(u32)) != 0)
return -EFAULT;
 

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

Re: [v2] powerpc/configs: Enable LEDS support

2015-08-27 Thread Vasant Hegde
On 08/27/2015 03:56 PM, Michael Ellerman wrote:
> On Thu, 2015-27-08 at 06:04:10 UTC, Vasant Hegde wrote:
>> Commit 84ad6e5c added LEDS support for PowerNV platform. Lets
>> update ppc64_defconfig to pick LEDS driver.
>>
>> PowerNV LEDS driver looks for "/ibm,opal/leds" node in device
>> tree and loads if this node exists. Hence added it as 'm'.
>>
>> Also note that powernv LEDS driver needs NEW_LEDS and LEDS_CLASS
>> as well. Hence added them to config file.
>>
>> Suggested-by: Michael Ellerman 
>> Signed-off-by: Vasant Hegde 
>> Cc: Stewart Smith 
>> ---
>> Changes in v2:
>>   - As suggested by Stewart updated patch description
>>
>> Michael,
>>   This is PowerNV specific config. Hence I've not updated pseries_defconfig.
>>   Let me know if you want me to update pseries_defconfig config as well.
> 
> I've added it to pseries_defconfig also, no need to resend.

Thanks!

-Vasant

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

[PATCH v2] powerpc/configs: Enable LEDS support

2015-08-26 Thread Vasant Hegde
Commit 84ad6e5c added LEDS support for PowerNV platform. Lets
update ppc64_defconfig to pick LEDS driver.

PowerNV LEDS driver looks for "/ibm,opal/leds" node in device
tree and loads if this node exists. Hence added it as 'm'.

Also note that powernv LEDS driver needs NEW_LEDS and LEDS_CLASS
as well. Hence added them to config file.

Suggested-by: Michael Ellerman 
Signed-off-by: Vasant Hegde 
Cc: Stewart Smith 
---
Changes in v2:
  - As suggested by Stewart updated patch description

Michael,
  This is PowerNV specific config. Hence I've not updated pseries_defconfig.
  Let me know if you want me to update pseries_defconfig config as well.

Vasant

 arch/powerpc/configs/ppc64_defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/powerpc/configs/ppc64_defconfig 
b/arch/powerpc/configs/ppc64_defconfig
index a97efc2..6bc0ee4 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -355,3 +355,6 @@ CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
 CONFIG_VIRTUALIZATION=y
 CONFIG_KVM_BOOK3S_64=m
 CONFIG_KVM_BOOK3S_64_HV=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+CONFIG_LEDS_POWERNV=m
-- 
2.1.0

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

Re: [PATCH] powerpc/configs: Enable LEDS support

2015-08-25 Thread Vasant Hegde
On 08/26/2015 05:56 AM, Stewart Smith wrote:
> Vasant Hegde  writes:
>> Presently PowerNV LEDS driver is specific to FSP based PowerNV
>> platform. Hence added it as 'm'. So that we will be loaded only
>> if we have required device tree support.

Stewart,

> 
> Currently the *firmware* support is FSP specific.
> 
> The driver should magically work on any OPAL machine that hooks up the
> OPAL calls and DT. Right?

Yep. It will just work if we have appropriate device tree . I'll update the
description and resend patch.


> 
> The A in OPAL is for Abstraction, not P for Passthrough-to-fsp.
> 

:-)

-Vasant

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

[PATCH] powerpc/configs: Enable LEDS support

2015-08-25 Thread Vasant Hegde
Commit 84ad6e5c added LEDS support for PowerNV platform. Lets
update ppc64_defconfig to pick LEDS driver.

Presently PowerNV LEDS driver is specific to FSP based PowerNV
platform. Hence added it as 'm'. So that we will be loaded only
if we have required device tree support.

Also note that powernv LEDS driver needs NEW_LEDS and LEDS_CLASS
as well. Hence added them to config file.

Suggested-by: Michael Ellerman 
Signed-off-by: Vasant Hegde 
---
Michael,
  This is PowerNV specific config. Hence I've not updated pseries_defconfig.
  Let me know if you want me to update pseries_defconfig config as well.

Vasant

 arch/powerpc/configs/ppc64_defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/powerpc/configs/ppc64_defconfig 
b/arch/powerpc/configs/ppc64_defconfig
index a97efc2..6bc0ee4 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -355,3 +355,6 @@ CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
 CONFIG_VIRTUALIZATION=y
 CONFIG_KVM_BOOK3S_64=m
 CONFIG_KVM_BOOK3S_64_HV=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+CONFIG_LEDS_POWERNV=m
-- 
2.1.0

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

Re: linux-next: build failure after merge of the powerpc tree

2015-08-21 Thread Vasant Hegde
On 08/22/2015 05:10 AM, Michael Ellerman wrote:
> On Fri, 2015-08-21 at 14:29 +0530, Vasant Hegde wrote:
>> On 08/21/2015 01:55 PM, Stephen Rothwell wrote:
>>> Hi all,
>>>
>>> After merging the nvdimm tree, today's linux-next build (powerpc
>>> allyesconfig) failed like this:
>>
>> Stephen,
>>
>> Thanks for reporting! I checked powerpc tree.. This is because of commit
>> 8a8d9181 in powerpc tree.. Basically Michael missed one hunk (below hunk in
>> opal-api.h)
> 
> Hmm, looks like it.
> 
> I do remember the patch didn't apply to my tree, so I guess I accidentally
> dropped a hunk when I was forcing it to apply.

Hmmm yeah..My patchset was based on pstream tree (4.2-rc7) instead of powerpc
next tree.


> 
> I also should have looked closer, as the following aren't in the skiboot
> version of opal-api.h. The skiboot and Linux versions of opal-api.h should be
> in sync as much as possible.
> 

As I mentioned in other thread I should have added all these macros to
opal-api.h in skiboot..


>> +/* LED Mode */
>> +#define POWERNV_LED_MODE_LIGHT_PATH"lightpath"
>> +#define POWERNV_LED_MODE_GUIDING_LIGHT "guidinglight"
>> +
>> +/* LED type */
>> +#define POWERNV_LED_TYPE_IDENTIFY  "identify"
>> +#define POWERNV_LED_TYPE_FAULT "fault"
>> +#define POWERNV_LED_TYPE_ATTENTION "attention"
> 
> Furthermore, I don't see the first two used at all, and the bottom three are
> only used in one place in the driver. So I've just sucked the values into the
> driver code and dropped the #defines. Patch coming shortly.
> 
> Also we're obviously not building this in any of our defconfigs. Can you 
> please
> send a patch to enable it for pseries_defconfig and ppc64_defconfig.

Sure.. Will send separate patch.

-Vasant

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

Re: [PATCH] powerpc/powernv: Fix mis-merge of OPAL support for LEDS driver

2015-08-21 Thread Vasant Hegde
On 08/22/2015 05:12 AM, Michael Ellerman wrote:
> When I merged the OPAL support for the powernv LEDS driver I missed a
> hunk.
> 
> This is slightly modified from the original patch, as the original added
> code to opal-api.h which is not in the skiboot version, which is
> discouraged.

Yeah. I should have made sure opal-api.h is in sync with skiboot. On skiboot
side I added below macros to fsp-leds.h instead of opal-api.h :-(

Anyway for now these macros are used by led driver only (on both side).. Hence I
think its fine to add to driver code itself. But we should make sure these
strings won't change as we use them while creating sysfs entries and use that
information to identify the type of LED.


> 
> Instead those values are moved into the driver, which is the only place
> they are used.
> 
> Fixes: 8a8d91817aec ("powerpc/powernv: Add OPAL interfaces for accessing and 
> modifying system LED states")
> Signed-off-by: Michael Ellerman 

Patch looks good.

Reviewed-by: Vasant Hegde 

-Vasant

> ---
>  arch/powerpc/include/asm/opal-api.h | 12 
>  drivers/leds/leds-powernv.c |  6 +++---
>  2 files changed, 15 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/opal-api.h 
> b/arch/powerpc/include/asm/opal-api.h
> index b516ec1d3b4c..9784c9241c70 100644
> --- a/arch/powerpc/include/asm/opal-api.h
> +++ b/arch/powerpc/include/asm/opal-api.h
> @@ -343,6 +343,18 @@ enum OpalPciResetState {
>   OPAL_ASSERT_RESET   = 1
>  };
> 
> +enum OpalSlotLedType {
> + OPAL_SLOT_LED_TYPE_ID = 0,  /* IDENTIFY LED */
> + OPAL_SLOT_LED_TYPE_FAULT = 1,   /* FAULT LED */
> + OPAL_SLOT_LED_TYPE_ATTN = 2,/* System Attention LED */
> + OPAL_SLOT_LED_TYPE_MAX = 3
> +};
> +
> +enum OpalSlotLedState {
> + OPAL_SLOT_LED_STATE_OFF = 0,/* LED is OFF */
> + OPAL_SLOT_LED_STATE_ON = 1  /* LED is ON */
> +};
> +
>  /*
>   * Address cycle types for LPC accesses. These also correspond
>   * to the content of the first cell of the "reg" property for
> diff --git a/drivers/leds/leds-powernv.c b/drivers/leds/leds-powernv.c
> index a2fea192573b..2c5c5b12ab64 100644
> --- a/drivers/leds/leds-powernv.c
> +++ b/drivers/leds/leds-powernv.c
> @@ -27,9 +27,9 @@ struct led_type_map {
>   const char  *desc;
>  };
>  static const struct led_type_map led_type_map[] = {
> - {OPAL_SLOT_LED_TYPE_ID, POWERNV_LED_TYPE_IDENTIFY},
> - {OPAL_SLOT_LED_TYPE_FAULT,  POWERNV_LED_TYPE_FAULT},
> - {OPAL_SLOT_LED_TYPE_ATTN,   POWERNV_LED_TYPE_ATTENTION},
> + {OPAL_SLOT_LED_TYPE_ID, "identify"},
> + {OPAL_SLOT_LED_TYPE_FAULT,  "fault"},
> + {OPAL_SLOT_LED_TYPE_ATTN,   "attention"},
>   {-1,NULL},
>  };
> 

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

Re: linux-next: build failure after merge of the powerpc tree

2015-08-21 Thread Vasant Hegde
On 08/21/2015 01:55 PM, Stephen Rothwell wrote:
> Hi all,
> 
> After merging the nvdimm tree, today's linux-next build (powerpc
> allyesconfig) failed like this:

Stephen,

Thanks for reporting! I checked powerpc tree.. This is because of commit
8a8d9181 in powerpc tree.. Basically Michael missed one hunk (below hunk in
opal-api.h)

+/* LED Mode */
+#define POWERNV_LED_MODE_LIGHT_PATH"lightpath"
+#define POWERNV_LED_MODE_GUIDING_LIGHT "guidinglight"
+
+/* LED type */
+#define POWERNV_LED_TYPE_IDENTIFY  "identify"
+#define POWERNV_LED_TYPE_FAULT "fault"
+#define POWERNV_LED_TYPE_ATTENTION "attention"
+
+enum OpalSlotLedType {
+   OPAL_SLOT_LED_TYPE_ID = 0,  /* IDENTIFY LED */
+   OPAL_SLOT_LED_TYPE_FAULT = 1,   /* FAULT LED */
+   OPAL_SLOT_LED_TYPE_ATTN = 2,/* System Attention LED */
+   OPAL_SLOT_LED_TYPE_MAX = 3
+};
+
+enum OpalSlotLedState {
+   OPAL_SLOT_LED_STATE_OFF = 0,/* LED is OFF */
+   OPAL_SLOT_LED_STATE_ON = 1  /* LED is ON */
+};
+


@Michael,
  Will you be fixing it or you want me to send separate patch for this one ?

-Vasant




> 
> drivers/leds/leds-powernv.c:30:3: error: 'OPAL_SLOT_LED_TYPE_ID' undeclared 
> here (not in a function)
>   {OPAL_SLOT_LED_TYPE_ID,  POWERNV_LED_TYPE_IDENTIFY},
>^
> drivers/leds/leds-powernv.c:30:27: error: 'POWERNV_LED_TYPE_IDENTIFY' 
> undeclared here (not in a function)
>   {OPAL_SLOT_LED_TYPE_ID,  POWERNV_LED_TYPE_IDENTIFY},
>^
> drivers/leds/leds-powernv.c:31:3: error: 'OPAL_SLOT_LED_TYPE_FAULT' 
> undeclared here (not in a function)
>   {OPAL_SLOT_LED_TYPE_FAULT, POWERNV_LED_TYPE_FAULT},
>^
> drivers/leds/leds-powernv.c:31:29: error: 'POWERNV_LED_TYPE_FAULT' undeclared 
> here (not in a function)
>   {OPAL_SLOT_LED_TYPE_FAULT, POWERNV_LED_TYPE_FAULT},
>  ^
> drivers/leds/leds-powernv.c:32:3: error: 'OPAL_SLOT_LED_TYPE_ATTN' undeclared 
> here (not in a function)
>   {OPAL_SLOT_LED_TYPE_ATTN, POWERNV_LED_TYPE_ATTENTION},
>^
> drivers/leds/leds-powernv.c:32:28: error: 'POWERNV_LED_TYPE_ATTENTION' 
> undeclared here (not in a function)
>   {OPAL_SLOT_LED_TYPE_ATTN, POWERNV_LED_TYPE_ATTENTION},
> ^
> drivers/leds/leds-powernv.c: In function 'powernv_led_set':
> drivers/leds/leds-powernv.c:92:13: error: 'OPAL_SLOT_LED_STATE_ON' undeclared 
> (first use in this function)
>   led_mask = OPAL_SLOT_LED_STATE_ON << powernv_led->led_type;
>  ^
> drivers/leds/leds-powernv.c:92:13: note: each undeclared identifier is 
> reported only once for each function it appears in
> drivers/leds/leds-powernv.c:92:36: error: invalid operands to binary << (have 
> 'const struct led_type_map *' and 'int')
>   led_mask = OPAL_SLOT_LED_STATE_ON << powernv_led->led_type;
> ^
> drivers/leds/leds-powernv.c:92:11: warning: assignment makes integer from 
> pointer without a cast
>   led_mask = OPAL_SLOT_LED_STATE_ON << powernv_led->led_type;
>^
> drivers/leds/leds-powernv.c: In function 'powernv_led_get':
> drivers/leds/leds-powernv.c:159:46: error: 'OPAL_SLOT_LED_STATE_ON' 
> undeclared (first use in this function)
>   if (!((led_mask >> powernv_led->led_type) & OPAL_SLOT_LED_STATE_ON)) {
>   ^
> drivers/leds/leds-powernv.c:159:44: error: invalid operands to binary & (have 
> 'u64' and 'const struct led_type_map *')
>   if (!((led_mask >> powernv_led->led_type) & OPAL_SLOT_LED_STATE_ON)) {
> ^
> drivers/leds/leds-powernv.c:166:43: error: invalid operands to binary & (have 
> 'u64' and 'const struct led_type_map *')
>   if ((led_value >> powernv_led->led_type) & OPAL_SLOT_LED_STATE_ON)
>^
> In file included from include/linux/byteorder/big_endian.h:4:0,
>  from arch/powerpc/include/uapi/asm/byteorder.h:13,
>  from include/asm-generic/bitops/le.h:5,
>  from arch/powerpc/include/asm/bitops.h:279,
>  from include/linux/bitops.h:36,
>  from include/linux/kernel.h:10,
>  from include/linux/list.h:8,
>  from include/linux/kobject.h:20,
>  from include/linux/device.h:17,
>  from include/linux/leds.h:15,
>  from drivers/leds/leds-powernv.c:15:
> drivers/leds/leds-powernv.c: In function 'powernv_led_probe':
> drivers/leds/leds-powernv.c:300:49: error: 'OPAL_SLOT_LED_TYPE_MAX' 
> undeclared (first use in this function)
>   powernv_led_common->max_led_type = cpu_to_be64(OPAL_SLOT_LED_TYPE_MAX);
>  ^
> include/uapi/linux/byteorder/big_endian.h:36:51: note: in definition of macro 
> '__cpu_to_be64'
>  #define __cpu_to_be64(x) ((__force __be64)(__u64)(x))
>^
> drivers/leds/leds-powernv.c:300:37: note: in

[PATCH v10 2/3] powerpc/powernv: Create LED platform device

2015-08-19 Thread Vasant Hegde
This patch adds platform devices for leds. Also export LED related
OPAL API's so that led driver can use these APIs.

Signed-off-by: Vasant Hegde 
Acked-by: Benjamin Herrenschmidt 
---
 arch/powerpc/platforms/powernv/opal.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index f084afa..6839358 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -648,7 +648,7 @@ static void opal_init_heartbeat(void)
 
 static int __init opal_init(void)
 {
-   struct device_node *np, *consoles;
+   struct device_node *np, *consoles, *leds;
int rc;
 
opal_node = of_find_node_by_path("/ibm,opal");
@@ -689,6 +689,13 @@ static int __init opal_init(void)
/* Setup a heatbeat thread if requested by OPAL */
opal_init_heartbeat();
 
+   /* Create leds platform devices */
+   leds = of_find_node_by_path("/ibm,opal/leds");
+   if (leds) {
+   of_platform_device_create(leds, "opal_leds", NULL);
+   of_node_put(leds);
+   }
+
/* Create "opal" kobject under /sys/firmware */
rc = opal_sysfs_init();
if (rc == 0) {
@@ -841,3 +848,6 @@ EXPORT_SYMBOL_GPL(opal_rtc_write);
 EXPORT_SYMBOL_GPL(opal_tpo_read);
 EXPORT_SYMBOL_GPL(opal_tpo_write);
 EXPORT_SYMBOL_GPL(opal_i2c_request);
+/* Export these symbols for PowerNV LED class driver */
+EXPORT_SYMBOL_GPL(opal_leds_get_ind);
+EXPORT_SYMBOL_GPL(opal_leds_set_ind);
-- 
2.1.0

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

[PATCH v10 3/3] leds/powernv: Add driver for PowerNV platform

2015-08-19 Thread Vasant Hegde
This patch implements LED driver for PowerNV platform using the existing
generic LED class framework.

PowerNV platform has below type of LEDs:
  - System attention
  Indicates there is a problem with the system that needs attention.
  - Identify
  Helps the user locate/identify a particular FRU or resource in the
  system.
  - Fault
  Indicates there is a problem with the FRU or resource at the
  location with which the indicator is associated.

We register classdev structures for all individual LEDs detected on the
system through LED specific device tree nodes. Device tree nodes specify
what all kind of LEDs present on the same location code. It registers
LED classdev structure for each of them.

All the system LEDs can be found in the same regular path /sys/class/leds/.
We don't use LED colors. We use LED node and led-types property to form
LED classdev. Our LEDs have names in this format.

:

Any positive brightness value would turn on the LED and a zero value would
turn off the LED. The driver will return LED_FULL (255) for any turned on
LED and LED_OFF (0) for any turned off LED.

The platform level implementation of LED get and set state has been
achieved through OPAL calls. These calls are made available for the
driver by exporting from architecture specific codes.

Signed-off-by: Vasant Hegde 
Signed-off-by: Anshuman Khandual 
Acked-by: Stewart Smith 
Tested-by: Stewart Smith 
Acked-by: Jacek Anaszewski 
---
 .../devicetree/bindings/leds/leds-powernv.txt  |  26 ++
 drivers/leds/Kconfig   |  11 +
 drivers/leds/Makefile  |   1 +
 drivers/leds/leds-powernv.c| 345 +
 4 files changed, 383 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-powernv.txt
 create mode 100644 drivers/leds/leds-powernv.c

diff --git a/Documentation/devicetree/bindings/leds/leds-powernv.txt 
b/Documentation/devicetree/bindings/leds/leds-powernv.txt
new file mode 100644
index 000..6665569
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/leds-powernv.txt
@@ -0,0 +1,26 @@
+Device Tree binding for LEDs on IBM Power Systems
+-
+
+Required properties:
+- compatible : Should be "ibm,opal-v3-led".
+- led-mode   : Should be "lightpath" or "guidinglight".
+
+Each location code of FRU/Enclosure must be expressed in the
+form of a sub-node.
+
+Required properties for the sub nodes:
+- led-types : Supported LED types (attention/identify/fault) provided
+  in the form of string array.
+
+Example:
+
+leds {
+   compatible = "ibm,opal-v3-led";
+   led-mode = "lightpath";
+
+   U78C9.001.RST0027-P1-C1 {
+   led-types = "identify", "fault";
+   };
+   ...
+   ...
+};
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 9ad35f7..f218cc3a 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -560,6 +560,17 @@ config LEDS_BLINKM
  This option enables support for the BlinkM RGB LED connected
  through I2C. Say Y to enable support for the BlinkM LED.
 
+config LEDS_POWERNV
+   tristate "LED support for PowerNV Platform"
+   depends on LEDS_CLASS
+   depends on PPC_POWERNV
+   depends on OF
+   help
+ This option enables support for the system LEDs present on
+ PowerNV platforms. Say 'y' to enable this support in kernel.
+ To compile this driver as a module, choose 'm' here: the module
+ will be called leds-powernv.
+
 config LEDS_SYSCON
bool "LED support for LEDs on system controllers"
depends on LEDS_CLASS=y
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 8d6a24a..6a943d1 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_LEDS_VERSATILE)  += leds-versatile.o
 obj-$(CONFIG_LEDS_MENF21BMC)   += leds-menf21bmc.o
 obj-$(CONFIG_LEDS_PM8941_WLED) += leds-pm8941-wled.o
 obj-$(CONFIG_LEDS_KTD2692) += leds-ktd2692.o
+obj-$(CONFIG_LEDS_POWERNV) += leds-powernv.o
 
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)  += leds-dac124s085.o
diff --git a/drivers/leds/leds-powernv.c b/drivers/leds/leds-powernv.c
new file mode 100644
index 000..a2fea19
--- /dev/null
+++ b/drivers/leds/leds-powernv.c
@@ -0,0 +1,345 @@
+/*
+ * PowerNV LED Driver
+ *
+ * Copyright IBM Corp. 2015
+ *
+ * Author: Vasant Hegde 
+ * Author: Anshuman Khandual 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#inc

[PATCH v10 1/3] powerpc/powernv: Add OPAL interfaces for accessing and modifying system LED states

2015-08-19 Thread Vasant Hegde
From: Anshuman Khandual 

This patch registers the following two new OPAL interfaces calls
for the platform LED subsystem. With the help of these new OPAL calls,
the kernel will be able to get or set the state of various individual
LEDs on the system at any given location code which is passed through
the LED specific device tree nodes.

(1) OPAL_LEDS_GET_INDICATOR opal_leds_get_ind
(2) OPAL_LEDS_SET_INDICATOR opal_leds_set_ind

Signed-off-by: Anshuman Khandual 
Signed-off-by: Vasant Hegde 
Acked-by: Stewart Smith 
Tested-by: Stewart Smith 
Acked-by: Benjamin Herrenschmidt 
---
 arch/powerpc/include/asm/opal-api.h| 25 -
 arch/powerpc/include/asm/opal.h|  4 
 arch/powerpc/platforms/powernv/opal-wrappers.S |  2 ++
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/opal-api.h 
b/arch/powerpc/include/asm/opal-api.h
index e9e4c52..8f8c45f 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -154,7 +154,9 @@
 #define OPAL_FLASH_WRITE   111
 #define OPAL_FLASH_ERASE   112
 #define OPAL_PRD_MSG   113
-#define OPAL_LAST  113
+#define OPAL_LEDS_GET_INDICATOR114
+#define OPAL_LEDS_SET_INDICATOR115
+#define OPAL_LAST  115
 
 /* Device tree flags */
 
@@ -756,6 +758,27 @@ struct opal_i2c_request {
__be64 buffer_ra;   /* Buffer real address */
 };
 
+/* LED Mode */
+#define POWERNV_LED_MODE_LIGHT_PATH"lightpath"
+#define POWERNV_LED_MODE_GUIDING_LIGHT "guidinglight"
+
+/* LED type */
+#define POWERNV_LED_TYPE_IDENTIFY  "identify"
+#define POWERNV_LED_TYPE_FAULT "fault"
+#define POWERNV_LED_TYPE_ATTENTION "attention"
+
+enum OpalSlotLedType {
+   OPAL_SLOT_LED_TYPE_ID = 0,  /* IDENTIFY LED */
+   OPAL_SLOT_LED_TYPE_FAULT = 1,   /* FAULT LED */
+   OPAL_SLOT_LED_TYPE_ATTN = 2,/* System Attention LED */
+   OPAL_SLOT_LED_TYPE_MAX = 3
+};
+
+enum OpalSlotLedState {
+   OPAL_SLOT_LED_STATE_OFF = 0,/* LED is OFF */
+   OPAL_SLOT_LED_STATE_ON = 1  /* LED is ON */
+};
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __OPAL_API_H */
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 958e941..3233e6d 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -195,6 +195,10 @@ int64_t opal_ipmi_recv(uint64_t interface, struct 
opal_ipmi_msg *msg,
 int64_t opal_i2c_request(uint64_t async_token, uint32_t bus_id,
 struct opal_i2c_request *oreq);
 int64_t opal_prd_msg(struct opal_prd_msg *msg);
+int64_t opal_leds_get_ind(char *loc_code, __be64 *led_mask,
+ __be64 *led_value, __be64 *max_led_type);
+int64_t opal_leds_set_ind(uint64_t token, char *loc_code, const u64 led_mask,
+ const u64 led_value, __be64 *max_led_type);
 
 int64_t opal_flash_read(uint64_t id, uint64_t offset, uint64_t buf,
uint64_t size, uint64_t token);
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S 
b/arch/powerpc/platforms/powernv/opal-wrappers.S
index d6a7b82..34c2734 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -297,3 +297,5 @@ 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_leds_get_ind,   OPAL_LEDS_GET_INDICATOR);
+OPAL_CALL(opal_leds_set_ind,   OPAL_LEDS_SET_INDICATOR);
-- 
2.1.0

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

[PATCH v10 0/3] LED driver for PowerNV platform

2015-08-19 Thread Vasant Hegde
The following series implements LED driver for PowerNV platform.

PowerNV platform has below type of LEDs:
  - System attention
  Indicates there is a problem with the system that needs attention.
  - Identify
  Helps the user locate/identify a particular FRU or resource in the
  system.
  - Fault
  Indicates there is a problem with the FRU or resource at the
  location with which the indicator is associated.

On PowerNV (Non Virtualized) platform OPAL firmware provides LED information
to host via device tree (location code and LED type). During init we check
for 'ibm,opal/leds' node in device tree to enable LED driver. And we use
OPAL API's to get/set LEDs.

Note that on PowerNV platform firmware can activate fault LED, if it can isolate
the problem. Also one can modify the LEDs using service processor interface. 
None
of these involes kernel. Hence we retain LED state in unload path.

Sample LED device tree output:
--
leds {
compatible = "ibm,opal-v3-led";
led-mode = "lightpath";

U78C9.001.RST0027-P1-C1 {
led-types = "identify", "fault";
};
...
...
}

Sample sysfs output:

.
├── U78CB.001.WZS008R-A1:fault
│   ├── brightness
│   ├── device -> ../../../opal_leds
│   ├── max_brightness
│   ├── power
│   │   ├── async
│   │   ├── autosuspend_delay_ms
│   │   ├── control
│   │   ├── runtime_active_kids
│   │   ├── runtime_active_time
│   │   ├── runtime_enabled
│   │   ├── runtime_status
│   │   ├── runtime_suspended_time
│   │   └── runtime_usage
│   ├── subsystem -> ../../../../../class/leds
│   ├── trigger
│   └── uevent
├── U78CB.001.WZS008R-A1:identify
│   ├── brightness
│   ├── device -> ../../../opal_leds
│   ├── max_brightness
│   ├── power
│   │   ├── async
│   │   ├── autosuspend_delay_ms
│   │   ├── control
│   │   ├── runtime_active_kids
│   │   ├── runtime_active_time
│   │   ├── runtime_enabled
│   │   ├── runtime_status
│   │   ├── runtime_suspended_time
│   │   └── runtime_usage
│   ├── subsystem -> ../../../../../class/leds
│   ├── trigger
│   └── uevent




patch 1/2: PowerNV architecture specific code. This adds necessary
   OPAL APIs.
patch 2/2: Create LED platform device and export OPAL symbols
patch 3/3: Actual LED driver implemenation for PowerNV platform.

Note:
 - This version of patchset is based on top of v4.2-rc7.

@Ben/Michael,
  This patchset is Acked by LED subsystem maintainer (Jacek) [1] and he
  suggested merge it via powerpc tree [1]. Can you please review/take
  this patchset?

[1] https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-July/131695.html

Previous patchset:
  v9: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-August/132964.html
  v8: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-July/131652.html
  v7: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-July/131533.html
  v6: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-July/131328.html
  v5: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-July/130602.html
  v4: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-April/128028.html
  v3: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-April/127702.html
  v2: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-March/126301.html
  v1: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-March/125705.html

Changes in v10:
  - Removed "led_disabled" variable initialization
  - Removed ".owner = THIS_MODULE"

Changes in v9:
  - Addressed minor comments from Jacek.
  - Added Ack-by: Jacek

Changes in v8:
  - Added powernv_led_common structure for common variables
  - Removed unused variable 'value'
  - Fixed locking issue

Changes in v7:
  - Club powernv_led_data & powernv_leds_priv into single structure
  - Removed num_leds & powernv_leds_count()
  - Replaced per LED mutex with global mutex
  - Removed driver specific workqueue. Instead this version uses new
global workqueue.

Changes in v6:
  - Added loc_code and type to powernv_led_data structure instead of parsing
them from led classdev name.
  - Fixed documentation issues.
  - Fixed mutex_destry issue
  - Replaced led_classdev_register with devm_led_classdev_register

Changes in v5:
  - Rebased on top of Linus tree
  - Renamed led as leds and updated documentation
  - As Ben and Arnd suggested, removed phandle from documenation
  - As Ben suggested removed led-loc device tree property
  - As Jacek suggested, added back compatible property to documentation

Changes in v4:
  - Updated macros to reflect platform.
  - s/u64/__be64/g for big endian data we get from firmware
  - Addressed review comments from Jacek. Major once are:
Removed list in powernv_led_data structure
s/kzalloc/devm_kzalloc/
Removed compatible property from documentation


Anshuman Khandual (1):
  powerpc/powernv: Add OPAL interfaces fo

Re: [PATCH v9 3/3] leds/powernv: Add driver for PowerNV platform

2015-08-19 Thread Vasant Hegde
On 08/19/2015 06:08 PM, Jacek Anaszewski wrote:
> Hi Vasant,

Hello Jacek,

> 
> I've found two superfluous lines. Please find my remarks below.

Thanks for the review. I will fix both issues and will send v10 soon.

-Vasant

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

Re: [PATCH v8 3/3] leds/powernv: Add driver for PowerNV platform

2015-08-19 Thread Vasant Hegde
On 08/19/2015 05:24 PM, Jacek Anaszewski wrote:
> Hi Vasant,
> 
> On 07/28/2015 07:40 PM, Jacek Anaszewski wrote:
>> Vasant,
>>
>>>

 Without my core changes your driver won't work with led triggers, but
 AFAIR this use case is not relevant for your LEDs? Eventually, we could
 produce a patch set adding support for LED triggers if it will be clear
 that LED core changes will not be merged in the upcoming merge window.
>>>
>>> IIUC current LED code doesn't allow me to sleep (without driver specific
>>> workqueue). And powernv_led_set() call will sleep. Hence I think it
>>> won't work.
>>>
>>> I did a quick test without your patch. It doesn't seems to be working.
> 

Jacek,

> Does brightness setting work properly without work queue?
> 

Sorry ...  I forgot to respond to this thread..

Yes.. It worked for me..

I have tested v9 with and without your code patchset.. In both cases its working
fine..

Sample test case :
[root@tul176p1 leds]# cd U78C9.001.RST0027-P1-C14:identify

[root@tul176p1 U78C9.001.RST0027-P1-C14:identify]# pwd
/sys/class/leds/U78C9.001.RST0027-P1-C14:identify

[root@tul176p1 U78C9.001.RST0027-P1-C14:identify]# cat brightness
0

[root@tul176p1 U78C9.001.RST0027-P1-C14:identify]# echo 1 > brightness
[root@tul176p1 U78C9.001.RST0027-P1-C14:identify]# cat brightness
255

-Vasant

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

[PATCH v9 1/3] powerpc/powernv: Add OPAL interfaces for accessing and modifying system LED states

2015-08-19 Thread Vasant Hegde
From: Anshuman Khandual 

This patch registers the following two new OPAL interfaces calls
for the platform LED subsystem. With the help of these new OPAL calls,
the kernel will be able to get or set the state of various individual
LEDs on the system at any given location code which is passed through
the LED specific device tree nodes.

(1) OPAL_LEDS_GET_INDICATOR opal_leds_get_ind
(2) OPAL_LEDS_SET_INDICATOR opal_leds_set_ind

Signed-off-by: Anshuman Khandual 
Signed-off-by: Vasant Hegde 
Acked-by: Stewart Smith 
Tested-by: Stewart Smith 
Acked-by: Benjamin Herrenschmidt 
---
 arch/powerpc/include/asm/opal-api.h| 25 -
 arch/powerpc/include/asm/opal.h|  4 
 arch/powerpc/platforms/powernv/opal-wrappers.S |  2 ++
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/opal-api.h 
b/arch/powerpc/include/asm/opal-api.h
index e9e4c52..8f8c45f 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -154,7 +154,9 @@
 #define OPAL_FLASH_WRITE   111
 #define OPAL_FLASH_ERASE   112
 #define OPAL_PRD_MSG   113
-#define OPAL_LAST  113
+#define OPAL_LEDS_GET_INDICATOR114
+#define OPAL_LEDS_SET_INDICATOR115
+#define OPAL_LAST  115
 
 /* Device tree flags */
 
@@ -756,6 +758,27 @@ struct opal_i2c_request {
__be64 buffer_ra;   /* Buffer real address */
 };
 
+/* LED Mode */
+#define POWERNV_LED_MODE_LIGHT_PATH"lightpath"
+#define POWERNV_LED_MODE_GUIDING_LIGHT "guidinglight"
+
+/* LED type */
+#define POWERNV_LED_TYPE_IDENTIFY  "identify"
+#define POWERNV_LED_TYPE_FAULT "fault"
+#define POWERNV_LED_TYPE_ATTENTION "attention"
+
+enum OpalSlotLedType {
+   OPAL_SLOT_LED_TYPE_ID = 0,  /* IDENTIFY LED */
+   OPAL_SLOT_LED_TYPE_FAULT = 1,   /* FAULT LED */
+   OPAL_SLOT_LED_TYPE_ATTN = 2,/* System Attention LED */
+   OPAL_SLOT_LED_TYPE_MAX = 3
+};
+
+enum OpalSlotLedState {
+   OPAL_SLOT_LED_STATE_OFF = 0,/* LED is OFF */
+   OPAL_SLOT_LED_STATE_ON = 1  /* LED is ON */
+};
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __OPAL_API_H */
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 958e941..3233e6d 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -195,6 +195,10 @@ int64_t opal_ipmi_recv(uint64_t interface, struct 
opal_ipmi_msg *msg,
 int64_t opal_i2c_request(uint64_t async_token, uint32_t bus_id,
 struct opal_i2c_request *oreq);
 int64_t opal_prd_msg(struct opal_prd_msg *msg);
+int64_t opal_leds_get_ind(char *loc_code, __be64 *led_mask,
+ __be64 *led_value, __be64 *max_led_type);
+int64_t opal_leds_set_ind(uint64_t token, char *loc_code, const u64 led_mask,
+ const u64 led_value, __be64 *max_led_type);
 
 int64_t opal_flash_read(uint64_t id, uint64_t offset, uint64_t buf,
uint64_t size, uint64_t token);
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S 
b/arch/powerpc/platforms/powernv/opal-wrappers.S
index d6a7b82..34c2734 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -297,3 +297,5 @@ 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_leds_get_ind,   OPAL_LEDS_GET_INDICATOR);
+OPAL_CALL(opal_leds_set_ind,   OPAL_LEDS_SET_INDICATOR);
-- 
2.1.0

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

[PATCH v9 3/3] leds/powernv: Add driver for PowerNV platform

2015-08-19 Thread Vasant Hegde
This patch implements LED driver for PowerNV platform using the existing
generic LED class framework.

PowerNV platform has below type of LEDs:
  - System attention
  Indicates there is a problem with the system that needs attention.
  - Identify
  Helps the user locate/identify a particular FRU or resource in the
  system.
  - Fault
  Indicates there is a problem with the FRU or resource at the
  location with which the indicator is associated.

We register classdev structures for all individual LEDs detected on the
system through LED specific device tree nodes. Device tree nodes specify
what all kind of LEDs present on the same location code. It registers
LED classdev structure for each of them.

All the system LEDs can be found in the same regular path /sys/class/leds/.
We don't use LED colors. We use LED node and led-types property to form
LED classdev. Our LEDs have names in this format.

:

Any positive brightness value would turn on the LED and a zero value would
turn off the LED. The driver will return LED_FULL (255) for any turned on
LED and LED_OFF (0) for any turned off LED.

The platform level implementation of LED get and set state has been
achieved through OPAL calls. These calls are made available for the
driver by exporting from architecture specific codes.

Signed-off-by: Vasant Hegde 
Signed-off-by: Anshuman Khandual 
Acked-by: Stewart Smith 
Tested-by: Stewart Smith 
Acked-by: Jacek Anaszewski 
---
 .../devicetree/bindings/leds/leds-powernv.txt  |  26 ++
 drivers/leds/Kconfig   |  11 +
 drivers/leds/Makefile  |   1 +
 drivers/leds/leds-powernv.c| 347 +
 4 files changed, 385 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-powernv.txt
 create mode 100644 drivers/leds/leds-powernv.c

diff --git a/Documentation/devicetree/bindings/leds/leds-powernv.txt 
b/Documentation/devicetree/bindings/leds/leds-powernv.txt
new file mode 100644
index 000..6665569
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/leds-powernv.txt
@@ -0,0 +1,26 @@
+Device Tree binding for LEDs on IBM Power Systems
+-
+
+Required properties:
+- compatible : Should be "ibm,opal-v3-led".
+- led-mode   : Should be "lightpath" or "guidinglight".
+
+Each location code of FRU/Enclosure must be expressed in the
+form of a sub-node.
+
+Required properties for the sub nodes:
+- led-types : Supported LED types (attention/identify/fault) provided
+  in the form of string array.
+
+Example:
+
+leds {
+   compatible = "ibm,opal-v3-led";
+   led-mode = "lightpath";
+
+   U78C9.001.RST0027-P1-C1 {
+   led-types = "identify", "fault";
+   };
+   ...
+   ...
+};
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 9ad35f7..f218cc3a 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -560,6 +560,17 @@ config LEDS_BLINKM
  This option enables support for the BlinkM RGB LED connected
  through I2C. Say Y to enable support for the BlinkM LED.
 
+config LEDS_POWERNV
+   tristate "LED support for PowerNV Platform"
+   depends on LEDS_CLASS
+   depends on PPC_POWERNV
+   depends on OF
+   help
+ This option enables support for the system LEDs present on
+ PowerNV platforms. Say 'y' to enable this support in kernel.
+ To compile this driver as a module, choose 'm' here: the module
+ will be called leds-powernv.
+
 config LEDS_SYSCON
bool "LED support for LEDs on system controllers"
depends on LEDS_CLASS=y
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 8d6a24a..6a943d1 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_LEDS_VERSATILE)  += leds-versatile.o
 obj-$(CONFIG_LEDS_MENF21BMC)   += leds-menf21bmc.o
 obj-$(CONFIG_LEDS_PM8941_WLED) += leds-pm8941-wled.o
 obj-$(CONFIG_LEDS_KTD2692) += leds-ktd2692.o
+obj-$(CONFIG_LEDS_POWERNV) += leds-powernv.o
 
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)  += leds-dac124s085.o
diff --git a/drivers/leds/leds-powernv.c b/drivers/leds/leds-powernv.c
new file mode 100644
index 000..ac3fdf5
--- /dev/null
+++ b/drivers/leds/leds-powernv.c
@@ -0,0 +1,347 @@
+/*
+ * PowerNV LED Driver
+ *
+ * Copyright IBM Corp. 2015
+ *
+ * Author: Vasant Hegde 
+ * Author: Anshuman Khandual 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#inc

[PATCH v9 0/3] LED driver for PowerNV platform

2015-08-19 Thread Vasant Hegde
The following series implements LED driver for PowerNV platform.

PowerNV platform has below type of LEDs:
  - System attention
  Indicates there is a problem with the system that needs attention.
  - Identify
  Helps the user locate/identify a particular FRU or resource in the
  system.
  - Fault
  Indicates there is a problem with the FRU or resource at the
  location with which the indicator is associated.

On PowerNV (Non Virtualized) platform OPAL firmware provides LED information
to host via device tree (location code and LED type). During init we check
for 'ibm,opal/leds' node in device tree to enable LED driver. And we use
OPAL API's to get/set LEDs.

Note that on PowerNV platform firmware can activate fault LED, if it can isolate
the problem. Also one can modify the LEDs using service processor interface. 
None
of these involes kernel. Hence we retain LED state in unload path.

Sample LED device tree output:
--
leds {
compatible = "ibm,opal-v3-led";
led-mode = "lightpath";

U78C9.001.RST0027-P1-C1 {
led-types = "identify", "fault";
};
...
...
}

Sample sysfs output:

.
├── U78CB.001.WZS008R-A1:fault
│   ├── brightness
│   ├── device -> ../../../opal_leds
│   ├── max_brightness
│   ├── power
│   │   ├── async
│   │   ├── autosuspend_delay_ms
│   │   ├── control
│   │   ├── runtime_active_kids
│   │   ├── runtime_active_time
│   │   ├── runtime_enabled
│   │   ├── runtime_status
│   │   ├── runtime_suspended_time
│   │   └── runtime_usage
│   ├── subsystem -> ../../../../../class/leds
│   ├── trigger
│   └── uevent
├── U78CB.001.WZS008R-A1:identify
│   ├── brightness
│   ├── device -> ../../../opal_leds
│   ├── max_brightness
│   ├── power
│   │   ├── async
│   │   ├── autosuspend_delay_ms
│   │   ├── control
│   │   ├── runtime_active_kids
│   │   ├── runtime_active_time
│   │   ├── runtime_enabled
│   │   ├── runtime_status
│   │   ├── runtime_suspended_time
│   │   └── runtime_usage
│   ├── subsystem -> ../../../../../class/leds
│   ├── trigger
│   └── uevent




patch 1/2: PowerNV architecture specific code. This adds necessary
   OPAL APIs.
patch 2/2: Create LED platform device and export OPAL symbols
patch 3/3: Actual LED driver implemenation for PowerNV platform.

Note:
 - This version of patchset is based on top of v4.2-rc7.

@Ben/Michael,
  This patchset is Acked by LED subsystem maintainer (Jacek) [1] and he
  suggested merge it via powerpc tree [1]. Can you please review/take
  this patchset?

[1] https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-July/131695.html

Previous patchset:
  v8: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-July/131652.html
  v7: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-July/131533.html
  v6: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-July/131328.html
  v5: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-July/130602.html
  v4: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-April/128028.html
  v3: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-April/127702.html
  v2: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-March/126301.html
  v1: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-March/125705.html

Changes in v9:
  - Addressed minor comments from Jacek.
  - Added Ack-by: Jacek

Changes in v8:
  - Added powernv_led_common structure for common variables
  - Removed unused variable 'value'
  - Fixed locking issue

Changes in v7:
  - Club powernv_led_data & powernv_leds_priv into single structure
  - Removed num_leds & powernv_leds_count()
  - Replaced per LED mutex with global mutex
  - Removed driver specific workqueue. Instead this version uses new
global workqueue.

Changes in v6:
  - Added loc_code and type to powernv_led_data structure instead of parsing
them from led classdev name.
  - Fixed documentation issues.
  - Fixed mutex_destry issue
  - Replaced led_classdev_register with devm_led_classdev_register

Changes in v5:
  - Rebased on top of Linus tree
  - Renamed led as leds and updated documentation
  - As Ben and Arnd suggested, removed phandle from documenation
  - As Ben suggested removed led-loc device tree property
  - As Jacek suggested, added back compatible property to documentation

Changes in v4:
  - Updated macros to reflect platform.
  - s/u64/__be64/g for big endian data we get from firmware
  - Addressed review comments from Jacek. Major once are:
Removed list in powernv_led_data structure
s/kzalloc/devm_kzalloc/
Removed compatible property from documentation


Anshuman Khandual (1):
  powerpc/powernv: Add OPAL interfaces for accessing and modifying
system LED states

Vasant Hegde (2):
  powerpc/powernv: Create LED platform device
  leds/powernv: Add driver for PowerNV platform
  - Removed redundant code in leds-power

[PATCH v9 2/3] powerpc/powernv: Create LED platform device

2015-08-19 Thread Vasant Hegde
This patch adds platform devices for leds. Also export LED related
OPAL API's so that led driver can use these APIs.

Signed-off-by: Vasant Hegde 
Acked-by: Benjamin Herrenschmidt 
---
 arch/powerpc/platforms/powernv/opal.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index f084afa..6839358 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -648,7 +648,7 @@ static void opal_init_heartbeat(void)
 
 static int __init opal_init(void)
 {
-   struct device_node *np, *consoles;
+   struct device_node *np, *consoles, *leds;
int rc;
 
opal_node = of_find_node_by_path("/ibm,opal");
@@ -689,6 +689,13 @@ static int __init opal_init(void)
/* Setup a heatbeat thread if requested by OPAL */
opal_init_heartbeat();
 
+   /* Create leds platform devices */
+   leds = of_find_node_by_path("/ibm,opal/leds");
+   if (leds) {
+   of_platform_device_create(leds, "opal_leds", NULL);
+   of_node_put(leds);
+   }
+
/* Create "opal" kobject under /sys/firmware */
rc = opal_sysfs_init();
if (rc == 0) {
@@ -841,3 +848,6 @@ EXPORT_SYMBOL_GPL(opal_rtc_write);
 EXPORT_SYMBOL_GPL(opal_tpo_read);
 EXPORT_SYMBOL_GPL(opal_tpo_write);
 EXPORT_SYMBOL_GPL(opal_i2c_request);
+/* Export these symbols for PowerNV LED class driver */
+EXPORT_SYMBOL_GPL(opal_leds_get_ind);
+EXPORT_SYMBOL_GPL(opal_leds_set_ind);
-- 
2.1.0

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

Re: [v8,3/3] leds/powernv: Add driver for PowerNV platform

2015-08-19 Thread Vasant Hegde
On 08/18/2015 03:51 PM, Michael Ellerman wrote:
> On Sat, 2015-25-07 at 05:21:10 UTC, Vasant Hegde wrote:
>> This patch implements LED driver for PowerNV platform using the existing
>> generic LED class framework.
>>
>> PowerNV platform has below type of LEDs:
>>   - System attention
>>   Indicates there is a problem with the system that needs attention.
>>   - Identify
>>   Helps the user locate/identify a particular FRU or resource in the
>>   system.
>>   - Fault
>>   Indicates there is a problem with the FRU or resource at the
>>   location with which the indicator is associated.
> 
> Hi Vasant,
> 
> I'm waiting for a respin of this based on the discussion between you and
> Jackek.
> 
> If I don't see it soon it will miss v4.3.

Michael,

I'll post v9 in a day or two.

-Vasant

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

Re: [PATCH v8 3/3] leds/powernv: Add driver for PowerNV platform

2015-07-28 Thread Vasant Hegde
On 07/27/2015 03:20 PM, Jacek Anaszewski wrote:
> Hi Vasant,
> 
> On 27.07.2015 05:41, Vasant Hegde wrote:
>> On 07/27/2015 03:11 AM, Jacek Anaszewski wrote:
>>> Hi Vasant,
>>>
>>
>> Hi Jacek,
>>
>>> Two trivial details left. Please find them below.
>>
>> Thanks for the review/Ack. I'll fix below issues and resend patchset.
>>
>> I will ask Benh/Michael to take this patchset. But this patchset is depending
>> on your core changes. Can you confirm that you are pushing that patchset in 
>> next
>> merge window?

Jacek,

> 
> Without my core changes your driver won't work with led triggers, but
> AFAIR this use case is not relevant for your LEDs? Eventually, we could
> produce a patch set adding support for LED triggers if it will be clear
> that LED core changes will not be merged in the upcoming merge window.

IIUC current LED code doesn't allow me to sleep (without driver specific
workqueue). And powernv_led_set() call will sleep. Hence I think it won't work.

I did a quick test without your patch. It doesn't seems to be working.

Alternatively we can revert the changes (add driver specific workqueue now) and
later when your changes goes to upstream, I can fix my code.

-Vasant

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

Re: [PATCH v8 3/3] leds/powernv: Add driver for PowerNV platform

2015-07-26 Thread Vasant Hegde
On 07/27/2015 03:11 AM, Jacek Anaszewski wrote:
> Hi Vasant,
> 

Hi Jacek,

> Two trivial details left. Please find them below.

Thanks for the review/Ack. I'll fix below issues and resend patchset.

I will ask Benh/Michael to take this patchset. But this patchset is depending
on your core changes. Can you confirm that you are pushing that patchset in next
merge window?

-Vasant


> 
> Since for two next weeks I will be unable even to compile-test
> this patch set I propose to merge it via powerpc tree.
> 
> Having both mentioned issues addressed, for this patch:
> 
> Acked-by: Jacek Anaszewski 
> 
> On 25.07.2015 07:21, Vasant Hegde wrote:
>> This patch implements LED driver for PowerNV platform using the existing
>> generic LED class framework.
>>
>> PowerNV platform has below type of LEDs:
>>- System attention
>>Indicates there is a problem with the system that needs attention.
>>- Identify
>>Helps the user locate/identify a particular FRU or resource in the
>>system.
>>- Fault
>>Indicates there is a problem with the FRU or resource at the
>>location with which the indicator is associated.
>>
>> We register classdev structures for all individual LEDs detected on the
>> system through LED specific device tree nodes. Device tree nodes specify
>> what all kind of LEDs present on the same location code. It registers
>> LED classdev structure for each of them.
>>
>> All the system LEDs can be found in the same regular path /sys/class/leds/.
>> We don't use LED colors. We use LED node and led-types property to form
>> LED classdev. Our LEDs have names in this format.
>>
>>  :
>>
>> Any positive brightness value would turn on the LED and a zero value would
>> turn off the LED. The driver will return LED_FULL (255) for any turned on
>> LED and LED_OFF (0) for any turned off LED.
>>
>> As per the LED class framework, the 'brightness_set' function should not
>> sleep. Hence these functions have been implemented through global work
>> queue tasks which might sleep on OPAL async call completion.
> 
> This is no longer true.
> 
>> The platform level implementation of LED get and set state has been
>> achieved through OPAL calls. These calls are made available for the
>> driver by exporting from architecture specific codes.
>>
>> Signed-off-by: Vasant Hegde 
>> Signed-off-by: Anshuman Khandual 
>> Acked-by: Stewart Smith 
>> Tested-by: Stewart Smith 
>> ---
>>   .../devicetree/bindings/leds/leds-powernv.txt  |  26 ++
>>   drivers/leds/Kconfig   |  11 +
>>   drivers/leds/Makefile  |   1 +
>>   drivers/leds/leds-powernv.c| 350 
>> +
>>   4 files changed, 388 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/leds/leds-powernv.txt
>>   create mode 100644 drivers/leds/leds-powernv.c
>>
>> diff --git a/Documentation/devicetree/bindings/leds/leds-powernv.txt
>> b/Documentation/devicetree/bindings/leds/leds-powernv.txt
>> new file mode 100644
>> index 000..6665569
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/leds/leds-powernv.txt
>> @@ -0,0 +1,26 @@
>> +Device Tree binding for LEDs on IBM Power Systems
>> +-
>> +
>> +Required properties:
>> +- compatible : Should be "ibm,opal-v3-led".
>> +- led-mode   : Should be "lightpath" or "guidinglight".
>> +
>> +Each location code of FRU/Enclosure must be expressed in the
>> +form of a sub-node.
>> +
>> +Required properties for the sub nodes:
>> +- led-types : Supported LED types (attention/identify/fault) provided
>> +  in the form of string array.
>> +
>> +Example:
>> +
>> +leds {
>> +compatible = "ibm,opal-v3-led";
>> +led-mode = "lightpath";
>> +
>> +U78C9.001.RST0027-P1-C1 {
>> +led-types = "identify", "fault";
>> +};
>> +...
>> +...
>> +};
>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>> index 9ad35f7..f218cc3a 100644
>> --- a/drivers/leds/Kconfig
>> +++ b/drivers/leds/Kconfig
>> @@ -560,6 +560,17 @@ config LEDS_BLINKM
>> This option enables support for the BlinkM RGB LED connected
>> through I2C. Say Y to enable support for the BlinkM LED.
>>
>> +config LEDS_POWERNV
>> +tristate

[PATCH v8 3/3] leds/powernv: Add driver for PowerNV platform

2015-07-24 Thread Vasant Hegde
This patch implements LED driver for PowerNV platform using the existing
generic LED class framework.

PowerNV platform has below type of LEDs:
  - System attention
  Indicates there is a problem with the system that needs attention.
  - Identify
  Helps the user locate/identify a particular FRU or resource in the
  system.
  - Fault
  Indicates there is a problem with the FRU or resource at the
  location with which the indicator is associated.

We register classdev structures for all individual LEDs detected on the
system through LED specific device tree nodes. Device tree nodes specify
what all kind of LEDs present on the same location code. It registers
LED classdev structure for each of them.

All the system LEDs can be found in the same regular path /sys/class/leds/.
We don't use LED colors. We use LED node and led-types property to form
LED classdev. Our LEDs have names in this format.

:

Any positive brightness value would turn on the LED and a zero value would
turn off the LED. The driver will return LED_FULL (255) for any turned on
LED and LED_OFF (0) for any turned off LED.

As per the LED class framework, the 'brightness_set' function should not
sleep. Hence these functions have been implemented through global work
queue tasks which might sleep on OPAL async call completion.

The platform level implementation of LED get and set state has been
achieved through OPAL calls. These calls are made available for the
driver by exporting from architecture specific codes.

Signed-off-by: Vasant Hegde 
Signed-off-by: Anshuman Khandual 
Acked-by: Stewart Smith 
Tested-by: Stewart Smith 
---
 .../devicetree/bindings/leds/leds-powernv.txt  |  26 ++
 drivers/leds/Kconfig   |  11 +
 drivers/leds/Makefile  |   1 +
 drivers/leds/leds-powernv.c| 350 +
 4 files changed, 388 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-powernv.txt
 create mode 100644 drivers/leds/leds-powernv.c

diff --git a/Documentation/devicetree/bindings/leds/leds-powernv.txt 
b/Documentation/devicetree/bindings/leds/leds-powernv.txt
new file mode 100644
index 000..6665569
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/leds-powernv.txt
@@ -0,0 +1,26 @@
+Device Tree binding for LEDs on IBM Power Systems
+-
+
+Required properties:
+- compatible : Should be "ibm,opal-v3-led".
+- led-mode   : Should be "lightpath" or "guidinglight".
+
+Each location code of FRU/Enclosure must be expressed in the
+form of a sub-node.
+
+Required properties for the sub nodes:
+- led-types : Supported LED types (attention/identify/fault) provided
+  in the form of string array.
+
+Example:
+
+leds {
+   compatible = "ibm,opal-v3-led";
+   led-mode = "lightpath";
+
+   U78C9.001.RST0027-P1-C1 {
+   led-types = "identify", "fault";
+   };
+   ...
+   ...
+};
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 9ad35f7..f218cc3a 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -560,6 +560,17 @@ config LEDS_BLINKM
  This option enables support for the BlinkM RGB LED connected
  through I2C. Say Y to enable support for the BlinkM LED.
 
+config LEDS_POWERNV
+   tristate "LED support for PowerNV Platform"
+   depends on LEDS_CLASS
+   depends on PPC_POWERNV
+   depends on OF
+   help
+ This option enables support for the system LEDs present on
+ PowerNV platforms. Say 'y' to enable this support in kernel.
+ To compile this driver as a module, choose 'm' here: the module
+ will be called leds-powernv.
+
 config LEDS_SYSCON
bool "LED support for LEDs on system controllers"
depends on LEDS_CLASS=y
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 8d6a24a..6a943d1 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_LEDS_VERSATILE)  += leds-versatile.o
 obj-$(CONFIG_LEDS_MENF21BMC)   += leds-menf21bmc.o
 obj-$(CONFIG_LEDS_PM8941_WLED) += leds-pm8941-wled.o
 obj-$(CONFIG_LEDS_KTD2692) += leds-ktd2692.o
+obj-$(CONFIG_LEDS_POWERNV) += leds-powernv.o
 
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)  += leds-dac124s085.o
diff --git a/drivers/leds/leds-powernv.c b/drivers/leds/leds-powernv.c
new file mode 100644
index 000..9799de5
--- /dev/null
+++ b/drivers/leds/leds-powernv.c
@@ -0,0 +1,350 @@
+/*
+ * PowerNV LED Driver
+ *
+ * Copyright IBM Corp. 2015
+ *
+ * Author: Vasant Hegde 
+ * Author: Anshuman Khandual 
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published 

[PATCH v8 2/3] powerpc/powernv: Create LED platform device

2015-07-24 Thread Vasant Hegde
This patch adds platform devices for leds. Also export LED related
OPAL API's so that led driver can use these APIs.

Signed-off-by: Vasant Hegde 
Acked-by: Benjamin Herrenschmidt 
---
 arch/powerpc/platforms/powernv/opal.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index f084afa..6839358 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -648,7 +648,7 @@ static void opal_init_heartbeat(void)
 
 static int __init opal_init(void)
 {
-   struct device_node *np, *consoles;
+   struct device_node *np, *consoles, *leds;
int rc;
 
opal_node = of_find_node_by_path("/ibm,opal");
@@ -689,6 +689,13 @@ static int __init opal_init(void)
/* Setup a heatbeat thread if requested by OPAL */
opal_init_heartbeat();
 
+   /* Create leds platform devices */
+   leds = of_find_node_by_path("/ibm,opal/leds");
+   if (leds) {
+   of_platform_device_create(leds, "opal_leds", NULL);
+   of_node_put(leds);
+   }
+
/* Create "opal" kobject under /sys/firmware */
rc = opal_sysfs_init();
if (rc == 0) {
@@ -841,3 +848,6 @@ EXPORT_SYMBOL_GPL(opal_rtc_write);
 EXPORT_SYMBOL_GPL(opal_tpo_read);
 EXPORT_SYMBOL_GPL(opal_tpo_write);
 EXPORT_SYMBOL_GPL(opal_i2c_request);
+/* Export these symbols for PowerNV LED class driver */
+EXPORT_SYMBOL_GPL(opal_leds_get_ind);
+EXPORT_SYMBOL_GPL(opal_leds_set_ind);
-- 
2.1.0

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

[PATCH v8 0/3] LED driver for PowerNV platform

2015-07-24 Thread Vasant Hegde
 OPAL platform sepcific part to separate patch
Moved repteated code to common function
Added device tree documentation for LEDs

Changes in v2:
  - Rebased patches on top of mpe's next branch
 https://git.kernel.org/cgit/linux/kernel/git/mpe/linux.git/log/?h=next
  - Added System Attention Indicator support
  - Removed redundant code in leds-powernv.c file


Anshuman Khandual (1):
  powerpc/powernv: Add OPAL interfaces for accessing and modifying
system LED states

Vasant Hegde (2):
  powerpc/powernv: Create LED platform device
  leds/powernv: Add driver for PowerNV platform

 .../devicetree/bindings/leds/leds-powernv.txt  |  26 ++
 arch/powerpc/include/asm/opal-api.h|  25 +-
 arch/powerpc/include/asm/opal.h|   4 +
 arch/powerpc/platforms/powernv/opal-wrappers.S |   2 +
 arch/powerpc/platforms/powernv/opal.c  |  12 +-
 drivers/leds/Kconfig   |  11 +
 drivers/leds/Makefile  |   1 +
 drivers/leds/leds-powernv.c| 350 +
 8 files changed, 429 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-powernv.txt
 create mode 100644 drivers/leds/leds-powernv.c

-- 
2.1.0

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

[PATCH v8 1/3] powerpc/powernv: Add OPAL interfaces for accessing and modifying system LED states

2015-07-24 Thread Vasant Hegde
From: Anshuman Khandual 

This patch registers the following two new OPAL interfaces calls
for the platform LED subsystem. With the help of these new OPAL calls,
the kernel will be able to get or set the state of various individual
LEDs on the system at any given location code which is passed through
the LED specific device tree nodes.

(1) OPAL_LEDS_GET_INDICATOR opal_leds_get_ind
(2) OPAL_LEDS_SET_INDICATOR opal_leds_set_ind

Signed-off-by: Anshuman Khandual 
Signed-off-by: Vasant Hegde 
Acked-by: Stewart Smith 
Tested-by: Stewart Smith 
Acked-by: Benjamin Herrenschmidt 
---
 arch/powerpc/include/asm/opal-api.h| 25 -
 arch/powerpc/include/asm/opal.h|  4 
 arch/powerpc/platforms/powernv/opal-wrappers.S |  2 ++
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/opal-api.h 
b/arch/powerpc/include/asm/opal-api.h
index e9e4c52..8f8c45f 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -154,7 +154,9 @@
 #define OPAL_FLASH_WRITE   111
 #define OPAL_FLASH_ERASE   112
 #define OPAL_PRD_MSG   113
-#define OPAL_LAST  113
+#define OPAL_LEDS_GET_INDICATOR114
+#define OPAL_LEDS_SET_INDICATOR115
+#define OPAL_LAST  115
 
 /* Device tree flags */
 
@@ -756,6 +758,27 @@ struct opal_i2c_request {
__be64 buffer_ra;   /* Buffer real address */
 };
 
+/* LED Mode */
+#define POWERNV_LED_MODE_LIGHT_PATH"lightpath"
+#define POWERNV_LED_MODE_GUIDING_LIGHT "guidinglight"
+
+/* LED type */
+#define POWERNV_LED_TYPE_IDENTIFY  "identify"
+#define POWERNV_LED_TYPE_FAULT "fault"
+#define POWERNV_LED_TYPE_ATTENTION "attention"
+
+enum OpalSlotLedType {
+   OPAL_SLOT_LED_TYPE_ID = 0,  /* IDENTIFY LED */
+   OPAL_SLOT_LED_TYPE_FAULT = 1,   /* FAULT LED */
+   OPAL_SLOT_LED_TYPE_ATTN = 2,/* System Attention LED */
+   OPAL_SLOT_LED_TYPE_MAX = 3
+};
+
+enum OpalSlotLedState {
+   OPAL_SLOT_LED_STATE_OFF = 0,/* LED is OFF */
+   OPAL_SLOT_LED_STATE_ON = 1  /* LED is ON */
+};
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __OPAL_API_H */
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 958e941..3233e6d 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -195,6 +195,10 @@ int64_t opal_ipmi_recv(uint64_t interface, struct 
opal_ipmi_msg *msg,
 int64_t opal_i2c_request(uint64_t async_token, uint32_t bus_id,
 struct opal_i2c_request *oreq);
 int64_t opal_prd_msg(struct opal_prd_msg *msg);
+int64_t opal_leds_get_ind(char *loc_code, __be64 *led_mask,
+ __be64 *led_value, __be64 *max_led_type);
+int64_t opal_leds_set_ind(uint64_t token, char *loc_code, const u64 led_mask,
+ const u64 led_value, __be64 *max_led_type);
 
 int64_t opal_flash_read(uint64_t id, uint64_t offset, uint64_t buf,
uint64_t size, uint64_t token);
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S 
b/arch/powerpc/platforms/powernv/opal-wrappers.S
index d6a7b82..34c2734 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -297,3 +297,5 @@ 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_leds_get_ind,   OPAL_LEDS_GET_INDICATOR);
+OPAL_CALL(opal_leds_set_ind,   OPAL_LEDS_SET_INDICATOR);
-- 
2.1.0

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

Re: [PATCH v7 3/3] leds/powernv: Add driver for PowerNV platform

2015-07-23 Thread Vasant Hegde
On 07/23/2015 01:25 PM, Jacek Anaszewski wrote:
> Hi Vasant,
> 

Jacek,

.../...

>> +/* PowerNV LED data */
>> +struct powernv_led_data {
>> +struct led_classdevcdev;
>> +char*loc_code;/* LED location code */
>> +intled_type;/* OPAL_SLOT_LED_TYPE_* */
>> +enum led_brightnessvalue;/* Brightness value */
> 
> You don't need 'value' as brightness value is already stored in
> cdev.brightness.
> 

Agree. I'll remove.

>> +/*
>> + * LED classdev 'brightness_get' function. This schedules work
>> + * to update LED state.
>> + */
>> +static void powernv_brightness_set(struct led_classdev *led_cdev,
>> +   enum led_brightness value)
>> +{
>> +struct powernv_led_data *powernv_led =
>> +container_of(led_cdev, struct powernv_led_data, cdev);
>> +
>> +/* Do not modify LED in unload path */
>> +if (led_disabled)
>> +return;
>> +
>> +/* Prepare the request */
>> +powernv_led->value = value;
>> +
>> + return powernv_led_set(powernv_led);
> 
> Isn't mutex_lock/unlock missing here?

Yes. I realized this after sending out the patch. I will fix this.
.../...

>> +
>> +max_led_type = devm_kzalloc(dev, sizeof(*max_led_type), GFP_KERNEL);
>> +if (!max_led_type)
>> +return -ENOMEM;
>> +
>> +mutex_init(lock);
>> +*max_led_type = cpu_to_be64(OPAL_SLOT_LED_TYPE_MAX);
>> +
>> +platform_set_drvdata(pdev, lock);
> 
> Setting only lock as drvdata looks odd to me and I haven't noticed
> anyone doing that.
> I'd prefer to put lock, led_disabled and max_led_type in a common
> struct and set it as drvdata. I know that I accepted this design, but
> I didn't take into account these details.

Yeah. Even I looked into existing code and I don't see anyone using like this.
Since it's void * and we just need lock, I added like this.

If I break this into two structure, then I've to use platform_get_drvdata() call
in multiple functions like powernv_brightness_set() to get max_let_type etc. Is
that fine?

-Vasant

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

[PATCH v7 1/3] powerpc/powernv: Add OPAL interfaces for accessing and modifying system LED states

2015-07-22 Thread Vasant Hegde
From: Anshuman Khandual 

This patch registers the following two new OPAL interfaces calls
for the platform LED subsystem. With the help of these new OPAL calls,
the kernel will be able to get or set the state of various individual
LEDs on the system at any given location code which is passed through
the LED specific device tree nodes.

(1) OPAL_LEDS_GET_INDICATOR opal_leds_get_ind
(2) OPAL_LEDS_SET_INDICATOR opal_leds_set_ind

Signed-off-by: Anshuman Khandual 
Signed-off-by: Vasant Hegde 
Acked-by: Stewart Smith 
Tested-by: Stewart Smith 
Acked-by: Benjamin Herrenschmidt 
---
 arch/powerpc/include/asm/opal-api.h| 25 -
 arch/powerpc/include/asm/opal.h|  4 
 arch/powerpc/platforms/powernv/opal-wrappers.S |  2 ++
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/opal-api.h 
b/arch/powerpc/include/asm/opal-api.h
index e9e4c52..8f8c45f 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -154,7 +154,9 @@
 #define OPAL_FLASH_WRITE   111
 #define OPAL_FLASH_ERASE   112
 #define OPAL_PRD_MSG   113
-#define OPAL_LAST  113
+#define OPAL_LEDS_GET_INDICATOR114
+#define OPAL_LEDS_SET_INDICATOR115
+#define OPAL_LAST  115
 
 /* Device tree flags */
 
@@ -756,6 +758,27 @@ struct opal_i2c_request {
__be64 buffer_ra;   /* Buffer real address */
 };
 
+/* LED Mode */
+#define POWERNV_LED_MODE_LIGHT_PATH"lightpath"
+#define POWERNV_LED_MODE_GUIDING_LIGHT "guidinglight"
+
+/* LED type */
+#define POWERNV_LED_TYPE_IDENTIFY  "identify"
+#define POWERNV_LED_TYPE_FAULT "fault"
+#define POWERNV_LED_TYPE_ATTENTION "attention"
+
+enum OpalSlotLedType {
+   OPAL_SLOT_LED_TYPE_ID = 0,  /* IDENTIFY LED */
+   OPAL_SLOT_LED_TYPE_FAULT = 1,   /* FAULT LED */
+   OPAL_SLOT_LED_TYPE_ATTN = 2,/* System Attention LED */
+   OPAL_SLOT_LED_TYPE_MAX = 3
+};
+
+enum OpalSlotLedState {
+   OPAL_SLOT_LED_STATE_OFF = 0,/* LED is OFF */
+   OPAL_SLOT_LED_STATE_ON = 1  /* LED is ON */
+};
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __OPAL_API_H */
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 958e941..3233e6d 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -195,6 +195,10 @@ int64_t opal_ipmi_recv(uint64_t interface, struct 
opal_ipmi_msg *msg,
 int64_t opal_i2c_request(uint64_t async_token, uint32_t bus_id,
 struct opal_i2c_request *oreq);
 int64_t opal_prd_msg(struct opal_prd_msg *msg);
+int64_t opal_leds_get_ind(char *loc_code, __be64 *led_mask,
+ __be64 *led_value, __be64 *max_led_type);
+int64_t opal_leds_set_ind(uint64_t token, char *loc_code, const u64 led_mask,
+ const u64 led_value, __be64 *max_led_type);
 
 int64_t opal_flash_read(uint64_t id, uint64_t offset, uint64_t buf,
uint64_t size, uint64_t token);
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S 
b/arch/powerpc/platforms/powernv/opal-wrappers.S
index d6a7b82..34c2734 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -297,3 +297,5 @@ 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_leds_get_ind,   OPAL_LEDS_GET_INDICATOR);
+OPAL_CALL(opal_leds_set_ind,   OPAL_LEDS_SET_INDICATOR);
-- 
2.1.0

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

[PATCH v7 2/3] powerpc/powernv: Create LED platform device

2015-07-22 Thread Vasant Hegde
This patch adds platform devices for leds. Also export LED related
OPAL API's so that led driver can use these APIs.

Signed-off-by: Vasant Hegde 
Acked-by: Benjamin Herrenschmidt 
---
 arch/powerpc/platforms/powernv/opal.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index f084afa..6839358 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -648,7 +648,7 @@ static void opal_init_heartbeat(void)
 
 static int __init opal_init(void)
 {
-   struct device_node *np, *consoles;
+   struct device_node *np, *consoles, *leds;
int rc;
 
opal_node = of_find_node_by_path("/ibm,opal");
@@ -689,6 +689,13 @@ static int __init opal_init(void)
/* Setup a heatbeat thread if requested by OPAL */
opal_init_heartbeat();
 
+   /* Create leds platform devices */
+   leds = of_find_node_by_path("/ibm,opal/leds");
+   if (leds) {
+   of_platform_device_create(leds, "opal_leds", NULL);
+   of_node_put(leds);
+   }
+
/* Create "opal" kobject under /sys/firmware */
rc = opal_sysfs_init();
if (rc == 0) {
@@ -841,3 +848,6 @@ EXPORT_SYMBOL_GPL(opal_rtc_write);
 EXPORT_SYMBOL_GPL(opal_tpo_read);
 EXPORT_SYMBOL_GPL(opal_tpo_write);
 EXPORT_SYMBOL_GPL(opal_i2c_request);
+/* Export these symbols for PowerNV LED class driver */
+EXPORT_SYMBOL_GPL(opal_leds_get_ind);
+EXPORT_SYMBOL_GPL(opal_leds_set_ind);
-- 
2.1.0

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

[PATCH v7 3/3] leds/powernv: Add driver for PowerNV platform

2015-07-22 Thread Vasant Hegde
This patch implements LED driver for PowerNV platform using the existing
generic LED class framework.

PowerNV platform has below type of LEDs:
  - System attention
  Indicates there is a problem with the system that needs attention.
  - Identify
  Helps the user locate/identify a particular FRU or resource in the
  system.
  - Fault
  Indicates there is a problem with the FRU or resource at the
  location with which the indicator is associated.

We register classdev structures for all individual LEDs detected on the
system through LED specific device tree nodes. Device tree nodes specify
what all kind of LEDs present on the same location code. It registers
LED classdev structure for each of them.

All the system LEDs can be found in the same regular path /sys/class/leds/.
We don't use LED colors. We use LED node and led-types property to form
LED classdev. Our LEDs have names in this format.

:

Any positive brightness value would turn on the LED and a zero value would
turn off the LED. The driver will return LED_FULL (255) for any turned on
LED and LED_OFF (0) for any turned off LED.

As per the LED class framework, the 'brightness_set' function should not
sleep. Hence these functions have been implemented through global work
queue tasks which might sleep on OPAL async call completion.

The platform level implementation of LED get and set state has been
achieved through OPAL calls. These calls are made available for the
driver by exporting from architecture specific codes.

Signed-off-by: Vasant Hegde 
Signed-off-by: Anshuman Khandual 
Acked-by: Stewart Smith 
Tested-by: Stewart Smith 
---
 .../devicetree/bindings/leds/leds-powernv.txt  |  26 ++
 drivers/leds/Kconfig   |  11 +
 drivers/leds/Makefile  |   1 +
 drivers/leds/leds-powernv.c| 342 +
 4 files changed, 380 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-powernv.txt
 create mode 100644 drivers/leds/leds-powernv.c

diff --git a/Documentation/devicetree/bindings/leds/leds-powernv.txt 
b/Documentation/devicetree/bindings/leds/leds-powernv.txt
new file mode 100644
index 000..6665569
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/leds-powernv.txt
@@ -0,0 +1,26 @@
+Device Tree binding for LEDs on IBM Power Systems
+-
+
+Required properties:
+- compatible : Should be "ibm,opal-v3-led".
+- led-mode   : Should be "lightpath" or "guidinglight".
+
+Each location code of FRU/Enclosure must be expressed in the
+form of a sub-node.
+
+Required properties for the sub nodes:
+- led-types : Supported LED types (attention/identify/fault) provided
+  in the form of string array.
+
+Example:
+
+leds {
+   compatible = "ibm,opal-v3-led";
+   led-mode = "lightpath";
+
+   U78C9.001.RST0027-P1-C1 {
+   led-types = "identify", "fault";
+   };
+   ...
+   ...
+};
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 9ad35f7..f218cc3a 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -560,6 +560,17 @@ config LEDS_BLINKM
  This option enables support for the BlinkM RGB LED connected
  through I2C. Say Y to enable support for the BlinkM LED.
 
+config LEDS_POWERNV
+   tristate "LED support for PowerNV Platform"
+   depends on LEDS_CLASS
+   depends on PPC_POWERNV
+   depends on OF
+   help
+ This option enables support for the system LEDs present on
+ PowerNV platforms. Say 'y' to enable this support in kernel.
+ To compile this driver as a module, choose 'm' here: the module
+ will be called leds-powernv.
+
 config LEDS_SYSCON
bool "LED support for LEDs on system controllers"
depends on LEDS_CLASS=y
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 8d6a24a..6a943d1 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_LEDS_VERSATILE)  += leds-versatile.o
 obj-$(CONFIG_LEDS_MENF21BMC)   += leds-menf21bmc.o
 obj-$(CONFIG_LEDS_PM8941_WLED) += leds-pm8941-wled.o
 obj-$(CONFIG_LEDS_KTD2692) += leds-ktd2692.o
+obj-$(CONFIG_LEDS_POWERNV) += leds-powernv.o
 
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)  += leds-dac124s085.o
diff --git a/drivers/leds/leds-powernv.c b/drivers/leds/leds-powernv.c
new file mode 100644
index 000..9e70291
--- /dev/null
+++ b/drivers/leds/leds-powernv.c
@@ -0,0 +1,342 @@
+/*
+ * PowerNV LED Driver
+ *
+ * Copyright IBM Corp. 2015
+ *
+ * Author: Vasant Hegde 
+ * Author: Anshuman Khandual 
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published 

[PATCH v7 0/3] LED driver for PowerNV platform

2015-07-22 Thread Vasant Hegde
 LEDs

Changes in v2:
  - Rebased patches on top of mpe's next branch
 https://git.kernel.org/cgit/linux/kernel/git/mpe/linux.git/log/?h=next
  - Added System Attention Indicator support
  - Removed redundant code in leds-powernv.c file


Anshuman Khandual (1):
  powerpc/powernv: Add OPAL interfaces for accessing and modifying
system LED states

Vasant Hegde (2):
  powerpc/powernv: Create LED platform device
  leds/powernv: Add driver for PowerNV platform

 .../devicetree/bindings/leds/leds-powernv.txt  |  26 ++
 arch/powerpc/include/asm/opal-api.h|  25 +-
 arch/powerpc/include/asm/opal.h|   4 +
 arch/powerpc/platforms/powernv/opal-wrappers.S |   2 +
 arch/powerpc/platforms/powernv/opal.c  |  12 +-
 drivers/leds/Kconfig   |  11 +
 drivers/leds/Makefile  |   1 +
 drivers/leds/leds-powernv.c| 342 +
 8 files changed, 421 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-powernv.txt
 create mode 100644 drivers/leds/leds-powernv.c

-- 
2.1.0

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

Re: [PATCH v6 3/3] leds/powernv: Add driver for PowerNV platform

2015-07-20 Thread Vasant Hegde
On 07/21/2015 11:24 AM, Vasant Hegde wrote:
> On 07/20/2015 03:10 AM, Jacek Anaszewski wrote:
>> Hi Vasant,
>>
> 
> Jacek,
> 
>> I've revised your patch and found few more issues.
>> Please refer to my comments below.
> 
> Thanks.
> 
> .../...
> 
>>>>
>>>> Please don't exceed 75 character line length limit.
>>>
>>> Ok. I will fix it.. But I thought 80 character is the limit.
>>
>> checkpatch.pl reports this.
> 
> Ah! I was running checkpatch.pl against source. Let me fix this.
> .../...
> 
>>>>> +/*
>>>>> + * LED set routines have been implemented as work queue tasks scheduled
>>>>> + * on the global work queue. Individual task calls OPAL interface to set
>>>>> + * the LED state which might sleep for some time.
>>>>> + */
>>>>> +struct powernv_led_data {
>>>>> +struct led_classdevcdev;
>>>>> +char*loc_code;/* LED location code */
>>>>> +intled_type;/* OPAL_SLOT_LED_TYPE_* */
>>>>> +enum led_brightnessvalue;/* Brightness value */
>>>>> +struct mutexlock;
>>
>> You're unnecessarily adding mutex for each LED class device.
>> The shared resource to protect is here powernv led interface,
>> so one mutex will suffice.
> 
> 
> Ok. Let me move that to common structure.
> 
>>
>>
>>>>> +struct work_structwork_led;/* LED update workqueue */
>>>>> +};
>>>>> +
>>>>> +struct powernv_leds_priv {
>>>>> +int num_leds;
>>>>> +struct powernv_led_data powernv_leds[];
>>>>> +};
>>
>> powernv_led_data doesn't have to be retained in the array. You access
>> the array elements only upon creation of LED class devices. When using
>> managed resource allocation you don't need to bother with freeing
>> resources, so you don't need to keep reference to the data.
>>
>> I propose to drop struct powernv_leds_priv and instead introduce
>> a structure that would aggregate common driver data like mutex,
>> led_disable and max_led_type.
> 
> I still think we need two structures.. One for common driver data like mutex,
> led_disable etc and other one for led data itself .. like
>   struct powernv_led_data {
>   struct led_classdev cdev;
>   char*loc_code; <-- pointer to DT node
>   int led_type;   /* OPAL_SLOT_LED_TYPE_* 
> */
>   enum led_brightness value;  /* Brightness value */
>   };
> 
>   struct powernv_led_common {
>   bool led_disable;
>   int max_led_type;
>   struct mutexlock;
>   };

Jacek,

Alternatively I can club both into single structure like below

struct powernv_led_data {
struct led_classdev cdev;
char*loc_code; <-- pointer to DT node
int led_type;   /* OPAL_SLOT_LED_TYPE_* 
*/
enum led_brightness value;  /* Brightness value */

int *max_led_type;
struct mutex*lock;
};

static  boolled_disable;


In this case I've to keep led_disable outside the structure as I need to access
this variable in powernv_led_remove().

One remaining issue with these approach (where we don't have array of
powernv_led ) is,
powernv_let_set() function can sleep. Current code (v6) calls flush_work before
unloading
module. That way we are sure work is complete before unloading module.
With new approach, I'm not sure how I can make sure work is completed before
loading module. Does new workqueue approach has sleep functionality? Is there
way to make sure work is completed before
unloading module?

-Vasant

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

Re: [PATCH v6 3/3] leds/powernv: Add driver for PowerNV platform

2015-07-20 Thread Vasant Hegde
On 07/20/2015 03:10 AM, Jacek Anaszewski wrote:
> Hi Vasant,
> 

Jacek,

> I've revised your patch and found few more issues.
> Please refer to my comments below.

Thanks.

.../...

>>>
>>> Please don't exceed 75 character line length limit.
>>
>> Ok. I will fix it.. But I thought 80 character is the limit.
> 
> checkpatch.pl reports this.

Ah! I was running checkpatch.pl against source. Let me fix this.
.../...

 +/*
 + * LED set routines have been implemented as work queue tasks scheduled
 + * on the global work queue. Individual task calls OPAL interface to set
 + * the LED state which might sleep for some time.
 + */
 +struct powernv_led_data {
 +struct led_classdevcdev;
 +char*loc_code;/* LED location code */
 +intled_type;/* OPAL_SLOT_LED_TYPE_* */
 +enum led_brightnessvalue;/* Brightness value */
 +struct mutexlock;
> 
> You're unnecessarily adding mutex for each LED class device.
> The shared resource to protect is here powernv led interface,
> so one mutex will suffice.


Ok. Let me move that to common structure.

> 
> 
 +struct work_structwork_led;/* LED update workqueue */
 +};
 +
 +struct powernv_leds_priv {
 +int num_leds;
 +struct powernv_led_data powernv_leds[];
 +};
> 
> powernv_led_data doesn't have to be retained in the array. You access
> the array elements only upon creation of LED class devices. When using
> managed resource allocation you don't need to bother with freeing
> resources, so you don't need to keep reference to the data.
> 
> I propose to drop struct powernv_leds_priv and instead introduce
> a structure that would aggregate common driver data like mutex,
> led_disable and max_led_type.

I still think we need two structures.. One for common driver data like mutex,
led_disable etc and other one for led data itself .. like
struct powernv_led_data {
struct led_classdev cdev;
char*loc_code; <-- pointer to DT node
int led_type;   /* OPAL_SLOT_LED_TYPE_* 
*/
enum led_brightness value;  /* Brightness value */
};

struct powernv_led_common {
bool led_disable;
int max_led_type;
struct mutexlock;
};

> 
 +
 +static __be64 max_led_type = cpu_to_be64(OPAL_SLOT_LED_TYPE_MAX);
>>>
>>> The C standard prohibits initialization of global objects with non-constant
>>> values. Section 6.7.8 of the C99 standard states:
>>>
>>> "All the expressions in an initializer for an object that has static storage
>>> duration shall be constant expressions or string literals."
>>>
>>> Compilation succeeds when using powerpc64-linux-gcc because then
>>> the following version of macro is used:
>>>
>>> #define cpu_to_be64(x) (x)
>>>
>>> and not
>>>
>>> #define cpu_to_be64(x) swab64(x)
>>>
>>> Please move max_led_type also to the struct powernv_leds_priv
>>> and initialize it dynamically.
>>
>> Yeah.. I should have added this to structure itself. Will fix.
>>
>>>
 +
 +
 +static inline int sizeof_powernv_leds_priv(int num_leds)
 +{
 +return sizeof(struct powernv_leds_priv) +
 +(sizeof(struct powernv_led_data) * num_leds);
 +}
 +/* Returns OPAL_SLOT_LED_TYPE_* for given led type string */
 +static int powernv_get_led_type(const char *led_type_desc)
 +{
 +int i;
 +
 +for (i = 0; i < ARRAY_SIZE(led_type_map); i++)
 +if (!strcmp(led_type_map[i].desc, led_type_desc))
 +return led_type_map[i].type;
 +
 +return -1;
 +}
 +
 +/*
 + * This commits the state change of the requested LED through an OPAL 
 call.
 + * This function is called from work queue task context when ever it gets
 + * scheduled. This function can sleep at opal_async_wait_response call.
 + */
 +static void powernv_led_set(struct powernv_led_data *powernv_led)
 +{
 +int rc, token;
 +u64 led_mask, led_value = 0;
 +__be64 max_type;
 +struct opal_msg msg;
 +struct device *dev = powernv_led->cdev.dev;
 +
 +/* Prepare for the OPAL call */
 +max_type = max_led_type;
 +led_mask = OPAL_SLOT_LED_STATE_ON << powernv_led->led_type;
 +if (powernv_led->value)
 +led_value = led_mask;
 +
 +/* OPAL async call */
 +token = opal_async_get_token_interruptible();
 +if (token < 0) {
 +if (token != -ERESTARTSYS)
 +dev_err(dev, "%s: Couldn't get OPAL async token\n",
 +__func__);
 +return;
 +}
 +
 +rc = opal_leds_set_ind(token, powernv_led->loc_code,
 +   led_mask, led_value, &max_type);
 +if (rc != OPAL_ASYNC_COMPL

Re: [PATCH v6 3/3] leds/powernv: Add driver for PowerNV platform

2015-07-20 Thread Vasant Hegde
On 07/20/2015 11:46 AM, Jacek Anaszewski wrote:
> On 19.07.2015 23:40, Jacek Anaszewski wrote:
> [...]
> +/* Platform driver probe */
> +static int powernv_led_probe(struct platform_device *pdev)
> +{
> +int num_leds;
> +struct device_node *led_node;
> +struct powernv_leds_priv *priv;
> +
> +led_node = of_find_node_by_path("/ibm,opal/leds");
> +if (!led_node) {
> +dev_err(&pdev->dev,
> +"%s: LED parent device node not found\n", __func__);
> +return -EINVAL;
> +}
> +
> +num_leds = powernv_leds_count(led_node);
> +if (num_leds <= 0) {
> +dev_err(&pdev->dev,
> +"%s: No location code found under LED node\n",
> +__func__);
> +return -EINVAL;
> +}
>>
>> You won't need to count the number of LEDs to register, just allocate
>> memory for each LED during parsing with managed resource allocation
>> API.

Jacek,

> 
> You can refer to drivers/leds/leds-bcm6328.c in order to gain
> full picture on how this can look like.
> struct powernv_led_data would have to carry the pointer to the
> new common struct.
> 

Sure.. Will though this code and will fix powernv code..

Thanks
-Vasant

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

Re: [PATCH v6 3/3] leds/powernv: Add driver for PowerNV platform

2015-07-17 Thread Vasant Hegde
On 07/17/2015 08:55 PM, Jacek Anaszewski wrote:
> Hi Vasant,

Hi Jacek,


.../...


>> As per the LED class framework, the 'brightness_set' function should not
>> sleep. Hence these functions have been implemented through global work
>> queue tasks which might sleep on OPAL async call completion.
>>
>> The platform level implementation of LED get and set state has been achieved
> 
> Please don't exceed 75 character line length limit.

Ok. I will fix it.. But I thought 80 character is the limit.

> 
>> through OPAL calls. These calls are made available for the driver by
>> exporting from architecture specific codes.
>>

.../...

>> +
>> +#include 
>> +
>> +/*
>> + * By default unload path resets all the LEDs. But on PowerNV platform
>> + * we want to retain LED state across reboot as these are controlled by
>> + * firmware. Also service processor can modify the LEDs independent of
>> + * OS. Hence avoid resetting LEDs in unload path.
>> + */
>> +static bool led_disabled;
> 
> Please move this to the struct powernv_leds_priv.

Hmmm.. Ok. Will update and use platform_get_drvdata to access 
platform_get_drvdata.

> 
>> +
>> +/* Map LED type to description. */
>> +struct led_type_map {
>> +const inttype;
>> +const char*desc;
>> +};
>> +static const struct led_type_map led_type_map[] = {
>> +{OPAL_SLOT_LED_TYPE_ID,POWERNV_LED_TYPE_IDENTIFY},
>> +{OPAL_SLOT_LED_TYPE_FAULT,POWERNV_LED_TYPE_FAULT},
>> +{OPAL_SLOT_LED_TYPE_ATTN,POWERNV_LED_TYPE_ATTENTION},
>> +{-1,NULL},
>> +};
>> +
>> +/*
>> + * LED set routines have been implemented as work queue tasks scheduled
>> + * on the global work queue. Individual task calls OPAL interface to set
>> + * the LED state which might sleep for some time.
>> + */
>> +struct powernv_led_data {
>> +struct led_classdevcdev;
>> +char*loc_code;/* LED location code */
>> +intled_type;/* OPAL_SLOT_LED_TYPE_* */
>> +enum led_brightnessvalue;/* Brightness value */
>> +struct mutexlock;
>> +struct work_structwork_led;/* LED update workqueue */
>> +};
>> +
>> +struct powernv_leds_priv {
>> +int num_leds;
>> +struct powernv_led_data powernv_leds[];
>> +};
>> +
>> +static __be64 max_led_type = cpu_to_be64(OPAL_SLOT_LED_TYPE_MAX);
> 
> The C standard prohibits initialization of global objects with non-constant
> values. Section 6.7.8 of the C99 standard states:
> 
> "All the expressions in an initializer for an object that has static storage
> duration shall be constant expressions or string literals."
> 
> Compilation succeeds when using powerpc64-linux-gcc because then
> the following version of macro is used:
> 
> #define cpu_to_be64(x) (x)
> 
> and not
> 
> #define cpu_to_be64(x) swab64(x)
> 
> Please move max_led_type also to the struct powernv_leds_priv
> and initialize it dynamically.

Yeah.. I should have added this to structure itself. Will fix.

> 
>> +
>> +
>> +static inline int sizeof_powernv_leds_priv(int num_leds)
>> +{
>> +return sizeof(struct powernv_leds_priv) +
>> +(sizeof(struct powernv_led_data) * num_leds);
>> +}
>> +/* Returns OPAL_SLOT_LED_TYPE_* for given led type string */
>> +static int powernv_get_led_type(const char *led_type_desc)
>> +{
>> +int i;
>> +
>> +for (i = 0; i < ARRAY_SIZE(led_type_map); i++)
>> +if (!strcmp(led_type_map[i].desc, led_type_desc))
>> +return led_type_map[i].type;
>> +
>> +return -1;
>> +}
>> +
>> +/*
>> + * This commits the state change of the requested LED through an OPAL call.
>> + * This function is called from work queue task context when ever it gets
>> + * scheduled. This function can sleep at opal_async_wait_response call.
>> + */
>> +static void powernv_led_set(struct powernv_led_data *powernv_led)
>> +{
>> +int rc, token;
>> +u64 led_mask, led_value = 0;
>> +__be64 max_type;
>> +struct opal_msg msg;
>> +struct device *dev = powernv_led->cdev.dev;
>> +
>> +/* Prepare for the OPAL call */
>> +max_type = max_led_type;
>> +led_mask = OPAL_SLOT_LED_STATE_ON << powernv_led->led_type;
>> +if (powernv_led->value)
>> +led_value = led_mask;
>> +
>> +/* OPAL async call */
>> +token = opal_async_get_token_interruptible();
>> +if (token < 0) {
>> +if (token != -ERESTARTSYS)
>> +dev_err(dev, "%s: Couldn't get OPAL async token\n",
>> +__func__);
>> +return;
>> +}
>> +
>> +rc = opal_leds_set_ind(token, powernv_led->loc_code,
>> +   led_mask, led_value, &max_type);
>> +if (rc != OPAL_ASYNC_COMPLETION) {
>> +dev_err(dev, "%s: OPAL set LED call failed for %s [rc=%d]\n",
>> +__func__, powernv_led->loc_code, rc);
>> +goto out_token;
>> +}
>> +
>> +rc = opal_async_wait_response(token, &msg);
>> +if (rc) {
>> +dev_err(dev,
>> +"%s: Failed to wait for the async response

[PATCH v6 2/3] powerpc/powernv: Create LED platform device

2015-07-17 Thread Vasant Hegde
This patch adds platform devices for leds. Also export LED related
OPAL API's so that led driver can use these APIs.

Signed-off-by: Vasant Hegde 
Acked-by: Benjamin Herrenschmidt 
---
 arch/powerpc/platforms/powernv/opal.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index f084afa..6839358 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -648,7 +648,7 @@ static void opal_init_heartbeat(void)
 
 static int __init opal_init(void)
 {
-   struct device_node *np, *consoles;
+   struct device_node *np, *consoles, *leds;
int rc;
 
opal_node = of_find_node_by_path("/ibm,opal");
@@ -689,6 +689,13 @@ static int __init opal_init(void)
/* Setup a heatbeat thread if requested by OPAL */
opal_init_heartbeat();
 
+   /* Create leds platform devices */
+   leds = of_find_node_by_path("/ibm,opal/leds");
+   if (leds) {
+   of_platform_device_create(leds, "opal_leds", NULL);
+   of_node_put(leds);
+   }
+
/* Create "opal" kobject under /sys/firmware */
rc = opal_sysfs_init();
if (rc == 0) {
@@ -841,3 +848,6 @@ EXPORT_SYMBOL_GPL(opal_rtc_write);
 EXPORT_SYMBOL_GPL(opal_tpo_read);
 EXPORT_SYMBOL_GPL(opal_tpo_write);
 EXPORT_SYMBOL_GPL(opal_i2c_request);
+/* Export these symbols for PowerNV LED class driver */
+EXPORT_SYMBOL_GPL(opal_leds_get_ind);
+EXPORT_SYMBOL_GPL(opal_leds_set_ind);
-- 
2.1.0

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

[PATCH v6 3/3] leds/powernv: Add driver for PowerNV platform

2015-07-17 Thread Vasant Hegde
This patch implements LED driver for PowerNV platform using the existing
generic LED class framework.

PowerNV platform has below type of LEDs:
  - System attention
  Indicates there is a problem with the system that needs attention.
  - Identify
  Helps the user locate/identify a particular FRU or resource in the
  system.
  - Fault
  Indicates there is a problem with the FRU or resource at the
  location with which the indicator is associated.

We register classdev structures for all individual LEDs detected on the
system through LED specific device tree nodes. Device tree nodes specify
what all kind of LEDs present on the same location code. It registers
LED classdev structure for each of them.

All the system LEDs can be found in the same regular path /sys/class/leds/.
We don't use LED colors. We use LED node and led-types property to form
LED classdev. Our LEDs have names in this format.

:

Any positive brightness value would turn on the LED and a zero value would
turn off the LED. The driver will return LED_FULL (255) for any turned on
LED and LED_OFF (0) for any turned off LED.

As per the LED class framework, the 'brightness_set' function should not
sleep. Hence these functions have been implemented through global work
queue tasks which might sleep on OPAL async call completion.

The platform level implementation of LED get and set state has been achieved
through OPAL calls. These calls are made available for the driver by
exporting from architecture specific codes.

Signed-off-by: Vasant Hegde 
Signed-off-by: Anshuman Khandual 
Acked-by: Stewart Smith 
Tested-by: Stewart Smith 
---
 .../devicetree/bindings/leds/leds-powernv.txt  |  26 ++
 drivers/leds/Kconfig   |  11 +
 drivers/leds/Makefile  |   1 +
 drivers/leds/leds-powernv.c| 422 +
 4 files changed, 460 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-powernv.txt
 create mode 100644 drivers/leds/leds-powernv.c

diff --git a/Documentation/devicetree/bindings/leds/leds-powernv.txt 
b/Documentation/devicetree/bindings/leds/leds-powernv.txt
new file mode 100644
index 000..6665569
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/leds-powernv.txt
@@ -0,0 +1,26 @@
+Device Tree binding for LEDs on IBM Power Systems
+-
+
+Required properties:
+- compatible : Should be "ibm,opal-v3-led".
+- led-mode   : Should be "lightpath" or "guidinglight".
+
+Each location code of FRU/Enclosure must be expressed in the
+form of a sub-node.
+
+Required properties for the sub nodes:
+- led-types : Supported LED types (attention/identify/fault) provided
+  in the form of string array.
+
+Example:
+
+leds {
+   compatible = "ibm,opal-v3-led";
+   led-mode = "lightpath";
+
+   U78C9.001.RST0027-P1-C1 {
+   led-types = "identify", "fault";
+   };
+   ...
+   ...
+};
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 9ad35f7..f218cc3a 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -560,6 +560,17 @@ config LEDS_BLINKM
  This option enables support for the BlinkM RGB LED connected
  through I2C. Say Y to enable support for the BlinkM LED.
 
+config LEDS_POWERNV
+   tristate "LED support for PowerNV Platform"
+   depends on LEDS_CLASS
+   depends on PPC_POWERNV
+   depends on OF
+   help
+ This option enables support for the system LEDs present on
+ PowerNV platforms. Say 'y' to enable this support in kernel.
+ To compile this driver as a module, choose 'm' here: the module
+ will be called leds-powernv.
+
 config LEDS_SYSCON
bool "LED support for LEDs on system controllers"
depends on LEDS_CLASS=y
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 8d6a24a..6a943d1 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_LEDS_VERSATILE)  += leds-versatile.o
 obj-$(CONFIG_LEDS_MENF21BMC)   += leds-menf21bmc.o
 obj-$(CONFIG_LEDS_PM8941_WLED) += leds-pm8941-wled.o
 obj-$(CONFIG_LEDS_KTD2692) += leds-ktd2692.o
+obj-$(CONFIG_LEDS_POWERNV) += leds-powernv.o
 
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)  += leds-dac124s085.o
diff --git a/drivers/leds/leds-powernv.c b/drivers/leds/leds-powernv.c
new file mode 100644
index 000..c3c0b0c
--- /dev/null
+++ b/drivers/leds/leds-powernv.c
@@ -0,0 +1,422 @@
+/*
+ * PowerNV LED Driver
+ *
+ * Copyright IBM Corp. 2015
+ *
+ * Author: Vasant Hegde 
+ * Author: Anshuman Khandual 
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published 

[PATCH v6 1/3] powerpc/powernv: Add OPAL interfaces for accessing and modifying system LED states

2015-07-17 Thread Vasant Hegde
From: Anshuman Khandual 

This patch registers the following two new OPAL interfaces calls
for the platform LED subsystem. With the help of these new OPAL calls,
the kernel will be able to get or set the state of various individual
LEDs on the system at any given location code which is passed through
the LED specific device tree nodes.

(1) OPAL_LEDS_GET_INDICATOR opal_leds_get_ind
(2) OPAL_LEDS_SET_INDICATOR opal_leds_set_ind

Signed-off-by: Anshuman Khandual 
Signed-off-by: Vasant Hegde 
Acked-by: Stewart Smith 
Tested-by: Stewart Smith 
Acked-by: Benjamin Herrenschmidt 
---
 arch/powerpc/include/asm/opal-api.h| 25 -
 arch/powerpc/include/asm/opal.h|  4 
 arch/powerpc/platforms/powernv/opal-wrappers.S |  2 ++
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/opal-api.h 
b/arch/powerpc/include/asm/opal-api.h
index e9e4c52..8f8c45f 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -154,7 +154,9 @@
 #define OPAL_FLASH_WRITE   111
 #define OPAL_FLASH_ERASE   112
 #define OPAL_PRD_MSG   113
-#define OPAL_LAST  113
+#define OPAL_LEDS_GET_INDICATOR114
+#define OPAL_LEDS_SET_INDICATOR115
+#define OPAL_LAST  115
 
 /* Device tree flags */
 
@@ -756,6 +758,27 @@ struct opal_i2c_request {
__be64 buffer_ra;   /* Buffer real address */
 };
 
+/* LED Mode */
+#define POWERNV_LED_MODE_LIGHT_PATH"lightpath"
+#define POWERNV_LED_MODE_GUIDING_LIGHT "guidinglight"
+
+/* LED type */
+#define POWERNV_LED_TYPE_IDENTIFY  "identify"
+#define POWERNV_LED_TYPE_FAULT "fault"
+#define POWERNV_LED_TYPE_ATTENTION "attention"
+
+enum OpalSlotLedType {
+   OPAL_SLOT_LED_TYPE_ID = 0,  /* IDENTIFY LED */
+   OPAL_SLOT_LED_TYPE_FAULT = 1,   /* FAULT LED */
+   OPAL_SLOT_LED_TYPE_ATTN = 2,/* System Attention LED */
+   OPAL_SLOT_LED_TYPE_MAX = 3
+};
+
+enum OpalSlotLedState {
+   OPAL_SLOT_LED_STATE_OFF = 0,/* LED is OFF */
+   OPAL_SLOT_LED_STATE_ON = 1  /* LED is ON */
+};
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __OPAL_API_H */
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 958e941..3233e6d 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -195,6 +195,10 @@ int64_t opal_ipmi_recv(uint64_t interface, struct 
opal_ipmi_msg *msg,
 int64_t opal_i2c_request(uint64_t async_token, uint32_t bus_id,
 struct opal_i2c_request *oreq);
 int64_t opal_prd_msg(struct opal_prd_msg *msg);
+int64_t opal_leds_get_ind(char *loc_code, __be64 *led_mask,
+ __be64 *led_value, __be64 *max_led_type);
+int64_t opal_leds_set_ind(uint64_t token, char *loc_code, const u64 led_mask,
+ const u64 led_value, __be64 *max_led_type);
 
 int64_t opal_flash_read(uint64_t id, uint64_t offset, uint64_t buf,
uint64_t size, uint64_t token);
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S 
b/arch/powerpc/platforms/powernv/opal-wrappers.S
index d6a7b82..34c2734 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -297,3 +297,5 @@ 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_leds_get_ind,   OPAL_LEDS_GET_INDICATOR);
+OPAL_CALL(opal_leds_set_ind,   OPAL_LEDS_SET_INDICATOR);
-- 
2.1.0

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

[PATCH v6 0/3] LED driver for PowerNV platform

2015-07-17 Thread Vasant Hegde
The following series implements LED driver for PowerNV platform.

PowerNV platform has below type of LEDs:
  - System attention
  Indicates there is a problem with the system that needs attention.
  - Identify
  Helps the user locate/identify a particular FRU or resource in the
  system.
  - Fault
  Indicates there is a problem with the FRU or resource at the
  location with which the indicator is associated.

On PowerNV (Non Virtualized) platform OPAL firmware provides LED information
to host via device tree (location code and LED type). During init we check
for 'ibm,opal/leds' node in device tree to enable LED driver. And we use
OPAL API's to get/set LEDs.

Note that on PowerNV platform firmware can activate fault LED, if it can isolate
the problem. Also one can modify the LEDs using service processor interface. 
None
of these involes kernel. Hence we retain LED state in unload path.

Sample LED device tree output:
--
leds {
compatible = "ibm,opal-v3-led";
led-mode = "lightpath";

U78C9.001.RST0027-P1-C1 {
led-types = "identify", "fault";
};
...
...
}

Sample sysfs output:

.
├── U78CB.001.WZS008R-A1:fault
│   ├── brightness
│   ├── device -> ../../../opal_leds
│   ├── max_brightness
│   ├── power
│   │   ├── async
│   │   ├── autosuspend_delay_ms
│   │   ├── control
│   │   ├── runtime_active_kids
│   │   ├── runtime_active_time
│   │   ├── runtime_enabled
│   │   ├── runtime_status
│   │   ├── runtime_suspended_time
│   │   └── runtime_usage
│   ├── subsystem -> ../../../../../class/leds
│   ├── trigger
│   └── uevent
├── U78CB.001.WZS008R-A1:identify
│   ├── brightness
│   ├── device -> ../../../opal_leds
│   ├── max_brightness
│   ├── power
│   │   ├── async
│   │   ├── autosuspend_delay_ms
│   │   ├── control
│   │   ├── runtime_active_kids
│   │   ├── runtime_active_time
│   │   ├── runtime_enabled
│   │   ├── runtime_status
│   │   ├── runtime_suspended_time
│   │   └── runtime_usage
│   ├── subsystem -> ../../../../../class/leds
│   ├── trigger
│   └── uevent




patch 1/2: PowerNV architecture specific code. This adds necessary
   OPAL APIs.
patch 2/2: Create LED platform device and export OPAL symbols
patch 3/3: Actual LED driver implemenation for PowerNV platform.

Note that this version of patchset is based on top of v4.2-rc2.

@Jacek,
  Let me know if you want me to rebase this patchset on top of LED tree.

Previous patchset:
  v5: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-July/130602.html
  v4: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-April/128028.html
  v3: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-April/127702.html
  v2: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-March/126301.html
  v1: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-March/125705.html

Changes in v6:
  - Added loc_code and type to powernv_led_data structure instead of parsing
them from led classdev name.
  - Fixed documentation issues.
  - Fixed mutex_destry issue
  - Replaced led_classdev_register with devm_led_classdev_register

Changes in v5:
  - Rebased on top of Linus tree
  - Renamed led as leds and updated documentation
  - As Ben and Arnd suggested, removed phandle from documenation
  - As Ben suggested removed led-loc device tree property
  - As Jacek suggested, added back compatible property to documentation

Changes in v4:
  - Updated macros to reflect platform.
  - s/u64/__be64/g for big endian data we get from firmware
  - Addressed review comments from Jacek. Major once are:
Removed list in powernv_led_data structure
s/kzalloc/devm_kzalloc/
Removed compatible property from documentation
s/powernv_led_set_queue/powernv_brightness_set/
  - Removed LED specific brightness_set/get function. Instead this version
uses single function to queue all LED set/get requests. Later we use
LED name to detect LED type and value.
  - Removed hardcoded LED type used in previous version. Instead we use
led-types property to form LED classdev.

Changes in v3:
  - Addressed review comments from Jacek. Major once are:
Replaced spin lock and mutex and removed redundant structures
Replaced pr_* with dev_*
Moved OPAL platform sepcific part to separate patch
Moved repteated code to common function
Added device tree documentation for LEDs

Changes in v2:
  - Rebased patches on top of mpe's next branch
 https://git.kernel.org/cgit/linux/kernel/git/mpe/linux.git/log/?h=next
  - Added System Attention Indicator support
  - Removed redundant code in leds-powernv.c file

Anshuman Khandual (1):
  powerpc/powernv: Add OPAL interfaces for accessing and modifying
system LED states

Vasant Hegde (2):
  powerpc/powernv: Create LED platform device
  leds/powernv: Add driver for PowerNV platform

 .../devicetree/bin

Re: [PATCH v5 3/3] leds/powernv: Add driver for PowerNV platform

2015-07-16 Thread Vasant Hegde
On 07/16/2015 02:17 PM, Michael Ellerman wrote:
> On Thu, 2015-07-16 at 10:27 +0200, Jacek Anaszewski wrote:
>> On 07/16/2015 08:54 AM, Vasant Hegde wrote:
>>>>> +static enum led_brightness powernv_led_get(struct led_classdev *led_cdev)
>>>>> +{
>>>>> +char *loc_code;
>>>>> +int rc, led_type;
>>>>> +__be64 led_mask, led_value, max_led_type;
>>>>> +
>>>>> +led_type = powernv_get_led_type(led_cdev);
>>>>> +if (led_type == -1)
>>>>> +return LED_OFF;
>>>>> +
>>>>> +loc_code = powernv_get_location_code(led_cdev);
>>>>> +if (!loc_code)
>>>>> +return LED_OFF;
>>>>> +
>>>>> +/* Fetch all LED status */
>>>>> +led_mask = cpu_to_be64(0);
>>>>> +led_value = cpu_to_be64(0);
>>>>> +max_led_type = cpu_to_be64(OPAL_SLOT_LED_TYPE_MAX);
>>>>> +
>>>>> +rc = opal_leds_get_ind(loc_code, &led_mask, &led_value, 
>>>>> &max_led_type);
>>>>> +if (rc != OPAL_SUCCESS && rc != OPAL_PARTIAL) {
>>>>> +dev_err(led_cdev->dev,
>>>>> +"%s: OPAL get led call failed [rc=%d]\n",
>>>>> +__func__, rc);
>>>>> +goto led_fail;
>>>>> +}
>>>>> +
>>>>> +led_mask = be64_to_cpu(led_mask);
>>>>> +led_value = be64_to_cpu(led_value);
>>>>
>>>> be64_to_cpu result should be assigned to the variable of u64/s64 type.
>>>
>>> PowerNV platform is capable of running both big/little endian mode.. But
>>> presently our firmware is big endian. These variable contains big endian 
>>> values.
>>> Hence I have created as __be64 .. (This is the convention we follow in other
>>> places as well).
>>
>> It is correct that the argument is of __be64 type, but be64_to_cpu
>> returns u64 type, whereas you assign it to  __be64.
> 
> Yeah that's wrong. You are using led_mask etc as __be64 when you pass them to
> firmware, which is correct, but then you're also using them as the lvalue of
> be64_to_cpu() which returns a u64.
> 

Yep. Got it.


> Sparse should warn you about that if you use it, please do.
> 
> $ apt-get install sparse
> $ cd kernel
> $ make C=2 CF=-D__CHECK_ENDIAN__
> 

Thanks!

-Vasant

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

Re: [PATCH v5 3/3] leds/powernv: Add driver for PowerNV platform

2015-07-16 Thread Vasant Hegde
On 07/16/2015 01:57 PM, Jacek Anaszewski wrote:
> Hi Vasan,
> 

Hello Jacek,

.../...

>>
>> I have added as
>> -  compatible : "ibm,opal-v3-led".
> 
> Please retain "Should be :".
> 

Done.

.../...

>>>
>>> Please parse the led type once upon initialization and add related
>>> property to the struct powernv_led_data that will hold the value.
>>
>> I thought we can get location code and type using class dev name itself. 
>> Hence I
>> didn't add these two properties to structure..
> 
> This way you are doing extra work for parsing the name each time
> the brightness is set.

Agreed. I have added them to structure now.

> 
>> Do you want me to add them to structure itself?
> 
> Yes, please add them.

Done.

> 
>>>
 +loc_code = powernv_get_location_code(led_cdev);
 +if (!loc_code)
 +return;
>>>
>>> The same situation as in case of led type.
>>>
 +/* Prepare for the OPAL call */
 +max_led_type = cpu_to_be64(OPAL_SLOT_LED_TYPE_MAX);
>>>
>>> This value could be also calculated only once.
>>
>> Yeah. May be I can move this to powernv_leds_priv structure.
>>
>>>
 +led_mask = OPAL_SLOT_LED_STATE_ON << led_type;
 +if (value)
 +led_value = led_mask;
 +
 +/* OPAL async call */
 +token = opal_async_get_token_interruptible();
 +if (token < 0) {
 +if (token != -ERESTARTSYS)
 +dev_err(led_cdev->dev,
 +"%s: Couldn't get OPAL async token\n",
 +__func__);
 +goto out_loc;
 +}
 +
 +rc = opal_leds_set_ind(token, loc_code,
 +   led_mask, led_value, &max_led_type);
 +if (rc != OPAL_ASYNC_COMPLETION) {
 +dev_err(led_cdev->dev,
 +"%s: OPAL set LED call failed for %s [rc=%d]\n",
 +__func__, loc_code, rc);
 +goto out_token;
 +}
 +
 +rc = opal_async_wait_response(token, &msg);
 +if (rc) {
 +dev_err(led_cdev->dev,
 +"%s: Failed to wait for the async response [rc=%d]\n",
 +__func__, rc);
 +goto out_token;
 +}
 +
 +rc = be64_to_cpu(msg.params[1]);
 +if (rc != OPAL_SUCCESS)
 +dev_err(led_cdev->dev,
 +"%s : OAPL async call returned failed [rc=%d]\n",
 +__func__, rc);
 +
 +out_token:
 +opal_async_release_token(token);
 +
 +out_loc:
 +kfree(loc_code);
 +}
 +
 +/*
 + * This function fetches the LED state for a given LED type for
 + * mentioned LED classdev structure.
 + */
 +static enum led_brightness powernv_led_get(struct led_classdev *led_cdev)
 +{
 +char *loc_code;
 +int rc, led_type;
 +__be64 led_mask, led_value, max_led_type;
 +
 +led_type = powernv_get_led_type(led_cdev);
 +if (led_type == -1)
 +return LED_OFF;
 +
 +loc_code = powernv_get_location_code(led_cdev);
 +if (!loc_code)
 +return LED_OFF;
 +
 +/* Fetch all LED status */
 +led_mask = cpu_to_be64(0);
 +led_value = cpu_to_be64(0);
 +max_led_type = cpu_to_be64(OPAL_SLOT_LED_TYPE_MAX);
 +
 +rc = opal_leds_get_ind(loc_code, &led_mask, &led_value, 
 &max_led_type);
 +if (rc != OPAL_SUCCESS && rc != OPAL_PARTIAL) {
 +dev_err(led_cdev->dev,
 +"%s: OPAL get led call failed [rc=%d]\n",
 +__func__, rc);
 +goto led_fail;
 +}
 +
 +led_mask = be64_to_cpu(led_mask);
 +led_value = be64_to_cpu(led_value);
>>>
>>> be64_to_cpu result should be assigned to the variable of u64/s64 type.
>>
>> PowerNV platform is capable of running both big/little endian mode.. But
>> presently our firmware is big endian. These variable contains big endian 
>> values.
>> Hence I have created as __be64 .. (This is the convention we follow in other
>> places as well).
> 
> It is correct that the argument is of __be64 type, but be64_to_cpu
> returns u64 type, whereas you assign it to  __be64.
> 

Got it .. Fixed.

>>>
 +/* LED status available */
 +if (!((led_mask >> led_type) & OPAL_SLOT_LED_STATE_ON)) {
 +dev_err(led_cdev->dev,
 +"%s: LED status not available for %s\n",
 +__func__, led_cdev->name);
 +goto led_fail;
 +}
 +
 +/* LED status value */
 +if ((led_value >> led_type) & OPAL_SLOT_LED_STATE_ON) {
 +kfree(loc_code);
 +return LED_FULL;
 +}
 +
 +led_fail:
 +kfree(loc_code);
 +return LED_OFF;
 +}
 +
 +/* Execute LED set task for given led classdev */
 +static void powernv_deferred_led_set(struct work_struct *work)
 +{
 +struct powernv_led_data *powernv_led =
 +container_of(work, struct powernv_led_

Re: [PATCH v5 3/3] leds/powernv: Add driver for PowerNV platform

2015-07-15 Thread Vasant Hegde
On 07/14/2015 02:30 PM, Jacek Anaszewski wrote:
> Hi Vasant,

Jacek,

> 
> Thanks for the update. I think that we have still room
> for improvements, please look at my comments below.

Thanks for the detailed review.


.../...

>> @@ -0,0 +1,24 @@
>> +Device Tree binding for LEDs on IBM Power Systems
>> +-
>> +
> 
> Please start with:
> 
> -
> 
> Required properties:
> - compatible : Should be "ibm,opal-v3-led".
> 
> Each location code of FRU/Enclosure must be expressed in the
> form of a sub-node.
> 
> Required properties for the sub nodes:
> - led-types : Supported LED types (attention/identify/fault) provided
>   in the form of string array.
> 
> -
> 
> or something of this flavour. The example should be at the end.
> 

Fixed.

> 
> 
>> +The 'leds' node under '/ibm,opal' lists service indicators available in the
>> +system and their capabilities.
>> +
>> +leds {
>> +compatible = "ibm,opal-v3-led";
>> +led-mode = "lightpath";
> 
> What about led-mode property? If it is generated by firmware I think,
> that this should be mentioned somehow.

Yes.. Its generated by firmware. Added this property to documentation file.

> 
>> +
>> +U78C9.001.RST0027-P1-C1 {
>> +led-types = "identify", "fault";
>> +};
>> +...
>> +...
>> +};
>> +
>> +Each node under 'leds' node describes location code of FRU/Enclosure.
>> +
>> +compatible : should be : "ibm,opal-v3-led".
> 
> Second colon was redundant here.
> 

I have added as
-  compatible : "ibm,opal-v3-led".


>> +
>> +The properties under each node:
>> +
>> +  led-types : Supported LED types (attention/identify/fault).
>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>> index 4191614..4f56c7a 100644
>> --- a/drivers/leds/Kconfig
>> +++ b/drivers/leds/Kconfig
>> @@ -505,6 +505,17 @@ config LEDS_BLINKM
>> This option enables support for the BlinkM RGB LED connected
>> through I2C. Say Y to enable support for the BlinkM LED.
>>
>> +config LEDS_POWERNV
>> +tristate "LED support for PowerNV Platform"
>> +depends on LEDS_CLASS
>> +depends on PPC_POWERNV
>> +depends on OF
>> +help
>> +  This option enables support for the system LEDs present on
>> +  PowerNV platforms. Say 'y' to enable this support in kernel.
>> +  To compile this driver as a module, choose 'm' here: the module
>> +  will be called leds-powernv.
>> +
>>   config LEDS_SYSCON
>>   bool "LED support for LEDs on system controllers"
>>   depends on LEDS_CLASS=y
>> diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
>> index bf46093..480814a 100644
>> --- a/drivers/leds/Makefile
>> +++ b/drivers/leds/Makefile
>> @@ -59,6 +59,7 @@ obj-$(CONFIG_LEDS_SYSCON)+= leds-syscon.o
>>   obj-$(CONFIG_LEDS_VERSATILE)+= leds-versatile.o
>>   obj-$(CONFIG_LEDS_MENF21BMC)+= leds-menf21bmc.o
>>   obj-$(CONFIG_LEDS_PM8941_WLED)+= leds-pm8941-wled.o
>> +obj-$(CONFIG_LEDS_POWERNV)+= leds-powernv.o
>>
>>   # LED SPI Drivers
>>   obj-$(CONFIG_LEDS_DAC124S085)+= leds-dac124s085.o
>> diff --git a/drivers/leds/leds-powernv.c b/drivers/leds/leds-powernv.c
>> new file mode 100644
>> index 000..b5a307c
>> --- /dev/null
>> +++ b/drivers/leds/leds-powernv.c
>> @@ -0,0 +1,463 @@
>> +/*
>> + * PowerNV LED Driver
>> + *
>> + * Copyright IBM Corp. 2015
>> + *
>> + * Author: Vasant Hegde 
>> + * Author: Anshuman Khandual 
>> + *
>> + * 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 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#include 
>> +
>> +/*
>> + * By default unload path resets all the LEDs. But on PowerNV platform
>> + * we want to retain LED state across reboot as these are controlled by
>> + * firmware. Also service processor can modify the LEDs independent of
>> + * OS. Hence avoid resetting LEDs in unload path.
>> + */
>> +static bool led_disabled;

[PATCH v5 3/3] leds/powernv: Add driver for PowerNV platform

2015-07-01 Thread Vasant Hegde
This patch implements LED driver for PowerNV platform using the existing
generic LED class framework.

PowerNV platform has below type of LEDs:
  - System attention
  Indicates there is a problem with the system that needs attention.
  - Identify
  Helps the user locate/identify a particular FRU or resource in the
  system.
  - Fault
  Indicates there is a problem with the FRU or resource at the
  location with which the indicator is associated.

We register classdev structures for all individual LEDs detected on the
system through LED specific device tree nodes. Device tree nodes specify
what all kind of LEDs present on the same location code. It registers
LED classdev structure for each of them.

All the system LEDs can be found in the same regular path /sys/class/leds/.
We don't use LED colors. We use LED node and led-types property to form
LED classdev. Our LEDs have names in this format.

:

Any positive brightness value would turn on the LED and a zero value would
turn off the LED. The driver will return LED_FULL (255) for any turned on
LED and LED_OFF (0) for any turned off LED.

As per the LED class framework, the 'brightness_set' function should not
sleep. Hence these functions have been implemented through global work
queue tasks which might sleep on OPAL async call completion.

The platform level implementation of LED get and set state has been achieved
through OPAL calls. These calls are made available for the driver by
exporting from architecture specific codes.

Signed-off-by: Vasant Hegde 
Signed-off-by: Anshuman Khandual 
Acked-by: Stewart Smith 
Tested-by: Stewart Smith 
---
 .../devicetree/bindings/leds/leds-powernv.txt  |  24 ++
 drivers/leds/Kconfig   |  11 +
 drivers/leds/Makefile  |   1 +
 drivers/leds/leds-powernv.c| 463 +
 4 files changed, 499 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-powernv.txt
 create mode 100644 drivers/leds/leds-powernv.c

diff --git a/Documentation/devicetree/bindings/leds/leds-powernv.txt 
b/Documentation/devicetree/bindings/leds/leds-powernv.txt
new file mode 100644
index 000..636f028
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/leds-powernv.txt
@@ -0,0 +1,24 @@
+Device Tree binding for LEDs on IBM Power Systems
+-
+
+The 'leds' node under '/ibm,opal' lists service indicators available in the
+system and their capabilities.
+
+leds {
+   compatible = "ibm,opal-v3-led";
+   led-mode = "lightpath";
+
+   U78C9.001.RST0027-P1-C1 {
+   led-types = "identify", "fault";
+   };
+   ...
+   ...
+};
+
+Each node under 'leds' node describes location code of FRU/Enclosure.
+
+compatible : should be : "ibm,opal-v3-led".
+
+The properties under each node:
+
+  led-types : Supported LED types (attention/identify/fault).
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 4191614..4f56c7a 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -505,6 +505,17 @@ config LEDS_BLINKM
  This option enables support for the BlinkM RGB LED connected
  through I2C. Say Y to enable support for the BlinkM LED.
 
+config LEDS_POWERNV
+   tristate "LED support for PowerNV Platform"
+   depends on LEDS_CLASS
+   depends on PPC_POWERNV
+   depends on OF
+   help
+ This option enables support for the system LEDs present on
+ PowerNV platforms. Say 'y' to enable this support in kernel.
+ To compile this driver as a module, choose 'm' here: the module
+ will be called leds-powernv.
+
 config LEDS_SYSCON
bool "LED support for LEDs on system controllers"
depends on LEDS_CLASS=y
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index bf46093..480814a 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_LEDS_SYSCON) += leds-syscon.o
 obj-$(CONFIG_LEDS_VERSATILE)   += leds-versatile.o
 obj-$(CONFIG_LEDS_MENF21BMC)   += leds-menf21bmc.o
 obj-$(CONFIG_LEDS_PM8941_WLED) += leds-pm8941-wled.o
+obj-$(CONFIG_LEDS_POWERNV) += leds-powernv.o
 
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)  += leds-dac124s085.o
diff --git a/drivers/leds/leds-powernv.c b/drivers/leds/leds-powernv.c
new file mode 100644
index 000..b5a307c
--- /dev/null
+++ b/drivers/leds/leds-powernv.c
@@ -0,0 +1,463 @@
+/*
+ * PowerNV LED Driver
+ *
+ * Copyright IBM Corp. 2015
+ *
+ * Author: Vasant Hegde 
+ * Author: Anshuman Khandual 
+ *
+ * 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; e

[PATCH v5 0/3] LED driver for PowerNV platform

2015-07-01 Thread Vasant Hegde
The following series implements LED driver for PowerNV platform.

PowerNV platform has below type of LEDs:
  - System attention
  Indicates there is a problem with the system that needs attention.
  - Identify
  Helps the user locate/identify a particular FRU or resource in the
  system.
  - Fault
  Indicates there is a problem with the FRU or resource at the
  location with which the indicator is associated.

On PowerNV (Non Virtualized) platform OPAL firmware provides LED information
to host via device tree (location code and LED type). During init we check
for 'ibm,opal/leds' node in device tree to enable LED driver. And we use
OPAL API's to get/set LEDs.

Note that on PowerNV platform firmware can activate fault LED, if it can isolate
the problem. Also one can modify the LEDs using service processor interface. 
None
of these involes kernel. Hence we retain LED state in unload path.

Sample LED device tree output:
--
leds {
compatible = "ibm,opal-v3-led";
led-mode = "lightpath";

U78C9.001.RST0027-P1-C1 {
led-types = "identify", "fault";
};
...
...
}

Sample sysfs output:

.
├── U78CB.001.WZS008R-A1:fault
│   ├── brightness
│   ├── device -> ../../../opal_leds
│   ├── max_brightness
│   ├── power
│   │   ├── async
│   │   ├── autosuspend_delay_ms
│   │   ├── control
│   │   ├── runtime_active_kids
│   │   ├── runtime_active_time
│   │   ├── runtime_enabled
│   │   ├── runtime_status
│   │   ├── runtime_suspended_time
│   │   └── runtime_usage
│   ├── subsystem -> ../../../../../class/leds
│   ├── trigger
│   └── uevent
├── U78CB.001.WZS008R-A1:identify
│   ├── brightness
│   ├── device -> ../../../opal_leds
│   ├── max_brightness
│   ├── power
│   │   ├── async
│   │   ├── autosuspend_delay_ms
│   │   ├── control
│   │   ├── runtime_active_kids
│   │   ├── runtime_active_time
│   │   ├── runtime_enabled
│   │   ├── runtime_status
│   │   ├── runtime_suspended_time
│   │   └── runtime_usage
│   ├── subsystem -> ../../../../../class/leds
│   ├── trigger
│   └── uevent




patch 1/2: PowerNV architecture specific code. This adds necessary
   OPAL APIs.
patch 2/2: Create LED platform device and export OPAL symbols
patch 3/3: Actual LED driver implemenation for PowerNV platform.

Note that this version of patchset is based on upstream Linus tree
as Jacek mention its better to go via LED subsystem (commit 05a8256c).

@Jacek,
  Let me know if you want me to rebase this patchset on top of LED tree.

Previous patchset:
  v4: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-April/128028.html
  v3: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-April/127702.html
  v2: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-March/126301.html
  v1: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-March/125705.html

Changes in v5:
  - Rebased on top of Linus tree
  - Renamed led as leds and updated documentation
  - As Ben and Arnd suggested, removed phandle from documenation
  - As Ben suggested removed led-loc device tree property
  - As Jacek suggested, added back compatible property to documentation

Changes in v4:
  - Updated macros to reflect platform.
  - s/u64/__be64/g for big endian data we get from firmware
  - Addressed review comments from Jacek. Major once are:
Removed list in powernv_led_data structure
s/kzalloc/devm_kzalloc/
Removed compatible property from documentation
s/powernv_led_set_queue/powernv_brightness_set/
  - Removed LED specific brightness_set/get function. Instead this version
uses single function to queue all LED set/get requests. Later we use
LED name to detect LED type and value.
  - Removed hardcoded LED type used in previous version. Instead we use
led-types property to form LED classdev.

Changes in v3:
  - Addressed review comments from Jacek. Major once are:
Replaced spin lock and mutex and removed redundant structures
Replaced pr_* with dev_*
Moved OPAL platform sepcific part to separate patch
Moved repteated code to common function
Added device tree documentation for LEDs

Changes in v2:
  - Rebased patches on top of mpe's next branch
 https://git.kernel.org/cgit/linux/kernel/git/mpe/linux.git/log/?h=next
  - Added System Attention Indicator support
  - Removed redundant code in leds-powernv.c file

Anshuman Khandual (1):
  powerpc/powernv: Add OPAL interfaces for accessing and modifying
system LED states

Vasant Hegde (2):
  powerpc/powernv: Create LED platform device
  leds/powernv: Add driver for PowerNV platform

 .../devicetree/bindings/leds/leds-powernv.txt  |  27 ++
 arch/powerpc/include/asm/opal-api.h|  29 +-
 arch/powerpc/include/asm/opal.h|   4 +
 arch/powerpc/platforms/powernv/opal-wrappers.S |   2 +
 arch/powe

[PATCH v5 1/3] powerpc/powernv: Add OPAL interfaces for accessing and modifying system LED states

2015-07-01 Thread Vasant Hegde
From: Anshuman Khandual 

This patch registers the following two new OPAL interfaces calls
for the platform LED subsystem. With the help of these new OPAL calls,
the kernel will be able to get or set the state of various individual
LEDs on the system at any given location code which is passed through
the LED specific device tree nodes.

(1) OPAL_LEDS_GET_INDICATOR opal_leds_get_ind
(2) OPAL_LEDS_SET_INDICATOR opal_leds_set_ind

Signed-off-by: Anshuman Khandual 
Signed-off-by: Vasant Hegde 
Acked-by: Stewart Smith 
Tested-by: Stewart Smith 
Acked-by: Benjamin Herrenschmidt 
---
 arch/powerpc/include/asm/opal-api.h| 25 -
 arch/powerpc/include/asm/opal.h|  4 
 arch/powerpc/platforms/powernv/opal-wrappers.S |  2 ++
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/opal-api.h 
b/arch/powerpc/include/asm/opal-api.h
index e9e4c52..8f8c45f 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -154,7 +154,9 @@
 #define OPAL_FLASH_WRITE   111
 #define OPAL_FLASH_ERASE   112
 #define OPAL_PRD_MSG   113
-#define OPAL_LAST  113
+#define OPAL_LEDS_GET_INDICATOR114
+#define OPAL_LEDS_SET_INDICATOR115
+#define OPAL_LAST  115
 
 /* Device tree flags */
 
@@ -756,6 +758,27 @@ struct opal_i2c_request {
__be64 buffer_ra;   /* Buffer real address */
 };
 
+/* LED Mode */
+#define POWERNV_LED_MODE_LIGHT_PATH"lightpath"
+#define POWERNV_LED_MODE_GUIDING_LIGHT "guidinglight"
+
+/* LED type */
+#define POWERNV_LED_TYPE_IDENTIFY  "identify"
+#define POWERNV_LED_TYPE_FAULT "fault"
+#define POWERNV_LED_TYPE_ATTENTION "attention"
+
+enum OpalSlotLedType {
+   OPAL_SLOT_LED_TYPE_ID = 0,  /* IDENTIFY LED */
+   OPAL_SLOT_LED_TYPE_FAULT = 1,   /* FAULT LED */
+   OPAL_SLOT_LED_TYPE_ATTN = 2,/* System Attention LED */
+   OPAL_SLOT_LED_TYPE_MAX = 3
+};
+
+enum OpalSlotLedState {
+   OPAL_SLOT_LED_STATE_OFF = 0,/* LED is OFF */
+   OPAL_SLOT_LED_STATE_ON = 1  /* LED is ON */
+};
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __OPAL_API_H */
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 958e941..03ef848 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -195,6 +195,10 @@ int64_t opal_ipmi_recv(uint64_t interface, struct 
opal_ipmi_msg *msg,
 int64_t opal_i2c_request(uint64_t async_token, uint32_t bus_id,
 struct opal_i2c_request *oreq);
 int64_t opal_prd_msg(struct opal_prd_msg *msg);
+int64_t opal_leds_get_ind(char *loc_code, u64 *led_mask,
+ u64 *led_value, u64 *max_led_type);
+int64_t opal_leds_set_ind(uint64_t token, char *loc_code, const u64 led_mask,
+ const u64 led_value, u64 *max_led_type);
 
 int64_t opal_flash_read(uint64_t id, uint64_t offset, uint64_t buf,
uint64_t size, uint64_t token);
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S 
b/arch/powerpc/platforms/powernv/opal-wrappers.S
index d6a7b82..34c2734 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -297,3 +297,5 @@ 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_leds_get_ind,   OPAL_LEDS_GET_INDICATOR);
+OPAL_CALL(opal_leds_set_ind,   OPAL_LEDS_SET_INDICATOR);
-- 
2.1.0

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

[PATCH v5 2/3] powerpc/powernv: Create LED platform device

2015-07-01 Thread Vasant Hegde
This patch adds platform devices for leds. Also export LED related
OPAL API's so that led driver can use these APIs.

Signed-off-by: Vasant Hegde 
Acked-by: Benjamin Herrenschmidt 
---
 arch/powerpc/platforms/powernv/opal.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index f084afa..6839358 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -648,7 +648,7 @@ static void opal_init_heartbeat(void)
 
 static int __init opal_init(void)
 {
-   struct device_node *np, *consoles;
+   struct device_node *np, *consoles, *leds;
int rc;
 
opal_node = of_find_node_by_path("/ibm,opal");
@@ -689,6 +689,13 @@ static int __init opal_init(void)
/* Setup a heatbeat thread if requested by OPAL */
opal_init_heartbeat();
 
+   /* Create leds platform devices */
+   leds = of_find_node_by_path("/ibm,opal/leds");
+   if (leds) {
+   of_platform_device_create(leds, "opal_leds", NULL);
+   of_node_put(leds);
+   }
+
/* Create "opal" kobject under /sys/firmware */
rc = opal_sysfs_init();
if (rc == 0) {
@@ -841,3 +848,6 @@ EXPORT_SYMBOL_GPL(opal_rtc_write);
 EXPORT_SYMBOL_GPL(opal_tpo_read);
 EXPORT_SYMBOL_GPL(opal_tpo_write);
 EXPORT_SYMBOL_GPL(opal_i2c_request);
+/* Export these symbols for PowerNV LED class driver */
+EXPORT_SYMBOL_GPL(opal_leds_get_ind);
+EXPORT_SYMBOL_GPL(opal_leds_set_ind);
-- 
2.1.0

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

Re: [PATCH v4 3/3] leds/powernv: Add driver for PowerNV platform

2015-06-25 Thread Vasant Hegde
On 06/25/2015 06:39 AM, Benjamin Herrenschmidt wrote:
> On Tue, 2015-04-28 at 15:40 +0530, Vasant Hegde wrote:
> 
>> +Device Tree binding for LEDs on IBM Power Systems
>> +-
>> +
>> +The 'led' node under '/ibm,opal' lists service indicators available in the
>> +system and their capabilities.
>> +
>> +led {
>> +compatible = "ibm,opal-v3-led";
>> +phandle = <0x106b>;
>> +linux,phandle = <0x106b>;
>> +led-mode = "lightpath";
>> +
>> +U78C9.001.RST0027-P1-C1 {
>> +led-types = "identify", "fault";
>> +led-loc = "descendent";
>> +phandle = <0x106f>;
>> +linux,phandle = <0x106f>;
>> +};
>> +...
>> +...
>> +};

Ben,

> 
> My only issue is that /led should probably have been /leds but afaik
> this is already committed in the FW tree. Vasant, have we done a release
> what that code yet or can we still change this ?

I think we can change OPAL side as we haven't released kernel code... So no
consumer yet.
Will send a patch to skiboot mailing list. lets see

> 
> Also what does led-mode = "lightpath" means ? Can you describe it ?
> Are there alternative values ? I don't see the point myself ...

Yes.. Our system can work in two modes...
   - light path --> Both identify and faults are supported
 typically all low end servers are in this mode
  - guiding light -> Only identify LEDs are supports . no fault indicator
support for individual FRU
 typically high end servers are in this mode.

These modes are static in nature.. meaning we cannot change that during run 
time...
AFAIK all the PowerNV boxes shipped today are in Light Path mode.. I have added
this, so that in future if they decide to ship system with guiding light mode,
then we don't need to make any changes.


> 
> Don't leave the "linux,phandle" in the description of the binding (nor
> the phandle actually). They are implicit for all nodes, no need to
> clutter the documentation with them.

Sure. Will fix in next version.


> 
>> +Each node under 'led' node describes location code of FRU/Enclosure.
>> +
>> +The properties under each node:
>> +
>> +  led-types : Supported LED types (attention/identify/fault).
>> +
>> +  led-loc   : enclosure/descendent(FRU) location code.
> 
> I don't understand what that means. Please provide a more detailed
> explanation.
> 

This describes the LED location (FRU or enclosure level).. This was added to
identify the component (as FRU leds are overloaded and enclosure level we have
separate LEDs for each component)...


> Is the name of the node the loc code of the FRU ? In that case, how do
> you deal with multiple LEDs on the same FRU without a unit address ?

We use location code + LED type for node. So that we can identify multiple LEDs.

Looking back again, probably we can take out above property as we are not using
that today.

-Vasant

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

Re: [PATCH v4 0/3] LED interface for PowerNV platform

2015-06-10 Thread Vasant Hegde
On 04/28/2015 03:39 PM, Vasant Hegde wrote:
> The following series implements LED driver for PowerNV platform.

Ben, Michael,

Can you please review/ACK this patchset?

-Vasant

> 
> PowerNV platform has below type of LEDs:
>   - System attention
>   Indicates there is a problem with the system that needs attention.
>   - Identify
>   Helps the user locate/identify a particular FRU or resource in the
>   system.
>   - Fault
>   Indicates there is a problem with the FRU or resource at the
>   location with which the indicator is associated.
> 
> On PowerNV (Non Virtualized) platform OPAL firmware provides LED information
> to host via device tree (location code and LED type). During init we check
> for 'ibm,opal/led' node in device tree to enable LED driver. And we use
> OPAL API's to get/set LEDs.
> 
> Note that on PowerNV platform firmware can activate fault LED, if it can 
> isolate
> the problem. Also one can modify the LEDs using service processor interface. 
> None
> of these involes kernel. Hence we retain LED state in unload path.
> 
> Sample LED device tree output:
> --
> led {
>   compatible = "ibm,opal-v3-led";
>   phandle = <0x106b>;
>   linux,phandle = <0x106b>;
>   led-mode = "lightpath";
> 
>   U78C9.001.RST0027-P1-C1 {
>   led-types = "identify", "fault";
>   led-loc = "descendent";
>   phandle = <0x106f>;
>   linux,phandle = <0x106f>;
>   };
>   ...
>   ...
> }
> 
> Sample sysfs output:
> 
> .
> ├── U78CB.001.WZS008R-A1:fault
> │   ├── brightness
> │   ├── device -> ../../../opal_led
> │   ├── max_brightness
> │   ├── power
> │   │   ├── async
> │   │   ├── autosuspend_delay_ms
> │   │   ├── control
> │   │   ├── runtime_active_kids
> │   │   ├── runtime_active_time
> │   │   ├── runtime_enabled
> │   │   ├── runtime_status
> │   │   ├── runtime_suspended_time
> │   │   └── runtime_usage
> │   ├── subsystem -> ../../../../../class/leds
> │   ├── trigger
> │   └── uevent
> ├── U78CB.001.WZS008R-A1:identify
> │   ├── brightness
> │   ├── device -> ../../../opal_led
> │   ├── max_brightness
> │   ├── power
> │   │   ├── async
> │   │   ├── autosuspend_delay_ms
> │   │   ├── control
> │   │   ├── runtime_active_kids
> │   │   ├── runtime_active_time
> │   │   ├── runtime_enabled
> │   │   ├── runtime_status
> │   │   ├── runtime_suspended_time
> │   │   └── runtime_usage
> │   ├── subsystem -> ../../../../../class/leds
> │   ├── trigger
> │   └── uevent
> 
> 
> 
> 
> patch 1/2: PowerNV architecture specific code. This adds necessary
>OPAL APIs.
> patch 2/2: Create LED platform device and export OPAL symbols
> patch 3/3: Actual LED driver implemenation for PowerNV platform.
> 
> This patchset is based on top of mpe's next branch:
>   https://git.kernel.org/cgit/linux/kernel/git/mpe/linux.git/log/?h=next
> 
> Previous patchset:
>   v3: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-April/127702.html
>   v2: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-March/126301.html
>   v1: https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-March/125705.html
> 
> Changes in v4:
>   - Updated macros to reflect platform.
>   - s/u64/__be64/g for big endian data we get from firmware
>   - Addressed review comments from Jacek. Major once are:
> Removed list in powernv_led_data structure
> s/kzalloc/devm_kzalloc/
> Removed compatible property from documentation
> s/powernv_led_set_queue/powernv_brightness_set/
>   - Removed LED specific brightness_set/get function. Instead this version
> uses single function to queue all LED set/get requests. Later we use
> LED name to detect LED type and value.
>   - Removed hardcoded LED type used in previous version. Instead we use
> led-types property to form LED classdev.
> 
> Changes in v3:
>   - Addressed review comments from Jacek. Major once are:
> Replaced spin lock and mutex and removed redundant structures
> Replaced pr_* with dev_*
> Moved OPAL platform sepcific part to separate patch
> Moved repteated code to common function
> Added device tree documentation for LEDs
> 
> Changes in v2:
>   - Rebased patches on top of mpe's next branch
> https://git.kernel.org/cgit/linux/kernel/git/mpe/linux.git/log/?h=next
>   - Added System Attention Indicator support
>   - Removed redundant code in leds-powernv.c file
> 
> 
> ---
> 
> Anshuman

Re: [PATCH v4 3/3] leds/powernv: Add driver for PowerNV platform

2015-04-30 Thread Vasant Hegde
On 04/30/2015 07:59 PM, Jacek Anaszewski wrote:
> Hi Vasant,
> 

Hi  Jacek,

.../...

>> diff --git a/Documentation/devicetree/bindings/leds/leds-powernv.txt
>> b/Documentation/devicetree/bindings/leds/leds-powernv.txt
>> new file mode 100644
>> index 000..6bb0e7e
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/leds/leds-powernv.txt
>> @@ -0,0 +1,29 @@
>> +Device Tree binding for LEDs on IBM Power Systems
>> +-
>> +
>> +The 'led' node under '/ibm,opal' lists service indicators available in the
>> +system and their capabilities.
>> +
>> +led {
>> +compatible = "ibm,opal-v3-led";
>> +phandle = <0x106b>;
>> +linux,phandle = <0x106b>;
>> +led-mode = "lightpath";
>> +
>> +U78C9.001.RST0027-P1-C1 {
>> +led-types = "identify", "fault";
>> +led-loc = "descendent";
>> +phandle = <0x106f>;
>> +linux,phandle = <0x106f>;
>> +};
>> +...
>> +...
>> +};
>> +
>> +Each node under 'led' node describes location code of FRU/Enclosure.
>> +
>> +The properties under each node:
>> +
>> +  led-types : Supported LED types (attention/identify/fault).
>> +
>> +  led-loc   : enclosure/descendent(FRU) location code.
> 
> DT documentation it usually constructed so that properties are
> described in the beginning and the file ends with an example.
> 
> Also last time I mistakenly requested to remove description of
> compatible property, but it should also be present here and
> the entry should described it in detail, like:
> 
> - compatible : Should be "ibm,opal-v3-led".

That's fine. I will fix it in v5.

> 
> Please refer to the other bindings,
> 
> I will express my opinion on the LED part after powerpc maintainer
> will ack DT bindings.
> 

Sure..

@Ben/Michael,
  Can you please review/ack this patchset?

-Vasant

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

Re: [PATCH v4 3/3] leds/powernv: Add driver for PowerNV platform

2015-04-30 Thread Vasant Hegde
On 04/28/2015 03:48 PM, Arnd Bergmann wrote:
> On Tuesday 28 April 2015 15:40:35 Vasant Hegde wrote:
>> +++ b/Documentation/devicetree/bindings/leds/leds-powernv.txt
>> @@ -0,0 +1,29 @@
>> +Device Tree binding for LEDs on IBM Power Systems
>> +-
>> +
>> +The 'led' node under '/ibm,opal' lists service indicators available in the
>> +system and their capabilities.
>> +
>> +led {
>> +   compatible = "ibm,opal-v3-led";
>> +   phandle = <0x106b>;
>> +   linux,phandle = <0x106b>;
>> +   led-mode = "lightpath";
>> +
>> +   U78C9.001.RST0027-P1-C1 {
>> +   led-types = "identify", "fault";
>> +   led-loc = "descendent";
>> +   phandle = <0x106f>;
>> +   linux,phandle = <0x106f>;
>> +   };
>> +   ...
>> +   ...
>> +};

Arnd,

  Thanks for the review.

> 
> We normally don't list the 'phandle' or 'linux,phandle' properties in the 
> binding
> description.
> 

Sure. .Will fix.


>> +
>> +Each node under 'led' node describes location code of FRU/Enclosure.
>> +
>> +The properties under each node:
>> +
>> +  led-types : Supported LED types (attention/identify/fault).
>> +
>> +  led-loc   : enclosure/descendent(FRU) location code.
>>
> 
> Could you use the standard 'label' property for this?

This was discussed earlier [1] and agreed to use led-types property here..

[1] https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-March/126301.html

-Vasant

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

Re: [PATCH v2 2/2] leds/powernv: Add driver for PowerNV platform

2015-04-28 Thread Vasant Hegde
On 04/27/2015 07:17 PM, Vasant Hegde wrote:
> On 04/27/2015 04:45 PM, Jacek Anaszewski wrote:
>> On 04/27/2015 11:53 AM, Benjamin Herrenschmidt wrote:
>>> On Mon, 2015-04-27 at 09:24 +0200, Jacek Anaszewski wrote:
>>>> I was not aware that some other entity than the driver could be
>>>> interested in the information provided by DT node. I will no longer
>>>> object, provided that we will get an ack from DT maintainer.
>>>
> 
> Jacket,

Oops.. Sorry..  It was a typo .. I meant Jacek..


-Vasant

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

[PATCH v4 2/3] powerpc/powernv: Create LED platform device

2015-04-28 Thread Vasant Hegde
This patch adds paltform devices for leds. Also export LED related
OPAL API's so that led driver can use these APIs.

Signed-off-by: Vasant Hegde 
---
 arch/powerpc/platforms/powernv/opal.c |   12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index 2241565..b1951aa 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -784,7 +784,7 @@ static void opal_init_heartbeat(void)
 
 static int __init opal_init(void)
 {
-   struct device_node *np, *consoles;
+   struct device_node *np, *consoles, *led;
int rc;
 
opal_node = of_find_node_by_path("/ibm,opal");
@@ -813,6 +813,13 @@ static int __init opal_init(void)
/* Setup a heatbeat thread if requested by OPAL */
opal_init_heartbeat();
 
+   /* Create led platform devices */
+   led = of_find_node_by_path("/ibm,opal/led");
+   if (led) {
+   of_platform_device_create(led, "opal_led", NULL);
+   of_node_put(led);
+   }
+
/* Find all OPAL interrupts and request them */
opal_irq_init(opal_node);
 
@@ -970,3 +977,6 @@ EXPORT_SYMBOL_GPL(opal_rtc_write);
 EXPORT_SYMBOL_GPL(opal_tpo_read);
 EXPORT_SYMBOL_GPL(opal_tpo_write);
 EXPORT_SYMBOL_GPL(opal_i2c_request);
+/* Export these symbols for PowerNV LED class driver */
+EXPORT_SYMBOL_GPL(opal_leds_get_ind);
+EXPORT_SYMBOL_GPL(opal_leds_set_ind);

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

[PATCH v4 3/3] leds/powernv: Add driver for PowerNV platform

2015-04-28 Thread Vasant Hegde
This patch implements LED driver for PowerNV platform using the existing
generic LED class framework.

PowerNV platform has below type of LEDs:
  - System attention
  Indicates there is a problem with the system that needs attention.
  - Identify
  Helps the user locate/identify a particular FRU or resource in the
  system.
  - Fault
  Indicates there is a problem with the FRU or resource at the
  location with which the indicator is associated.

We register classdev structures for all individual LEDs detected on the
system through LED specific device tree nodes. Device tree nodes specify
what all kind of LEDs present on the same location code. It registers
LED classdev structure for each of them.

All the system LEDs can be found in the same regular path /sys/class/leds/.
We don't use LED colors. We use LED node and led-types property to form
LED classdev. Our LEDs have names in this format.

:

Any positive brightness value would turn on the LED and a zero value would
turn off the LED. The driver will return LED_FULL (255) for any turned on
LED and LED_OFF (0) for any turned off LED.

As per the LED class framework, the 'brightness_set' function should not
sleep. Hence these functions have been implemented through global work
queue tasks which might sleep on OPAL async call completion.

The platform level implementation of LED get and set state has been achieved
through OPAL calls. These calls are made available for the driver by
exporting from architecture specific codes.

Signed-off-by: Vasant Hegde 
Signed-off-by: Anshuman Khandual 
Acked-by: Stewart Smith 
Tested-by: Stewart Smith 

---
Changes in v4:
  - s/u64/__be64/g for big endian data we get from firmware
  - Addressed review comments from Jacek. Major once are:
Removed list in powernv_led_data structure
s/kzalloc/devm_kzalloc/
Removed compatible property from documentation
s/powernv_led_set_queue/powernv_brightness_set/
  - Removed LED specific brightness_set/get function. Instead this version
uses single function to queue all LED set/get requests. Later we use
LED name to detect LED type and value.
  - Removed hardcoded LED type used in previous version. Instead we use
led-types property to form LED classdev.


Changes in v3:
  - Addressed review comments from Jacek. Major once are:
Replaced spin lock and mutex and removed redundant structures
Replaced pr_* with dev_*
Moved OPAL platform sepcific part to separate patch
Moved repteated code to common function
Added device tree documentation for LEDs


Changes in v2:
  - Added System Attention indicator support
  - Moved common code to powernv_led_set_queue()


 .../devicetree/bindings/leds/leds-powernv.txt  |   29 +
 drivers/leds/Kconfig   |   11 
 drivers/leds/Makefile  |1 
 drivers/leds/leds-powernv.c|  472 
 4 files changed, 513 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-powernv.txt
 create mode 100644 drivers/leds/leds-powernv.c

diff --git a/Documentation/devicetree/bindings/leds/leds-powernv.txt 
b/Documentation/devicetree/bindings/leds/leds-powernv.txt
new file mode 100644
index 000..6bb0e7e
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/leds-powernv.txt
@@ -0,0 +1,29 @@
+Device Tree binding for LEDs on IBM Power Systems
+-
+
+The 'led' node under '/ibm,opal' lists service indicators available in the
+system and their capabilities.
+
+led {
+   compatible = "ibm,opal-v3-led";
+   phandle = <0x106b>;
+   linux,phandle = <0x106b>;
+   led-mode = "lightpath";
+
+   U78C9.001.RST0027-P1-C1 {
+   led-types = "identify", "fault";
+   led-loc = "descendent";
+   phandle = <0x106f>;
+   linux,phandle = <0x106f>;
+   };
+   ...
+   ...
+};
+
+Each node under 'led' node describes location code of FRU/Enclosure.
+
+The properties under each node:
+
+  led-types : Supported LED types (attention/identify/fault).
+
+  led-loc   : enclosure/descendent(FRU) location code.
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 25b320d..2ea0849 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -508,6 +508,17 @@ config LEDS_BLINKM
  This option enables support for the BlinkM RGB LED connected
  through I2C. Say Y to enable support for the BlinkM LED.
 
+config LEDS_POWERNV
+   tristate "LED support for PowerNV Platform"
+   depends on LEDS_CLASS
+   depends on PPC_POWERNV
+   depends on OF
+   help
+ This option enables support for the system LEDs present on
+ PowerNV platforms. Say 'y' to enable this support in ker

  1   2   >