Re: [RFC PATCH] scripts/gdb: add data window feature

2015-07-21 Thread Houcheng Lin
2015-07-22 5:04 GMT+08:00 Jan Kiszka :
> On 2015-07-16 17:58, Houcheng Lin wrote:
>> Add data window feature to show current kernel status
>> on separate consoles, including: 1) registers, 2) back
>> trace and 3) watch data windows.
>>
>> The data window would help kernel developer to understand
>> current hardware/ kernel status, and on single-stepping, the
>> modified fields in the data window would be highlighted.
>
> I was trying to get an overview of this feature. Unfortunately, it does
> not work for me. I type in the commands you describe in the
> documentation, but nothing shows up. I suspect there are some hard-coded
> assumption about directory layouts etc. that aren't fulfilled here
> (out-of-tree build).
Sorry for not working. The steps might be run the "lx-dw" command
first, then step the kernel in gdb; the kernel status would be dump
to files in /tmp. Then you can run lx-dw.sh that creates 3 xterm window
to display registers, back trace and watch variables.

>
> Anyway, let's try to understand what you would like to achieve. This
> seems to be some add-on tool for gdb debugging sessions to display
> target states continuously in separate terminals. Right? Is this
> comparable to gdb's tui mode?
>
Yes, it is similar feature; dumps the content of register and kernel
status into a separate window continuously and highlight the difference.
It's snapshot is here:
https://www.dropbox.com/s/tl67sxm6474jd8i/dw-screenshot.png?dl=0

> More important, is this specific to the debugging infrastructure we have
> in scripts/gdb? Or could I install it (after some modifications, I
> guess) in my home directory and use it for any gdb session, not just
> with Linux kernels? Is there anything in it that particularly refers to
> Linux structures? In that case I would suggest to make it stand-alone
> first so that one could easily include it whenever needed, either
> explicitly or via ~/.gitinit.

This is not under the infrastructure of kernel gdb, however, this feature
is needed and specific for kernel debugging. When trace an optimized kernel
source, we usually need to trace it in assembly and throught the data window
to update the current kernel status. It can be standalone, but I think it may
helps a lot when developing kernel and good to be part of kernel gdb scripts.

best regards,
Houcheng Lin

>
> Thanks for sharing in any case!
>
> Jan
>



-- 
Best regards,
Houcheng Lin
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH] scripts/gdb: add data window feature

2015-07-21 Thread Houcheng Lin
2015-07-22 5:04 GMT+08:00 Jan Kiszka jan.kis...@web.de:
 On 2015-07-16 17:58, Houcheng Lin wrote:
 Add data window feature to show current kernel status
 on separate consoles, including: 1) registers, 2) back
 trace and 3) watch data windows.

 The data window would help kernel developer to understand
 current hardware/ kernel status, and on single-stepping, the
 modified fields in the data window would be highlighted.

 I was trying to get an overview of this feature. Unfortunately, it does
 not work for me. I type in the commands you describe in the
 documentation, but nothing shows up. I suspect there are some hard-coded
 assumption about directory layouts etc. that aren't fulfilled here
 (out-of-tree build).
Sorry for not working. The steps might be run the lx-dw command
first, then step the kernel in gdb; the kernel status would be dump
to files in /tmp. Then you can run lx-dw.sh that creates 3 xterm window
to display registers, back trace and watch variables.


 Anyway, let's try to understand what you would like to achieve. This
 seems to be some add-on tool for gdb debugging sessions to display
 target states continuously in separate terminals. Right? Is this
 comparable to gdb's tui mode?

Yes, it is similar feature; dumps the content of register and kernel
status into a separate window continuously and highlight the difference.
It's snapshot is here:
https://www.dropbox.com/s/tl67sxm6474jd8i/dw-screenshot.png?dl=0

 More important, is this specific to the debugging infrastructure we have
 in scripts/gdb? Or could I install it (after some modifications, I
 guess) in my home directory and use it for any gdb session, not just
 with Linux kernels? Is there anything in it that particularly refers to
 Linux structures? In that case I would suggest to make it stand-alone
 first so that one could easily include it whenever needed, either
 explicitly or via ~/.gitinit.

This is not under the infrastructure of kernel gdb, however, this feature
is needed and specific for kernel debugging. When trace an optimized kernel
source, we usually need to trace it in assembly and throught the data window
to update the current kernel status. It can be standalone, but I think it may
helps a lot when developing kernel and good to be part of kernel gdb scripts.

best regards,
Houcheng Lin


 Thanks for sharing in any case!

 Jan




-- 
Best regards,
Houcheng Lin
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH] scripts/gdb: add data window feature

2015-07-16 Thread Houcheng Lin
Add data window feature to show current kernel status
on separate consoles, including: 1) registers, 2) back
trace and 3) watch data windows.

The data window would help kernel developer to understand
current hardware/ kernel status, and on single-stepping, the
modified fields in the data window would be highlighted.

Signed-off-by: Houcheng Lin 
---
 Documentation/gdb-kernel-debugging.txt |   9 ++
 scripts/gdb/linux/dw.py| 234 +
 scripts/gdb/linux/lx-dw.py |  53 
 scripts/gdb/vmlinux-gdb.py |   1 +
 scripts/lx-dw.sh   |   4 +
 5 files changed, 301 insertions(+)
 create mode 100644 scripts/gdb/linux/dw.py
 create mode 100644 scripts/gdb/linux/lx-dw.py
 create mode 100755 scripts/lx-dw.sh

diff --git a/Documentation/gdb-kernel-debugging.txt 
b/Documentation/gdb-kernel-debugging.txt
index 7050ce8..b74ecff 100644
--- a/Documentation/gdb-kernel-debugging.txt
+++ b/Documentation/gdb-kernel-debugging.txt
@@ -139,6 +139,14 @@ Examples of using the Linux-provided gdb helpers
   start_comm = "swapper/2\000\000\000\000\000\000"
 }
 
+ o Enable the debugging data window feature in GDB, then run lx-dw.sh script
+   to create three xterm console on desktop to display the CPU registers,
+   back trace and variables.
+(gdb) lx-dw
+(gdb) lx-add p $lx_current().comm
+(gdb) lx-add x/8x $rsp
+(gdb) lx-add x/8i $rip
+
 
 List of commands and functions
 --
@@ -153,6 +161,7 @@ this is just a snapshot of the initial version:
  function lx_task_by_pid -- Find Linux task by PID and return the task_struct 
variable
  function lx_thread_info -- Calculate Linux thread_info from task variable
  lx-dmesg -- Print Linux kernel log buffer
+ lx-dw -- Enable GDB data window feature
  lx-lsmod -- List currently loaded modules
  lx-symbols -- (Re-)load symbols of Linux kernel and currently loaded modules
 
diff --git a/scripts/gdb/linux/dw.py b/scripts/gdb/linux/dw.py
new file mode 100644
index 000..9d78bb3
--- /dev/null
+++ b/scripts/gdb/linux/dw.py
@@ -0,0 +1,234 @@
+#
+# gdb data window feature for Linux kernel debugging
+#
+#
+# Authors:
+#  Houcheng Lin 
+#
+# This work is licensed under the terms of the GNU GPL version 2.
+#
+
+from __future__ import with_statement
+from __future__ import print_function
+
+import gdb
+
+
+class CmdWindow:
+def __init__(self, file, cmd, DecoClass):
+self.cmd = cmd
+self.file = file
+self.decowin = DecoClass(file)
+def refresh(self, events):
+try:
+regstr = gdb.execute(self.cmd, False, True)
+except:
+regstr = 'Exception on instruction:%s' % cmd
+v = self.decowin.parse(regstr)
+self.decowin.update(v)
+self.decowin.refresh()
+
+class DecoWindow:
+def __init__(self, filename):
+self.filename = filename
+self.file = None
+self.pre = {}
+self.pre2 = {}
+def insertLine(self, i, v, prev):
+if self.file == None:
+self.file = open(self.filename, 'w')
+if v == prev:
+print(v , file=self.file)
+else:
+print('@@' + v, file=self.file)
+self.file.flush()
+def update(self, valuelist):
+for (i, v) in valuelist:
+try:
+prevalue = self.pre[i]
+except:
+prevalue = None
+self.insertLine(i, v, prevalue)
+self.pre2[i] = v
+def parse(self, regstr):
+vlist = []
+for line in regstr.split('\n'):
+if len(line.strip()) == 0:
+continue
+vlist.append((line.split()[0], line))
+return vlist
+def refresh(self):
+if self.file == None:
+self.file = open(self.filename, 'w')
+self.file.close()
+self.file = None
+self.pre = self.pre2
+self.pre2 = {}
+
+
+def findRegAnnotate(regstr):
+b = regstr.find('<')
+if b > 0:
+return regstr[b:regstr.find('>') + 1]
+b = regstr.find('[')
+if b > 0:
+return regstr[b:regstr.find(']') + 1]
+
+
+class RegDecoWindow(DecoWindow):
+def __init__(self, filename):
+DecoWindow.__init__(self, filename)
+def insertLine(self, i, v, prev):
+if self.file == None:
+self.file = open(self.filename, 'w')
+ann = findRegAnnotate(v)
+if v == prev:
+prefix = '\r'
+else:
+prefix = '\r@@'
+if ann != None:
+output = prefix + i + '\t' + v.split()[1] + '///\t' + ann
+else:
+output = prefix + i + '\t' + v.split()[1]
+print(output, file=self.file)
+self.file.flush()
+
+'''
+  decorate bt output string
+'''
+class BtDecoWindow(DecoWindow):
+def __init__(self, filename):
+DecoWindow.__init__(self, filename)
+def parse(self, regstr):
+vlist = []
+  

[RFC PATCH] scripts/gdb: add data window feature

2015-07-16 Thread Houcheng Lin
Add data window feature to show current kernel status
on separate consoles, including: 1) registers, 2) back
trace and 3) watch data windows.

The data window would help kernel developer to understand
current hardware/ kernel status, and on single-stepping, the
modified fields in the data window would be highlighted.

Signed-off-by: Houcheng Lin houch...@gmail.com
---
 Documentation/gdb-kernel-debugging.txt |   9 ++
 scripts/gdb/linux/dw.py| 234 +
 scripts/gdb/linux/lx-dw.py |  53 
 scripts/gdb/vmlinux-gdb.py |   1 +
 scripts/lx-dw.sh   |   4 +
 5 files changed, 301 insertions(+)
 create mode 100644 scripts/gdb/linux/dw.py
 create mode 100644 scripts/gdb/linux/lx-dw.py
 create mode 100755 scripts/lx-dw.sh

diff --git a/Documentation/gdb-kernel-debugging.txt 
b/Documentation/gdb-kernel-debugging.txt
index 7050ce8..b74ecff 100644
--- a/Documentation/gdb-kernel-debugging.txt
+++ b/Documentation/gdb-kernel-debugging.txt
@@ -139,6 +139,14 @@ Examples of using the Linux-provided gdb helpers
   start_comm = swapper/2\000\000\000\000\000\000
 }
 
+ o Enable the debugging data window feature in GDB, then run lx-dw.sh script
+   to create three xterm console on desktop to display the CPU registers,
+   back trace and variables.
+(gdb) lx-dw
+(gdb) lx-add p $lx_current().comm
+(gdb) lx-add x/8x $rsp
+(gdb) lx-add x/8i $rip
+
 
 List of commands and functions
 --
@@ -153,6 +161,7 @@ this is just a snapshot of the initial version:
  function lx_task_by_pid -- Find Linux task by PID and return the task_struct 
variable
  function lx_thread_info -- Calculate Linux thread_info from task variable
  lx-dmesg -- Print Linux kernel log buffer
+ lx-dw -- Enable GDB data window feature
  lx-lsmod -- List currently loaded modules
  lx-symbols -- (Re-)load symbols of Linux kernel and currently loaded modules
 
diff --git a/scripts/gdb/linux/dw.py b/scripts/gdb/linux/dw.py
new file mode 100644
index 000..9d78bb3
--- /dev/null
+++ b/scripts/gdb/linux/dw.py
@@ -0,0 +1,234 @@
+#
+# gdb data window feature for Linux kernel debugging
+#
+#
+# Authors:
+#  Houcheng Lin houch...@gmail.com
+#
+# This work is licensed under the terms of the GNU GPL version 2.
+#
+
+from __future__ import with_statement
+from __future__ import print_function
+
+import gdb
+
+
+class CmdWindow:
+def __init__(self, file, cmd, DecoClass):
+self.cmd = cmd
+self.file = file
+self.decowin = DecoClass(file)
+def refresh(self, events):
+try:
+regstr = gdb.execute(self.cmd, False, True)
+except:
+regstr = 'Exception on instruction:%s' % cmd
+v = self.decowin.parse(regstr)
+self.decowin.update(v)
+self.decowin.refresh()
+
+class DecoWindow:
+def __init__(self, filename):
+self.filename = filename
+self.file = None
+self.pre = {}
+self.pre2 = {}
+def insertLine(self, i, v, prev):
+if self.file == None:
+self.file = open(self.filename, 'w')
+if v == prev:
+print(v , file=self.file)
+else:
+print('@@' + v, file=self.file)
+self.file.flush()
+def update(self, valuelist):
+for (i, v) in valuelist:
+try:
+prevalue = self.pre[i]
+except:
+prevalue = None
+self.insertLine(i, v, prevalue)
+self.pre2[i] = v
+def parse(self, regstr):
+vlist = []
+for line in regstr.split('\n'):
+if len(line.strip()) == 0:
+continue
+vlist.append((line.split()[0], line))
+return vlist
+def refresh(self):
+if self.file == None:
+self.file = open(self.filename, 'w')
+self.file.close()
+self.file = None
+self.pre = self.pre2
+self.pre2 = {}
+
+
+def findRegAnnotate(regstr):
+b = regstr.find('')
+if b  0:
+return regstr[b:regstr.find('') + 1]
+b = regstr.find('[')
+if b  0:
+return regstr[b:regstr.find(']') + 1]
+
+
+class RegDecoWindow(DecoWindow):
+def __init__(self, filename):
+DecoWindow.__init__(self, filename)
+def insertLine(self, i, v, prev):
+if self.file == None:
+self.file = open(self.filename, 'w')
+ann = findRegAnnotate(v)
+if v == prev:
+prefix = '\r'
+else:
+prefix = '\r@@'
+if ann != None:
+output = prefix + i + '\t' + v.split()[1] + '///\t' + ann
+else:
+output = prefix + i + '\t' + v.split()[1]
+print(output, file=self.file)
+self.file.flush()
+
+'''
+  decorate bt output string
+'''
+class BtDecoWindow(DecoWindow):
+def __init__(self, filename):
+DecoWindow.__init__(self, filename)
+def parse(self, regstr):
+vlist

Re: [PATCH v2] netfilter: release skbuf when nlmsg put fail

2014-10-14 Thread Houcheng Lin
2014-10-14 18:49 GMT+08:00 Florian Westphal :
> Houcheng Lin  wrote:
>> When system is under heavy loading, the __nfulnl_send() may may failed
>> to put nlmsg into skbuf of nfulnl_instance. If not clear the skbuff on 
>> failed,
>> the __nfulnl_send() will still try to put next nlmsg onto this half-full 
>> skbuf
>> and cause the user program can never receive packet.
>>
>> This patch fix this issue by releasing skbuf immediately after nlmst put
>> failed.
>
> Could you please try this patch on top of this one and see if the
> WARN_ON goes away?
>
> Thanks
>
> diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
> --- a/net/netfilter/nfnetlink_log.c
> +++ b/net/netfilter/nfnetlink_log.c
> @@ -649,7 +649,8 @@ nfulnl_log_packet(struct net *net,
> + nla_total_size(sizeof(u_int32_t)) /* gid */
> + nla_total_size(plen)  /* prefix */
> + nla_total_size(sizeof(struct nfulnl_msg_packet_hw))
> -   + nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp));
> +   + nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp))
> +   + nla_total_size(sizeof(struct nfgenmsg));  /* NLMSG_DONE 
> */
>
> if (in && skb_mac_header_was_set(skb)) {
> size +=   nla_total_size(skb->dev->hard_header_len)
> @@ -692,8 +693,7 @@ nfulnl_log_packet(struct net *net,
> goto unlock_and_release;
> }
>
> -   if (inst->skb &&
> -   size > skb_tailroom(inst->skb) - sizeof(struct nfgenmsg)) {
> +   if (inst->skb && size > skb_tailroom(inst->skb)) {
> /* either the queue len is too high or we don't have
>  * enough room in the skb left. flush to userspace. */
> __nfulnl_flush(inst);
Hi Florian,
The modified code seems won't affect the program flow: Size is add a
extra value,
sizeof(struct nfgenmsg), during initialization. comparison size with tailroom
space, the right-side value also add the same value. Is there anything
I miss or
not understand ?

-- 
Best regards,
Houcheng Lin
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] netfilter: release skbuf when nlmsg put fail

2014-10-14 Thread Houcheng Lin
When system is under heavy loading, the __nfulnl_send() may may failed
to put nlmsg into skbuf of nfulnl_instance. If not clear the skbuff on failed,
the __nfulnl_send() will still try to put next nlmsg onto this half-full skbuf
and cause the user program can never receive packet.

This patch fix this issue by releasing skbuf immediately after nlmst put
failed.

Signed-off-by: Houcheng Lin 
---
 net/netfilter/nfnetlink_log.c |8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index a11c5ff..0ad5d32 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -353,15 +353,17 @@ __nfulnl_send(struct nfulnl_instance *inst)
  NLMSG_DONE,
  sizeof(struct nfgenmsg),
  0);
- if (!nlh)
+ if (!nlh) {
+ WARN_ON(1);
+ kfree_skb(inst->skb);
  goto out;
+ }
  }
  status = nfnetlink_unicast(inst->skb, inst->net, inst->peer_portid,
MSG_DONTWAIT);
-
+out:
  inst->qlen = 0;
  inst->skb = NULL;
-out:
  return status;
 }

-- 
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] netfilter: release skbuf when nlmsg put fail

2014-10-14 Thread Houcheng Lin
Hi Florian:
Please see my replies below.

2014-10-13 19:42 GMT+08:00 Florian Westphal :
> Houcheng Lin  wrote:
>> When system is under heavy loading, the __nfulnl_send() may may failed
>> to put nlmsg into skbuf of nfulnl_instance. If not clear the skbuff on 
>> failed,
>> the __nfulnl_send() will still try to put next nlmsg onto this half-full 
>> skbuf
>> and cause the user program can never receive packet.
>>
>> This patch fix this issue by releasing skbuf immediately after nlmst put
>> failed.
>
> Did you observe such problem or is this based on code reading?
> I ask because nflog should make sure we always have enough room left in
> skb to append a done message, see nfulnl_log_packet():

I observe this problem as my user mode program can not received any packet
on receive() function after bursts of packets. After this patch, my user mode
program can always receive packet.

>
> if (inst->skb &&
> size > skb_tailroom(inst->skb) - sizeof(struct nfgenmsg)) {
> /* flush skb */

I agree with you. The code had check skb lefting space before sending.
Not sure where was wrong.

>
> Your patch fixes such 'can never send' skb condition by leaking the
> skb.  So at the very least you would need to call kfree_skb(), and
> perhaps also add WARN_ON() so we catch this and can fix up the size
> accounting?

Sorry for not releasing the skb buffer. I modified my code to call kfree_skb on
put failure and call a WARN_ON(1).

A) Below is WARN_ON log that repeatly inserted into syslog when heavy loading:

[  531.877328] [ cut here ]
[  531.877338] WARNING: CPU: 2 PID: 4133 at
net/netfilter/nfnetlink_log.c:357 __nfulnl_send+0x91/0xb0
[nfnetlink_log]()
[  531.877340] Modules linked in: nfnetlink_log ebt_nflog ebt_ip
ebtable_filter vhost_net vhost tun ebtable_nat kvm_intel kvm r8169
[  531.877352] CPU: 2 PID: 4133 Comm: vhost-4131 Tainted: GW
   3.17.0-rc6+ #3
[  531.877354] Hardware name: Gigabyte Technology Co., Ltd.
EP43-UD3L/EP43-UD3L, BIOS F6 08/31/2009
[  531.877356]  0165 88023fd038a8 8183177b
0007
[  531.877359]   88023fd038e8 8104c877
8802361b4000
[  531.877362]  8802213bc600 0338 88023fd03b6c
8800834a7e00
[  531.877366] Call Trace:
[  531.877368][] dump_stack+0x46/0x58
[  531.877377]  [] warn_slowpath_common+0x87/0xb0
[  531.877380]  [] warn_slowpath_null+0x15/0x20
[  531.877384]  [] __nfulnl_send+0x91/0xb0 [nfnetlink_log]
[  531.877387]  [] __nfulnl_flush+0x28/0x40 [nfnetlink_log]
[  531.877390]  [] nfulnl_log_packet+0x2ce/0x84c
[nfnetlink_log]
[  531.877395]  [] nf_log_packet+0xda/0x110
[  531.877400]  [] ? map_single+0x19/0x20
[  531.877403]  [] ? swiotlb_map_page+0x93/0x160
[  531.877408]  [] ? rtl8169_start_xmit+0x1c3/0x7c0 [r8169]
[  531.877412]  [] ebt_nflog_tg+0x68/0x7c [ebt_nflog]
[  531.877417]  [] ebt_do_table+0x53a/0x700
[  531.877421]  [] ? br_dev_queue_push_xmit+0x60/0x60
[  531.877424]  [] ebt_in_hook+0x1a/0x1c [ebtable_filter]
[  531.877428]  [] nf_iterate+0x86/0xc0
[  531.877431]  [] ? br_dev_queue_push_xmit+0x60/0x60
[  531.877434]  [] nf_hook_slow+0x75/0x150
[  531.877437]  [] ? br_dev_queue_push_xmit+0x60/0x60
[  531.877440]  [] __br_forward+0x7d/0xc0
[  531.877443]  [] br_forward+0x55/0x60
[  531.877446]  [] br_handle_frame_finish+0x147/0x350
[  531.877449]  [] br_handle_frame+0x198/0x250
[  531.877452]  [] ? br_handle_frame_finish+0x350/0x350
[  531.877456]  [] __netif_receive_skb_core+0x196/0x700
[  531.877459]  [] ? enqueue_hrtimer+0x39/0xc0
[  531.877462]  [] __netif_receive_skb+0x21/0x70
[  531.877465]  [] process_backlog+0x7f/0x150
[  531.877468]  [] net_rx_action+0x109/0x200
[  531.877471]  [] __do_softirq+0xe8/0x2e0
[  531.877476]  [] do_softirq_own_stack+0x1c/0x30
[  531.877477][] do_softirq+0x35/0x40
[  531.877482]  [] netif_rx_ni+0x41/0x90
[  531.877486]  [] tun_get_user+0x3dc/0x860 [tun]
[  531.877490]  [] ? vhost_get_vq_desc+0x223/0x3e0 [vhost]
[  531.877494]  [] tun_sendmsg+0x52/0x80 [tun]
[  531.877497]  [] handle_tx+0x240/0x420 [vhost_net]
[  531.877501]  [] handle_tx_kick+0x10/0x20 [vhost_net]
[  531.877505]  [] vhost_worker+0xff/0x1c0 [vhost]
[  531.877508]  [] ?
vhost_attach_cgroups_work+0x30/0x30 [vhost]
[  531.877511]  [] kthread+0xc4/0xe0
[  531.877515]  [] ? flush_kthread_worker+0x90/0x90
[  531.877518]  [] ret_from_fork+0x7c/0xb0
[  531.877521]  [] ? flush_kthread_worker+0x90/0x90
[  531.877523] ---[ end trace 4e280f9febf1c04d ]---

B) My ebtable settings to trigger this bug:
-p IPv4 --ip-src 192.168.122.229 --ip-proto tcp --nflog-prefix
"1"--nflog-group 1 --nflog-range 65535 --nflog-threshold 20 -j
ACCEPT
-p IPv4 --ip-dst 192.168.122.229 --ip-proto tcp --nflog-prefix
"1"--nflog-group 1 --nflog-range 65535 --nflog-threshold 20 -j
ACCEPT
-p IPv4 --ip-src 192.168.122.222 --ip-proto tcp --n

Re: [PATCH] netfilter: release skbuf when nlmsg put fail

2014-10-14 Thread Houcheng Lin
Hi Florian:
Please see my replies below.

2014-10-13 19:42 GMT+08:00 Florian Westphal f...@strlen.de:
 Houcheng Lin houch...@gmail.com wrote:
 When system is under heavy loading, the __nfulnl_send() may may failed
 to put nlmsg into skbuf of nfulnl_instance. If not clear the skbuff on 
 failed,
 the __nfulnl_send() will still try to put next nlmsg onto this half-full 
 skbuf
 and cause the user program can never receive packet.

 This patch fix this issue by releasing skbuf immediately after nlmst put
 failed.

 Did you observe such problem or is this based on code reading?
 I ask because nflog should make sure we always have enough room left in
 skb to append a done message, see nfulnl_log_packet():

I observe this problem as my user mode program can not received any packet
on receive() function after bursts of packets. After this patch, my user mode
program can always receive packet.


 if (inst-skb 
 size  skb_tailroom(inst-skb) - sizeof(struct nfgenmsg)) {
 /* flush skb */

I agree with you. The code had check skb lefting space before sending.
Not sure where was wrong.


 Your patch fixes such 'can never send' skb condition by leaking the
 skb.  So at the very least you would need to call kfree_skb(), and
 perhaps also add WARN_ON() so we catch this and can fix up the size
 accounting?

Sorry for not releasing the skb buffer. I modified my code to call kfree_skb on
put failure and call a WARN_ON(1).

A) Below is WARN_ON log that repeatly inserted into syslog when heavy loading:

[  531.877328] [ cut here ]
[  531.877338] WARNING: CPU: 2 PID: 4133 at
net/netfilter/nfnetlink_log.c:357 __nfulnl_send+0x91/0xb0
[nfnetlink_log]()
[  531.877340] Modules linked in: nfnetlink_log ebt_nflog ebt_ip
ebtable_filter vhost_net vhost tun ebtable_nat kvm_intel kvm r8169
[  531.877352] CPU: 2 PID: 4133 Comm: vhost-4131 Tainted: GW
   3.17.0-rc6+ #3
[  531.877354] Hardware name: Gigabyte Technology Co., Ltd.
EP43-UD3L/EP43-UD3L, BIOS F6 08/31/2009
[  531.877356]  0165 88023fd038a8 8183177b
0007
[  531.877359]   88023fd038e8 8104c877
8802361b4000
[  531.877362]  8802213bc600 0338 88023fd03b6c
8800834a7e00
[  531.877366] Call Trace:
[  531.877368]  IRQ  [8183177b] dump_stack+0x46/0x58
[  531.877377]  [8104c877] warn_slowpath_common+0x87/0xb0
[  531.877380]  [8104c8b5] warn_slowpath_null+0x15/0x20
[  531.877384]  [a00e4161] __nfulnl_send+0x91/0xb0 [nfnetlink_log]
[  531.877387]  [a00e4508] __nfulnl_flush+0x28/0x40 [nfnetlink_log]
[  531.877390]  [a00e4dbe] nfulnl_log_packet+0x2ce/0x84c
[nfnetlink_log]
[  531.877395]  [81693d9a] nf_log_packet+0xda/0x110
[  531.877400]  [8130f029] ? map_single+0x19/0x20
[  531.877403]  [8130f1e3] ? swiotlb_map_page+0x93/0x160
[  531.877408]  [a0008c23] ? rtl8169_start_xmit+0x1c3/0x7c0 [r8169]
[  531.877412]  [a00e0088] ebt_nflog_tg+0x68/0x7c [ebt_nflog]
[  531.877417]  [81773afa] ebt_do_table+0x53a/0x700
[  531.877421]  [81765660] ? br_dev_queue_push_xmit+0x60/0x60
[  531.877424]  [a00d80ba] ebt_in_hook+0x1a/0x1c [ebtable_filter]
[  531.877428]  [816934c6] nf_iterate+0x86/0xc0
[  531.877431]  [81765660] ? br_dev_queue_push_xmit+0x60/0x60
[  531.877434]  [81693575] nf_hook_slow+0x75/0x150
[  531.877437]  [81765660] ? br_dev_queue_push_xmit+0x60/0x60
[  531.877440]  [8176573d] __br_forward+0x7d/0xc0
[  531.877443]  [817658f5] br_forward+0x55/0x60
[  531.877446]  [81766637] br_handle_frame_finish+0x147/0x350
[  531.877449]  [817669d8] br_handle_frame+0x198/0x250
[  531.877452]  [81766840] ? br_handle_frame_finish+0x350/0x350
[  531.877456]  [816633b6] __netif_receive_skb_core+0x196/0x700
[  531.877459]  [8109f639] ? enqueue_hrtimer+0x39/0xc0
[  531.877462]  [81663941] __netif_receive_skb+0x21/0x70
[  531.877465]  [81663a0f] process_backlog+0x7f/0x150
[  531.877468]  [816641c9] net_rx_action+0x109/0x200
[  531.877471]  [8104fe08] __do_softirq+0xe8/0x2e0
[  531.877476]  [8183cddc] do_softirq_own_stack+0x1c/0x30
[  531.877477]  EOI  [81050075] do_softirq+0x35/0x40
[  531.877482]  [81662ed1] netif_rx_ni+0x41/0x90
[  531.877486]  [a00bf96c] tun_get_user+0x3dc/0x860 [tun]
[  531.877490]  [a00c9483] ? vhost_get_vq_desc+0x223/0x3e0 [vhost]
[  531.877494]  [a00bfe42] tun_sendmsg+0x52/0x80 [tun]
[  531.877497]  [a00d1d80] handle_tx+0x240/0x420 [vhost_net]
[  531.877501]  [a00d1f90] handle_tx_kick+0x10/0x20 [vhost_net]
[  531.877505]  [a00c8a6f] vhost_worker+0xff/0x1c0 [vhost]
[  531.877508]  [a00c8970] ?
vhost_attach_cgroups_work+0x30/0x30 [vhost]
[  531.877511]  [810679e4] kthread+0xc4/0xe0
[  531.877515]  [81067920] ? flush_kthread_worker+0x90

[PATCH v2] netfilter: release skbuf when nlmsg put fail

2014-10-14 Thread Houcheng Lin
When system is under heavy loading, the __nfulnl_send() may may failed
to put nlmsg into skbuf of nfulnl_instance. If not clear the skbuff on failed,
the __nfulnl_send() will still try to put next nlmsg onto this half-full skbuf
and cause the user program can never receive packet.

This patch fix this issue by releasing skbuf immediately after nlmst put
failed.

Signed-off-by: Houcheng Lin houch...@gmail.com
---
 net/netfilter/nfnetlink_log.c |8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index a11c5ff..0ad5d32 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -353,15 +353,17 @@ __nfulnl_send(struct nfulnl_instance *inst)
  NLMSG_DONE,
  sizeof(struct nfgenmsg),
  0);
- if (!nlh)
+ if (!nlh) {
+ WARN_ON(1);
+ kfree_skb(inst-skb);
  goto out;
+ }
  }
  status = nfnetlink_unicast(inst-skb, inst-net, inst-peer_portid,
MSG_DONTWAIT);
-
+out:
  inst-qlen = 0;
  inst-skb = NULL;
-out:
  return status;
 }

-- 
1.7.9.5
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] netfilter: release skbuf when nlmsg put fail

2014-10-14 Thread Houcheng Lin
2014-10-14 18:49 GMT+08:00 Florian Westphal f...@strlen.de:
 Houcheng Lin houch...@gmail.com wrote:
 When system is under heavy loading, the __nfulnl_send() may may failed
 to put nlmsg into skbuf of nfulnl_instance. If not clear the skbuff on 
 failed,
 the __nfulnl_send() will still try to put next nlmsg onto this half-full 
 skbuf
 and cause the user program can never receive packet.

 This patch fix this issue by releasing skbuf immediately after nlmst put
 failed.

 Could you please try this patch on top of this one and see if the
 WARN_ON goes away?

 Thanks

 diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
 --- a/net/netfilter/nfnetlink_log.c
 +++ b/net/netfilter/nfnetlink_log.c
 @@ -649,7 +649,8 @@ nfulnl_log_packet(struct net *net,
 + nla_total_size(sizeof(u_int32_t)) /* gid */
 + nla_total_size(plen)  /* prefix */
 + nla_total_size(sizeof(struct nfulnl_msg_packet_hw))
 -   + nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp));
 +   + nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp))
 +   + nla_total_size(sizeof(struct nfgenmsg));  /* NLMSG_DONE 
 */

 if (in  skb_mac_header_was_set(skb)) {
 size +=   nla_total_size(skb-dev-hard_header_len)
 @@ -692,8 +693,7 @@ nfulnl_log_packet(struct net *net,
 goto unlock_and_release;
 }

 -   if (inst-skb 
 -   size  skb_tailroom(inst-skb) - sizeof(struct nfgenmsg)) {
 +   if (inst-skb  size  skb_tailroom(inst-skb)) {
 /* either the queue len is too high or we don't have
  * enough room in the skb left. flush to userspace. */
 __nfulnl_flush(inst);
Hi Florian,
The modified code seems won't affect the program flow: Size is add a
extra value,
sizeof(struct nfgenmsg), during initialization. comparison size with tailroom
space, the right-side value also add the same value. Is there anything
I miss or
not understand ?

-- 
Best regards,
Houcheng Lin
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] netfilter: release skbuf when nlmsg put fail

2014-10-13 Thread Houcheng Lin
When system is under heavy loading, the __nfulnl_send() may may failed
to put nlmsg into skbuf of nfulnl_instance. If not clear the skbuff on failed,
the __nfulnl_send() will still try to put next nlmsg onto this half-full skbuf
and cause the user program can never receive packet.

This patch fix this issue by releasing skbuf immediately after nlmst put
failed.

Signed-off-by: Houcheng Lin 

---
 net/netfilter/nfnetlink_log.c |3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index a11c5ff..0cb9ede 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -358,10 +358,9 @@ __nfulnl_send(struct nfulnl_instance *inst)
 }
 status = nfnetlink_unicast(inst->skb, inst->net, inst->peer_portid,
MSG_DONTWAIT);
-
+out:
 inst->qlen = 0;
 inst->skb = NULL;
-out:
 return status;
 }

-- 
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] netfilter: release skbuf when nlmsg put fail

2014-10-13 Thread Houcheng Lin
When system is under heavy loading, the __nfulnl_send() may may failed
to put nlmsg into skbuf of nfulnl_instance. If not clear the skbuff on failed,
the __nfulnl_send() will still try to put next nlmsg onto this half-full skbuf
and cause the user program can never receive packet.

This patch fix this issue by releasing skbuf immediately after nlmst put
failed.

Signed-off-by: Houcheng Lin houch...@gmail.com

---
 net/netfilter/nfnetlink_log.c |3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index a11c5ff..0cb9ede 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -358,10 +358,9 @@ __nfulnl_send(struct nfulnl_instance *inst)
 }
 status = nfnetlink_unicast(inst-skb, inst-net, inst-peer_portid,
MSG_DONTWAIT);
-
+out:
 inst-qlen = 0;
 inst-skb = NULL;
-out:
 return status;
 }

-- 
1.7.9.5
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH v3] reset: Add a defer reset object to send board specific reset

2014-06-18 Thread Houcheng Lin
The Problem
---
The reset signal on a hardware board is send either:
- during machine initialization
- during bus master's initialization

In some hardware design, devices on bus need a non-standard and extra reset
signal after bus is initialied. Most reason is to wake up device from hanging
state.

The board spefic reset code can not be put into machine init code, as it is
too early. This code can not also be put onto chip's driver, as it is board
specific and not suitable for a common chip driver.

Defer Reset Object
--
The defer reset object is to resolve this issue, developer can put a defer-
reset device on the board's dts file and enable DEFER RESET OBJECT CONFIG.
During driver init-calls, a defer-reset object is created and issue reset signal
after the enclosing device is initialized.

This eliminate the need to rewrite a driver module with only one purpose: 
sending
a board specific reset. This also allow mainstream kernel to support many boards
that modify the common drivers to send board specific reset. Configuring 
defer-reset
device in dts leave the board specific reset rules on board level and simple to
maintain.

Example dts File

Example 1:
defer_reset_vbus {
compatible = "defer-reset";
reset-gpios = < 5 GPIO_ACTIVE_LOW>;
duration = <5>;
};

Example 2:
defer_reset_vbus {
compatible = "defer-reset";
reset-gpios = < 5 GPIO_ACTIVE_HIGH>;
duration = <0>;
};

Block Diagram of dts File
-
+-+
| usb-ehci-chip@1211000   |
|   +-+   |
|   | defer-reset(gpx3)   |   |
|   +-+   |
+---------+

Signed-off-by: Houcheng Lin 
---
 .../devicetree/bindings/reset/gpio-defer-reset.txt |  30 
 drivers/reset/Kconfig  |   8 +
 drivers/reset/Makefile |   1 +
 drivers/reset/gpio-defer-reset.c   | 180 +
 4 files changed, 219 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/reset/gpio-defer-reset.txt
 create mode 100644 drivers/reset/gpio-defer-reset.c

diff --git a/Documentation/devicetree/bindings/reset/gpio-defer-reset.txt 
b/Documentation/devicetree/bindings/reset/gpio-defer-reset.txt
new file mode 100644
index 000..2ef416e
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/gpio-defer-reset.txt
@@ -0,0 +1,30 @@
+GPIO defer reset binding
+
+Put a defer-reset device in a device node and enable DEFER RESET OBJECT CONFIG.
+During driver init-calls, a defer-reset object will be created and issue reset
+signal after the enclosing device node's initialization complete.
+
+Required properties:
+- compatible:
+  - "defer-reset" for creating defer reset object
+- reset-gpio: specify gpio pin to send reset signal, GPIO_ACTIVE_LOW indicates
+  the reset signal is low and would revert line back to high.
+  It can be an array.
+- duration: specify reset signal duration in ms, 0 indicates hold the reset
+signal forever.
+It can be an array.
+
+Example 1:
+   defer_reset_vbus {
+   compatible = "defer-reset";
+   reset-gpios = < 5 GPIO_ACTIVE_LOW>;
+   duration = <5>;
+   };
+
+Example 2:
+   defer_reset_vbus {
+   compatible = "defer-reset";
+   reset-gpios = < 5 GPIO_ACTIVE_HIGH>;
+   duration = <0>;
+   };
+
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 0615f50..d53eb26 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -12,4 +12,12 @@ menuconfig RESET_CONTROLLER
 
  If unsure, say no.
 
+config GPIO_DEFER_RESET
+   bool "Defer reset driver via gpio"
+   depends on OF_GPIO
+   help
+ Enable defer reset drvier
+ The reset signal would be issued after a device on USB or PCI bus is 
initialied.
+ The dependency of reset signal and device can be specified in board's 
dts file.
+
 source "drivers/reset/sti/Kconfig"
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 4f60caf..a3fdfef 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_RESET_CONTROLLER) += core.o
 obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o
 obj-$(CONFIG_ARCH_STI) += sti/
+obj-$(CONFIG_GPIO_DEFER_RESET) += gpio-defer-reset.o
diff --git a/drivers/reset/gpio-defer-reset.c b/drivers/reset/gpio-defer-reset.c
new file mode 100644
index 000..e75ec14
--- /dev/null
+++ b/drivers/reset/gpio-defer-reset.c
@@ -0,0 +1,180 @@
+/*
+ * GPIO Defer Reset Driver
+ *
+ * Copyright (C) 2014 Houcheng Lin
+ * Author: Houcheng Lin 
+ *
+ * This program is free software; you can r

[RFC PATCH v3] reset: Add a defer reset object to send board specific reset

2014-06-18 Thread Houcheng Lin
The Problem
---
The reset signal on a hardware board is send either:
- during machine initialization
- during bus master's initialization

In some hardware design, devices on bus need a non-standard and extra reset
signal after bus is initialied. Most reason is to wake up device from hanging
state.

The board spefic reset code can not be put into machine init code, as it is
too early. This code can not also be put onto chip's driver, as it is board
specific and not suitable for a common chip driver.

Defer Reset Object
--
The defer reset object is to resolve this issue, developer can put a defer-
reset device on the board's dts file and enable DEFER RESET OBJECT CONFIG.
During driver init-calls, a defer-reset object is created and issue reset signal
after the enclosing device is initialized.

This eliminate the need to rewrite a driver module with only one purpose: 
sending
a board specific reset. This also allow mainstream kernel to support many boards
that modify the common drivers to send board specific reset. Configuring 
defer-reset
device in dts leave the board specific reset rules on board level and simple to
maintain.

Example dts File

Example 1:
defer_reset_vbus {
compatible = defer-reset;
reset-gpios = gpx3 5 GPIO_ACTIVE_LOW;
duration = 5;
};

Example 2:
defer_reset_vbus {
compatible = defer-reset;
reset-gpios = gpx3 5 GPIO_ACTIVE_HIGH;
duration = 0;
};

Block Diagram of dts File
-
+-+
| usb-ehci-chip@1211000   |
|   +-+   |
|   | defer-reset(gpx3)   |   |
|   +-+   |
+-+

Signed-off-by: Houcheng Lin houch...@gmail.com
---
 .../devicetree/bindings/reset/gpio-defer-reset.txt |  30 
 drivers/reset/Kconfig  |   8 +
 drivers/reset/Makefile |   1 +
 drivers/reset/gpio-defer-reset.c   | 180 +
 4 files changed, 219 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/reset/gpio-defer-reset.txt
 create mode 100644 drivers/reset/gpio-defer-reset.c

diff --git a/Documentation/devicetree/bindings/reset/gpio-defer-reset.txt 
b/Documentation/devicetree/bindings/reset/gpio-defer-reset.txt
new file mode 100644
index 000..2ef416e
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/gpio-defer-reset.txt
@@ -0,0 +1,30 @@
+GPIO defer reset binding
+
+Put a defer-reset device in a device node and enable DEFER RESET OBJECT CONFIG.
+During driver init-calls, a defer-reset object will be created and issue reset
+signal after the enclosing device node's initialization complete.
+
+Required properties:
+- compatible:
+  - defer-reset for creating defer reset object
+- reset-gpio: specify gpio pin to send reset signal, GPIO_ACTIVE_LOW indicates
+  the reset signal is low and would revert line back to high.
+  It can be an array.
+- duration: specify reset signal duration in ms, 0 indicates hold the reset
+signal forever.
+It can be an array.
+
+Example 1:
+   defer_reset_vbus {
+   compatible = defer-reset;
+   reset-gpios = gpx3 5 GPIO_ACTIVE_LOW;
+   duration = 5;
+   };
+
+Example 2:
+   defer_reset_vbus {
+   compatible = defer-reset;
+   reset-gpios = gpx3 5 GPIO_ACTIVE_HIGH;
+   duration = 0;
+   };
+
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 0615f50..d53eb26 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -12,4 +12,12 @@ menuconfig RESET_CONTROLLER
 
  If unsure, say no.
 
+config GPIO_DEFER_RESET
+   bool Defer reset driver via gpio
+   depends on OF_GPIO
+   help
+ Enable defer reset drvier
+ The reset signal would be issued after a device on USB or PCI bus is 
initialied.
+ The dependency of reset signal and device can be specified in board's 
dts file.
+
 source drivers/reset/sti/Kconfig
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 4f60caf..a3fdfef 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_RESET_CONTROLLER) += core.o
 obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o
 obj-$(CONFIG_ARCH_STI) += sti/
+obj-$(CONFIG_GPIO_DEFER_RESET) += gpio-defer-reset.o
diff --git a/drivers/reset/gpio-defer-reset.c b/drivers/reset/gpio-defer-reset.c
new file mode 100644
index 000..e75ec14
--- /dev/null
+++ b/drivers/reset/gpio-defer-reset.c
@@ -0,0 +1,180 @@
+/*
+ * GPIO Defer Reset Driver
+ *
+ * Copyright (C) 2014 Houcheng Lin
+ * Author: Houcheng Lin houch...@gmail.com
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published

Re: [RFC PATCH] gpio: Add a defer reset object to send board specific reset

2014-06-17 Thread Houcheng Lin
Hi,

2014-06-16 21:18 GMT+08:00 Ulf Hansson :
>
> If I understand correct, you need a per device reset functionality?
> And obviously the reset implementation is board/SoC specific.
>
> We have the "Reset Controller framework", drivers/reset. Could this help you?
>
> Kind regards
> Ulf Hansson
>

Thanks for your information. The defer reset object is to send
board specific reset signal and this signal has to be sent after
some device is intialized. For example, a USB device may need extra
reset signal after root hub is initialized.

As machine init code is run before driver init-call, can not add reset
sending here if it depends on a specific device's initialization.

Also it provides a DT node that helps both HW/SW developer to use this
feature.

Best regards,
Houcheng Lin
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] [RFC PATCH v2] power:reset: Add defer reset object to send board specific reset

2014-06-17 Thread Houcheng Lin
Hi,

2014-06-15 17:09 GMT+08:00 Sebastian Reichel :
>
> I think this belongs to drivers/reset and not to drivers/power/reset.
> The drivers in drivers/power/reset are about board reboot / shutdown.
> This driver seems to be used for periphals.

Yes, this driver is for pherphials and I think it is reasonble
to placed it at drivers/reset. I'll moved it in next release.

> Alternatively you could do this via the duration. An infinite long
> reset signal basically means, that the line is never changed back.
>
> To give a few examples for the above comments:
>
> /* keep "gpx3 5" low for 5ms, change back to high afterwards */
> defer_reset_vbus {
> compatible = "defer-reset";
> reset-gpios = < 5 GPIO_ACTIVE_LOW>;
> duration = <5>;
> };
>
> /* keep "gpx3 5" high for 5ms, change back to low afterwards */
> defer_reset_vbus {
> compatible = "defer-reset";
> reset-gpios = < 5 GPIO_ACTIVE_HIGH>;
> duration = <5>;
> };
>
> /* keep "gpx3 5" low */
> defer_reset_vbus {
> compatible = "defer-reset";
> reset-gpios = < 5 GPIO_ACTIVE_LOW>;
> duration = <0>;

These DT properties looks simpler and better: Use of GPIO_ACTIVE_HIGH
and GPIO_ACTIVE_LOW increase readability for HW/SW developer, use
of <0> to indicate holding the reset signal. I'll updated code according
on this. Thanks for your comments.

-- 
Best regards,
Houcheng Lin
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] [RFC PATCH v2] power:reset: Add defer reset object to send board specific reset

2014-06-17 Thread Houcheng Lin
Hi,

2014-06-15 17:09 GMT+08:00 Sebastian Reichel s...@kernel.org:

 I think this belongs to drivers/reset and not to drivers/power/reset.
 The drivers in drivers/power/reset are about board reboot / shutdown.
 This driver seems to be used for periphals.

Yes, this driver is for pherphials and I think it is reasonble
to placed it at drivers/reset. I'll moved it in next release.

 Alternatively you could do this via the duration. An infinite long
 reset signal basically means, that the line is never changed back.

 To give a few examples for the above comments:

 /* keep gpx3 5 low for 5ms, change back to high afterwards */
 defer_reset_vbus {
 compatible = defer-reset;
 reset-gpios = gpx3 5 GPIO_ACTIVE_LOW;
 duration = 5;
 };

 /* keep gpx3 5 high for 5ms, change back to low afterwards */
 defer_reset_vbus {
 compatible = defer-reset;
 reset-gpios = gpx3 5 GPIO_ACTIVE_HIGH;
 duration = 5;
 };

 /* keep gpx3 5 low */
 defer_reset_vbus {
 compatible = defer-reset;
 reset-gpios = gpx3 5 GPIO_ACTIVE_LOW;
 duration = 0;

These DT properties looks simpler and better: Use of GPIO_ACTIVE_HIGH
and GPIO_ACTIVE_LOW increase readability for HW/SW developer, use
of 0 to indicate holding the reset signal. I'll updated code according
on this. Thanks for your comments.

-- 
Best regards,
Houcheng Lin
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH] gpio: Add a defer reset object to send board specific reset

2014-06-17 Thread Houcheng Lin
Hi,

2014-06-16 21:18 GMT+08:00 Ulf Hansson ulf.hans...@linaro.org:

 If I understand correct, you need a per device reset functionality?
 And obviously the reset implementation is board/SoC specific.

 We have the Reset Controller framework, drivers/reset. Could this help you?

 Kind regards
 Ulf Hansson


Thanks for your information. The defer reset object is to send
board specific reset signal and this signal has to be sent after
some device is intialized. For example, a USB device may need extra
reset signal after root hub is initialized.

As machine init code is run before driver init-call, can not add reset
sending here if it depends on a specific device's initialization.

Also it provides a DT node that helps both HW/SW developer to use this
feature.

Best regards,
Houcheng Lin
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] [RFC PATCH v2] power:reset: Add defer reset object to send board specific reset

2014-06-15 Thread Houcheng Lin
The Problem
---
The reset signal on a hardware board is send either:
- during machine initialization
- during bus master's initialization

In some hardware design, devices on bus need a non-standard and extra reset
signal after bus is initialied. Most reason is to wake up device from hanging
state.

The board spefic reset code can not be put into machine init code, as it is
too early. This code can not also be put onto chip's driver, as it is board
specific and not suitable for a common chip driver.

Defer Reset Object
--
The defer reset object is to resolve this issue, developer can put a defer-
reset device on the board's dts file and enable DEFER RESET OBJECT CONFIG.
During driver init-calls, a defer-reset object is created and issue reset signal
after the enclosing device is initialized.

This eliminate the need to rewrite a driver module with only one purpose: 
sending
a board specific reset. This also allow mainstream kernel to support many boards
that modify the common drivers to send board specific reset. Configuring 
defer-reset
device in dts leave the board specific reset rules on board level and simple to
maintain.

Example dts File

usb-ehci-chip@1211000{
usb-phy = <_phy>;
defer_reset_vbus {
compatible = "defer-reset";
reset-gpios = < 5 1>;
reset-init = <0>;
reset-end = <1>;
delay = <5>;
};
};

Block Diagram of dts File
-
+-+
| usb-ehci-chip@1211000   |
|   +-+   |
|   | defer-reset(gpx3)   |   |
|   +-+   |
+---------+

Signed-off-by: Houcheng Lin 
---
 .../devicetree/bindings/gpio/gpio-defer-reset.txt  |  22 +++
 drivers/power/reset/Kconfig|   8 +
 drivers/power/reset/Makefile   |   1 +
 drivers/power/reset/gpio-defer-reset.c | 192 +
 4 files changed, 223 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-defer-reset.txt
 create mode 100644 drivers/power/reset/gpio-defer-reset.c

diff --git a/Documentation/devicetree/bindings/gpio/gpio-defer-reset.txt 
b/Documentation/devicetree/bindings/gpio/gpio-defer-reset.txt
new file mode 100644
index 000..5d55830
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-defer-reset.txt
@@ -0,0 +1,22 @@
+GPIO defer reset binding
+
+Put a defer-reset device in a device node and enable DEFER RESET OBJECT CONFIG.
+During driver init-calls, a defer-reset object will be created and issue reset
+signal after the enclosing device node's initialization complete.
+
+Required properties:
+- compatible:
+  - "defer-reset" for creating defer reset object
+- reset-gpio: specify gpio pin, can be an array.
+- reset-init: specify reset signal initial value, can be 0 or 1.
+- reset-end: specify reset signal end value, can be 0 or 1.
+- delay: specify reset duration in ms.
+
+Example:
+   defer_reset_vbus {
+   compatible = "defer-reset";
+   reset-gpios = < 5 1>;
+   reset-init = <0>;
+   reset-end = <1>;
+   delay = <5>;
+   };
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index fa0e4e0..74b7eb0 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -57,3 +57,11 @@ config POWER_RESET_XGENE
depends on POWER_RESET
help
  Reboot support for the APM SoC X-Gene Eval boards.
+
+config GPIO_DEFER_RESET
+   bool "Defer reset driver via gpio"
+   depends on OF_GPIO && POWER_RESET
+   help
+ Enable defer reset drvier
+ The reset signal would be issued after a device on USB or PCI bus is 
initialied.
+ The dependency of reset signal and device can be specified in board's 
dts file.
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index a5b4a77..166baf9 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o
 obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o
 obj-$(CONFIG_POWER_RESET_VEXPRESS) += vexpress-poweroff.o
 obj-$(CONFIG_POWER_RESET_XGENE) += xgene-reboot.o
+obj-$(CONFIG_GPIO_DEFER_RESET) += gpio-defer-reset.o
diff --git a/drivers/power/reset/gpio-defer-reset.c 
b/drivers/power/reset/gpio-defer-reset.c
new file mode 100644
index 000..6425519
--- /dev/null
+++ b/drivers/power/reset/gpio-defer-reset.c
@@ -0,0 +1,192 @@
+/*
+ * GPIO Defer Reset Driver
+ *
+ * Copyright (C) 2014 Houcheng Lin
+ * Author: Houcheng Lin 
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public Li

[PATCH] [RFC PATCH v2] power:reset: Add defer reset object to send board specific reset

2014-06-15 Thread Houcheng Lin
The Problem
---
The reset signal on a hardware board is send either:
- during machine initialization
- during bus master's initialization

In some hardware design, devices on bus need a non-standard and extra reset
signal after bus is initialied. Most reason is to wake up device from hanging
state.

The board spefic reset code can not be put into machine init code, as it is
too early. This code can not also be put onto chip's driver, as it is board
specific and not suitable for a common chip driver.

Defer Reset Object
--
The defer reset object is to resolve this issue, developer can put a defer-
reset device on the board's dts file and enable DEFER RESET OBJECT CONFIG.
During driver init-calls, a defer-reset object is created and issue reset signal
after the enclosing device is initialized.

This eliminate the need to rewrite a driver module with only one purpose: 
sending
a board specific reset. This also allow mainstream kernel to support many boards
that modify the common drivers to send board specific reset. Configuring 
defer-reset
device in dts leave the board specific reset rules on board level and simple to
maintain.

Example dts File

usb-ehci-chip@1211000{
usb-phy = usb2_phy;
defer_reset_vbus {
compatible = defer-reset;
reset-gpios = gpx3 5 1;
reset-init = 0;
reset-end = 1;
delay = 5;
};
};

Block Diagram of dts File
-
+-+
| usb-ehci-chip@1211000   |
|   +-+   |
|   | defer-reset(gpx3)   |   |
|   +-+   |
+-+

Signed-off-by: Houcheng Lin houch...@gmail.com
---
 .../devicetree/bindings/gpio/gpio-defer-reset.txt  |  22 +++
 drivers/power/reset/Kconfig|   8 +
 drivers/power/reset/Makefile   |   1 +
 drivers/power/reset/gpio-defer-reset.c | 192 +
 4 files changed, 223 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-defer-reset.txt
 create mode 100644 drivers/power/reset/gpio-defer-reset.c

diff --git a/Documentation/devicetree/bindings/gpio/gpio-defer-reset.txt 
b/Documentation/devicetree/bindings/gpio/gpio-defer-reset.txt
new file mode 100644
index 000..5d55830
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-defer-reset.txt
@@ -0,0 +1,22 @@
+GPIO defer reset binding
+
+Put a defer-reset device in a device node and enable DEFER RESET OBJECT CONFIG.
+During driver init-calls, a defer-reset object will be created and issue reset
+signal after the enclosing device node's initialization complete.
+
+Required properties:
+- compatible:
+  - defer-reset for creating defer reset object
+- reset-gpio: specify gpio pin, can be an array.
+- reset-init: specify reset signal initial value, can be 0 or 1.
+- reset-end: specify reset signal end value, can be 0 or 1.
+- delay: specify reset duration in ms.
+
+Example:
+   defer_reset_vbus {
+   compatible = defer-reset;
+   reset-gpios = gpx3 5 1;
+   reset-init = 0;
+   reset-end = 1;
+   delay = 5;
+   };
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index fa0e4e0..74b7eb0 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -57,3 +57,11 @@ config POWER_RESET_XGENE
depends on POWER_RESET
help
  Reboot support for the APM SoC X-Gene Eval boards.
+
+config GPIO_DEFER_RESET
+   bool Defer reset driver via gpio
+   depends on OF_GPIO  POWER_RESET
+   help
+ Enable defer reset drvier
+ The reset signal would be issued after a device on USB or PCI bus is 
initialied.
+ The dependency of reset signal and device can be specified in board's 
dts file.
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index a5b4a77..166baf9 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o
 obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o
 obj-$(CONFIG_POWER_RESET_VEXPRESS) += vexpress-poweroff.o
 obj-$(CONFIG_POWER_RESET_XGENE) += xgene-reboot.o
+obj-$(CONFIG_GPIO_DEFER_RESET) += gpio-defer-reset.o
diff --git a/drivers/power/reset/gpio-defer-reset.c 
b/drivers/power/reset/gpio-defer-reset.c
new file mode 100644
index 000..6425519
--- /dev/null
+++ b/drivers/power/reset/gpio-defer-reset.c
@@ -0,0 +1,192 @@
+/*
+ * GPIO Defer Reset Driver
+ *
+ * Copyright (C) 2014 Houcheng Lin
+ * Author: Houcheng Lin houch...@gmail.com
+ *
+ * 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

Re: [RFC PATCH] gpio: Add a defer reset object to send board specific reset

2014-06-14 Thread Houcheng Lin
Hi Linus, please see my replies below,

2014-06-12 20:35 GMT+08:00 Linus Walleij :
>
> OK this is interesting stuff..
>
> But this driver *MUST* live under drivers/power/reset/*, as it
> has absolutely *nothing* to do with GPIO except for being a consumer
> of it. I won't merge it.
>
> And you should discuss it with Dmitry and David W.
>
> But I will review it nevertheless :-D

Thanks for this information, I changed source to under drivers/
power/reset.

>
> OK so reset init and reset end is a way to specify when reset
> is asserted (as one or zero).
>
> DON'T do this. The GPIO bindings already know a way to define
> if GPIOs are active high or low, and the gpiod interface will invert
> the signal for you if this is specified as active low.
>
> This way you get rid of both strange properties.
>

May I reserve the "reset-init" and ""reset-end" properties? As
some boards use power line off to reset device. The power line
is active high when as power but active low when as a reset signal.

>
> You forgot to free the deferred_reset_list here. Fix that.
>

Thank a lot for your reviews :) Here are fixed of version 2:
- change location to drivers/power/reset
- remove unused #include
- change to use GPIO descriptor interface and use customer.h
- free resources after issue reset. However, if a enclosing
  chip is not probled, the correpsonding reset will not send
      and memeory is still not free in this case.
- other minor fixs

Best regards,
Houcheng Lin
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH] gpio: Add a defer reset object to send board specific reset

2014-06-14 Thread Houcheng Lin
Hi Linus, please see my replies below,

2014-06-12 20:35 GMT+08:00 Linus Walleij linus.wall...@linaro.org:

 OK this is interesting stuff..

 But this driver *MUST* live under drivers/power/reset/*, as it
 has absolutely *nothing* to do with GPIO except for being a consumer
 of it. I won't merge it.

 And you should discuss it with Dmitry and David W.

 But I will review it nevertheless :-D

Thanks for this information, I changed source to under drivers/
power/reset.


 OK so reset init and reset end is a way to specify when reset
 is asserted (as one or zero).

 DON'T do this. The GPIO bindings already know a way to define
 if GPIOs are active high or low, and the gpiod interface will invert
 the signal for you if this is specified as active low.

 This way you get rid of both strange properties.


May I reserve the reset-init and reset-end properties? As
some boards use power line off to reset device. The power line
is active high when as power but active low when as a reset signal.


 You forgot to free the deferred_reset_list here. Fix that.


Thank a lot for your reviews :) Here are fixed of version 2:
- change location to drivers/power/reset
- remove unused #include
- change to use GPIO descriptor interface and use customer.h
- free resources after issue reset. However, if a enclosing
  chip is not probled, the correpsonding reset will not send
  and memeory is still not free in this case.
- other minor fixs

Best regards,
Houcheng Lin
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH] gpio: Add a defer reset object to send board specific reset

2014-06-08 Thread Houcheng Lin
egister this device from kernel.

>
> Before doing a more thorough review, I'd like to discuss the basic
> idea. All the previous attempts at implementing an out-of-bus reset
> mechanism are strong evidence that something like this is needed.
> Having a generic mechanism would be a great plus. I am not convinced
> that using a dummy device instance is the right thing to do though.
> Also depending on the bus or device you might desire a different
> timing for issuing the reset: e.g. I know of a modem on a discoverable
> bus (MMC) that will only let itself be probed after the reset is
> applied.

On some hardware board's resetting signal's timing sequence depends on
initialization of a device. Pull the reseting logic onto the device level fits
the original hardware and no need to modify the chip driver's source code.

However, this mechanism is encasulated as a dummy, pseudo device in kerne. By
nature, it should be a system type/errata, bus feature or kernel feature. I am
not sure if it is okay that a kernel feature code can registers a driver, run
probe code and de-register driver. Is there any suggestion ?

>
> Maybe something ought to be implemented at a deeper level, like the
> bus (as in, all of them) of even the device layer?
>
> Alex.

Thanks a lot for spending time and giving comments.
Best regards,
Houcheng Lin
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH] gpio: Add a defer reset object to send board specific reset

2014-06-08 Thread Houcheng Lin
) that will only let itself be probed after the reset is
 applied.

On some hardware board's resetting signal's timing sequence depends on
initialization of a device. Pull the reseting logic onto the device level fits
the original hardware and no need to modify the chip driver's source code.

However, this mechanism is encasulated as a dummy, pseudo device in kerne. By
nature, it should be a system type/errata, bus feature or kernel feature. I am
not sure if it is okay that a kernel feature code can registers a driver, run
probe code and de-register driver. Is there any suggestion ?


 Maybe something ought to be implemented at a deeper level, like the
 bus (as in, all of them) of even the device layer?

 Alex.

Thanks a lot for spending time and giving comments.
Best regards,
Houcheng Lin
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH] gpio: Add a defer reset object to send board specific reset

2014-06-07 Thread Houcheng Lin
The Problem
---
The reset signal on a hardware board is send either:
- during machine initialization
- during bus master's initialization

In some hardware design, devices on bus need a non-standard and extra reset
signal after bus is initialied. Most reason is to wake up device from hanging
state.

The board spefic reset code can not be put into machine init code, as it is
too early. This code can not also be put onto chip's driver, as it is board
specific and not suitable for a common chip driver.

Defer Reset Object
--
The defer reset object is to resolve this issue, developer can put a defer-
reset device on the board's dts file and enable DEFER RESET OBJECT CONFIG.
During driver init-calls, a defer-reset object is created and issue reset signal
after the enclosing device is initialized.

This eliminate the need to rewrite a driver module with only one purpose: 
sending
a board specific reset. This also allow mainstream kernel to support many boards
that modify the common drivers to send board specific reset. Configuring 
defer-reset
device in dts leave the board specific reset rules on board level and simple to
maintain.

Example dts File

usb-ehci-chip@1211000{
usb-phy = <_phy>;
defer_reset_vbus {
compatible = "defer-reset";
reset-gpios = < 5 1>;
reset-init = <0>;
reset-end = <1>;
delay = <5>;
};
};

Block Diagram of dts File
-
+-+
| usb-ehci-chip@1211000   |
|   +-+   |
|   | defer-reset(gpx3)   |   |
|   +-+   |
+---------+

Signed-off-by: Houcheng Lin 
---
 drivers/gpio/Kconfig|   8 ++
 drivers/gpio/Makefile   |   1 +
 drivers/gpio/gpio-defer-reset.c | 179 
 3 files changed, 188 insertions(+)
 create mode 100644 drivers/gpio/gpio-defer-reset.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index a86c49a..99aa0d6 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -851,6 +851,14 @@ config GPIO_BCM_KONA
help
  Turn on GPIO support for Broadcom "Kona" chips.
 
+config GPIO_DEFER_RESET
+   bool "Defer reset driver via gpio"
+   depends on OF_GPIO
+   help
+ Enable defer reset drvier
+ The reset signal would be issued after a device on USB or PCI bus is 
initialied.
+ The dependency of reset signal and device can be specified in board's 
dts file.
+
 comment "USB GPIO expanders:"
 
 config GPIO_VIPERBOARD
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 6309aff..0754758 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -101,3 +101,4 @@ obj-$(CONFIG_GPIO_WM8994)   += gpio-wm8994.o
 obj-$(CONFIG_GPIO_XILINX)  += gpio-xilinx.o
 obj-$(CONFIG_GPIO_XTENSA)  += gpio-xtensa.o
 obj-$(CONFIG_GPIO_ZEVIO)   += gpio-zevio.o
+obj-$(CONFIG_GPIO_DEFER_RESET) += gpio-defer-reset.o
diff --git a/drivers/gpio/gpio-defer-reset.c b/drivers/gpio/gpio-defer-reset.c
new file mode 100644
index 000..c6decab
--- /dev/null
+++ b/drivers/gpio/gpio-defer-reset.c
@@ -0,0 +1,179 @@
+/*
+ * GPIO Defer Reset Driver
+ *
+ * Copyright (C) 2014 Houcheng Lin
+ * Author: Houcheng Lin 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+
+#define DRIVER_DESC "GPIO Defer Reset Driver"
+#define GDR_MAX_DEV 32
+
+
+static DEFINE_MUTEX(deferred_reset_mutex);
+static LIST_HEAD(deferred_reset_list);
+
+
+struct defer_reset_private {
+   struct list_head next;
+   struct device_node *node;  /* defer_reset device */
+   intissued;
+};
+
+static void gdr_issue_reset(
+   struct platform_device *pdev, struct device_node *dnode)
+{
+   int gpio;
+   int i;
+   int count = of_gpio_named_count(dnode, "reset-gpios");
+   u32 reset_init[GDR_MAX_DEV];
+   u32 reset_end[GDR_MAX_DEV];
+   u32 delay;
+
+   if (count != of_property_count_u32_elems(dnode, "reset-init")) {
+   dev_err(>dev, "should call std error here, number is 
wrong:%d\n",
+   of_property_count_u32_elems(dnode, "reset-init"));
+   return;
+   }
+   if (count != of_property_count_u32_elems(dnode, "reset-end")) {
+   dev_err(>dev, "should 

[RFC PATCH] gpio: Add a defer reset object to send board specific reset

2014-06-07 Thread Houcheng Lin
The Problem
---
The reset signal on a hardware board is send either:
- during machine initialization
- during bus master's initialization

In some hardware design, devices on bus need a non-standard and extra reset
signal after bus is initialied. Most reason is to wake up device from hanging
state.

The board spefic reset code can not be put into machine init code, as it is
too early. This code can not also be put onto chip's driver, as it is board
specific and not suitable for a common chip driver.

Defer Reset Object
--
The defer reset object is to resolve this issue, developer can put a defer-
reset device on the board's dts file and enable DEFER RESET OBJECT CONFIG.
During driver init-calls, a defer-reset object is created and issue reset signal
after the enclosing device is initialized.

This eliminate the need to rewrite a driver module with only one purpose: 
sending
a board specific reset. This also allow mainstream kernel to support many boards
that modify the common drivers to send board specific reset. Configuring 
defer-reset
device in dts leave the board specific reset rules on board level and simple to
maintain.

Example dts File

usb-ehci-chip@1211000{
usb-phy = usb2_phy;
defer_reset_vbus {
compatible = defer-reset;
reset-gpios = gpx3 5 1;
reset-init = 0;
reset-end = 1;
delay = 5;
};
};

Block Diagram of dts File
-
+-+
| usb-ehci-chip@1211000   |
|   +-+   |
|   | defer-reset(gpx3)   |   |
|   +-+   |
+-+

Signed-off-by: Houcheng Lin houch...@gmail.com
---
 drivers/gpio/Kconfig|   8 ++
 drivers/gpio/Makefile   |   1 +
 drivers/gpio/gpio-defer-reset.c | 179 
 3 files changed, 188 insertions(+)
 create mode 100644 drivers/gpio/gpio-defer-reset.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index a86c49a..99aa0d6 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -851,6 +851,14 @@ config GPIO_BCM_KONA
help
  Turn on GPIO support for Broadcom Kona chips.
 
+config GPIO_DEFER_RESET
+   bool Defer reset driver via gpio
+   depends on OF_GPIO
+   help
+ Enable defer reset drvier
+ The reset signal would be issued after a device on USB or PCI bus is 
initialied.
+ The dependency of reset signal and device can be specified in board's 
dts file.
+
 comment USB GPIO expanders:
 
 config GPIO_VIPERBOARD
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 6309aff..0754758 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -101,3 +101,4 @@ obj-$(CONFIG_GPIO_WM8994)   += gpio-wm8994.o
 obj-$(CONFIG_GPIO_XILINX)  += gpio-xilinx.o
 obj-$(CONFIG_GPIO_XTENSA)  += gpio-xtensa.o
 obj-$(CONFIG_GPIO_ZEVIO)   += gpio-zevio.o
+obj-$(CONFIG_GPIO_DEFER_RESET) += gpio-defer-reset.o
diff --git a/drivers/gpio/gpio-defer-reset.c b/drivers/gpio/gpio-defer-reset.c
new file mode 100644
index 000..c6decab
--- /dev/null
+++ b/drivers/gpio/gpio-defer-reset.c
@@ -0,0 +1,179 @@
+/*
+ * GPIO Defer Reset Driver
+ *
+ * Copyright (C) 2014 Houcheng Lin
+ * Author: Houcheng Lin houch...@gmail.com
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include linux/clk.h
+#include linux/dma-mapping.h
+#include linux/io.h
+#include linux/kernel.h
+#include linux/slab.h
+#include linux/module.h
+#include linux/of.h
+#include linux/of_gpio.h
+#include linux/of_platform.h
+#include linux/platform_device.h
+#include linux/usb/phy.h
+#include linux/usb/samsung_usb_phy.h
+#include linux/usb.h
+#include linux/usb/hcd.h
+#include linux/usb/otg.h
+
+
+#define DRIVER_DESC GPIO Defer Reset Driver
+#define GDR_MAX_DEV 32
+
+
+static DEFINE_MUTEX(deferred_reset_mutex);
+static LIST_HEAD(deferred_reset_list);
+
+
+struct defer_reset_private {
+   struct list_head next;
+   struct device_node *node;  /* defer_reset device */
+   intissued;
+};
+
+static void gdr_issue_reset(
+   struct platform_device *pdev, struct device_node *dnode)
+{
+   int gpio;
+   int i;
+   int count = of_gpio_named_count(dnode, reset-gpios);
+   u32 reset_init[GDR_MAX_DEV];
+   u32 reset_end[GDR_MAX_DEV];
+   u32 delay;
+
+   if (count != of_property_count_u32_elems(dnode, reset-init)) {
+   dev_err(pdev-dev, should call std error here, number is 
wrong:%d\n,
+   of_property_count_u32_elems(dnode, reset-init));
+   return;
+   }
+   if (count