* [PATCH v2] ibm_newemac: Fixes entry of short packets
From: Stefan Roese @ 2008-07-01 8:58 UTC (permalink / raw)
To: linuxppc-dev, netdev; +Cc: Sathya Narayanan
From: Sathya Narayanan <sathyan@teamf1.com>
Short packets has to be discarded by the driver. So this patch addresses the
issue of discarding the short packets of size lesser then ethernet header
size.
Signed-off-by: Sathya Narayanan <sathyan@teamf1.com>
Signed-off-by: Stefan Roese <sr@denx.de>
---
drivers/net/ibm_newemac/core.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index ca63fa0..babc79a 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -1636,6 +1636,12 @@ static int emac_poll_rx(void *param, int budget)
goto next;
}
+ if (len < ETH_HLEN) {
+ ++dev->estats.rx_dropped_stack;
+ emac_recycle_rx_skb(dev, slot, len);
+ goto next;
+ }
+
if (len && len < EMAC_RX_COPY_THRESH) {
struct sk_buff *copy_skb =
alloc_skb(len + EMAC_RX_SKB_HEADROOM + 2, GFP_ATOMIC);
--
1.5.6.1
^ permalink raw reply related
* Re: [PATCH] powerpc: fix compile warning in init_thread
From: Benjamin Herrenschmidt @ 2008-07-01 9:07 UTC (permalink / raw)
To: Michael Neuling; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <1214895639.691008.114376646781.qpush@coopers>
On Tue, 2008-07-01 at 17:00 +1000, Michael Neuling wrote:
> arch/powerpc/kernel/init_task.c:33: warning: missing braces around initializer
> arch/powerpc/kernel/init_task.c:33: warning: (near initialization for 'init_task.thread.fpr[0]')
>
> Noticed by SFR.
>
> Signed-off-by: Michael Neuling <mikey@neuling.org>
That's when fpr is part of the union but what if CONFIG_VSX is off ?
Ben.
> ---
>
> include/asm-powerpc/processor.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> Index: linux-2.6-ozlabs/include/asm-powerpc/processor.h
> ===================================================================
> --- linux-2.6-ozlabs.orig/include/asm-powerpc/processor.h
> +++ linux-2.6-ozlabs/include/asm-powerpc/processor.h
> @@ -222,7 +222,7 @@ struct thread_struct {
> .ksp_limit = INIT_SP_LIMIT, \
> .regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \
> .fs = KERNEL_DS, \
> - .fpr = {0}, \
> + .fpr = {{0}}, \
> .fpscr = { .val = 0, }, \
> .fpexc_mode = 0, \
> }
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
^ permalink raw reply
* Re: linux-next: manual merge of the net tree
From: David Miller @ 2008-07-01 9:33 UTC (permalink / raw)
To: sfr; +Cc: linuxppc-dev, linux-next, paulus, jgarzik, Jason.jin
In-Reply-To: <20080701171940.6f282113.sfr@canb.auug.org.au>
From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Tue, 1 Jul 2008 17:19:40 +1000
> Today's linux-next merge of the net tree got a conflict
...
Thanks for the heads up on these two conflicts with the
powerpc tree.
The best seems to let you keep using your resolving, so
that's what I'll let you do :)
^ permalink raw reply
* linux-next: manual merge of the ttydev tree
From: Stephen Rothwell @ 2008-07-01 10:59 UTC (permalink / raw)
To: Alan Cox; +Cc: Adrian Bunk, linuxppc-dev, linux-next, Mackerras, Paul
[-- Attachment #1: Type: text/plain, Size: 559 bytes --]
Hi Alan,
Today's linux-next merge of the ttydev tree got a conflict in
drivers/serial/cpm_uart/cpm_uart_core.c between commit
0b2a2e5b7747f1f63bd86ca22b5c6097da5b2137 ("cpm_uart: Remove
!CONFIG_PPC_CPM_NEW_BINDING code") from the powerpc tree and commit
33e211d606d46d18befa6fe6aec76aa7971eefa8 ("03-serial_vcs") from the
ttydev tree.
The former removes some of the code modified by the latter. It is a
simple fixup and I can carry it.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Re: [PATCH] powerpc: fix compile warning in init_thread
From: Michael Neuling @ 2008-07-01 11:02 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <1214903256.20711.123.camel@pasglop>
In message <1214903256.20711.123.camel@pasglop> you wrote:
> On Tue, 2008-07-01 at 17:00 +1000, Michael Neuling wrote:
> > arch/powerpc/kernel/init_task.c:33: warning: missing braces around initiali
zer
> > arch/powerpc/kernel/init_task.c:33: warning: (near initialization for 'init
_task.thread.fpr[0]')
> >
> > Noticed by SFR.
> >
> > Signed-off-by: Michael Neuling <mikey@neuling.org>
>
> That's when fpr is part of the union but what if CONFIG_VSX is off ?
It's not a union anymore. It's a 2D array irrespective of CONFIG_VSX.
double fpr[32][TS_FPRWIDTH];
Mikey
>
> Ben.
>
> > ---
> >
> > include/asm-powerpc/processor.h | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > Index: linux-2.6-ozlabs/include/asm-powerpc/processor.h
> > ===================================================================
> > --- linux-2.6-ozlabs.orig/include/asm-powerpc/processor.h
> > +++ linux-2.6-ozlabs/include/asm-powerpc/processor.h
> > @@ -222,7 +222,7 @@ struct thread_struct {
> > .ksp_limit = INIT_SP_LIMIT, \
> > .regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \
> > .fs = KERNEL_DS, \
> > - .fpr = {0}, \
> > + .fpr = {{0}}, \
> > .fpscr = { .val = 0, }, \
> > .fpexc_mode = 0, \
> > }
> > _______________________________________________
> > Linuxppc-dev mailing list
> > Linuxppc-dev@ozlabs.org
> > https://ozlabs.org/mailman/listinfo/linuxppc-dev
>
^ permalink raw reply
* [BUG] 2.6.26-rc8-git2 - powerpc - circular locking dependency detected with net/ehea driver
From: Kamalesh Babulal @ 2008-07-01 12:38 UTC (permalink / raw)
To: kernel list; +Cc: netdev, linuxppc-dev, kernel-testers, jgarzik, Balbir Singh
Hi,
circular locking dependency is detected, while booting the
powerpc box with the 2.6.26-rc8-git2 kernel.
=======================================================
[ INFO: possible circular locking dependency detected ]
2.6.26-rc8-git2 #1
-------------------------------------------------------
ip/2214 is trying to acquire lock:
(&ehea_fw_handles.lock){--..}, at: [<d0000000007b4fa8>] .ehea_up+0x6c/0x6f8 [ehea]
but task is already holding lock:
(&port->port_lock){--..}, at: [<d0000000007b57bc>] .ehea_open+0x44/0xcc [ehea]
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #2 (&port->port_lock){--..}:
[<c0000000000aa0e8>] .__lock_acquire+0xc84/0xee0
[<c0000000000aa41c>] .lock_acquire+0xd8/0x124
[<c000000000452008>] .mutex_lock_nested+0x168/0x420
[<d0000000007b57bc>] .ehea_open+0x44/0xcc [ehea]
[<c0000000003b62b0>] .dev_open+0xec/0x160
[<c0000000003b46a4>] .dev_change_flags+0x10c/0x210
[<c0000000004162b0>] .devinet_ioctl+0x2cc/0x778
[<c0000000004173e0>] .inet_ioctl+0xdc/0x134
[<c0000000003a4464>] .sock_ioctl+0x2dc/0x338
[<c00000000012d12c>] .vfs_ioctl+0x64/0xfc
[<c00000000012d614>] .do_vfs_ioctl+0x450/0x494
[<c00000000012d6d0>] .sys_ioctl+0x78/0xc0
[<c00000000016413c>] .dev_ifsioc+0x1e8/0x450
[<c000000000163588>] .compat_sys_ioctl+0x3ec/0x484
[<c0000000000086dc>] syscall_exit+0x0/0x40
-> #1 (rtnl_mutex){--..}:
[<c0000000000aa0e8>] .__lock_acquire+0xc84/0xee0
[<c0000000000aa41c>] .lock_acquire+0xd8/0x124
[<c000000000452008>] .mutex_lock_nested+0x168/0x420
[<c0000000003c1ad0>] .rtnl_lock+0x28/0x44
[<c0000000003b5334>] .register_netdev+0x24/0x8c
[<d0000000007b3810>] .ehea_setup_single_port+0x2d4/0x3e0 [ehea]
[<d0000000007ba434>] .ehea_probe_adapter+0x290/0x3a0 [ehea]
[<c0000000003a0098>] .of_platform_device_probe+0x80/0x8c4
[<c000000000305ce4>] .driver_probe_device+0x144/0x20c
[<c000000000305e14>] .__driver_attach+0x68/0xb0
[<c000000000304ed4>] .bus_for_each_dev+0x88/0xe4
[<c000000000305a24>] .driver_attach+0x34/0x50
[<c000000000305524>] .bus_add_driver+0xe0/0x294
[<c000000000306178>] .driver_register+0xcc/0x1a4
[<c00000000039ff30>] .of_register_driver+0x54/0x6c
[<c0000000000256f4>] .ibmebus_register_driver+0x40/0x60
[<d0000000007ba728>] .ehea_module_init+0x1e4/0x22fc [ehea]
[<c0000000000b5294>] .sys_init_module+0x19a0/0x1b80
[<c0000000000086dc>] syscall_exit+0x0/0x40
-> #0 (&ehea_fw_handles.lock){--..}:
[<c0000000000a9fe4>] .__lock_acquire+0xb80/0xee0
[<c0000000000aa41c>] .lock_acquire+0xd8/0x124
[<c000000000452008>] .mutex_lock_nested+0x168/0x420
[<d0000000007b4fa8>] .ehea_up+0x6c/0x6f8 [ehea]
[<d0000000007b57e4>] .ehea_open+0x6c/0xcc [ehea]
[<c0000000003b62b0>] .dev_open+0xec/0x160
[<c0000000003b46a4>] .dev_change_flags+0x10c/0x210
[<c0000000004162b0>] .devinet_ioctl+0x2cc/0x778
[<c0000000004173e0>] .inet_ioctl+0xdc/0x134
[<c0000000003a4464>] .sock_ioctl+0x2dc/0x338
[<c00000000012d12c>] .vfs_ioctl+0x64/0xfc
[<c00000000012d614>] .do_vfs_ioctl+0x450/0x494
[<c00000000012d6d0>] .sys_ioctl+0x78/0xc0
[<c00000000016413c>] .dev_ifsioc+0x1e8/0x450
[<c000000000163588>] .compat_sys_ioctl+0x3ec/0x484
[<c0000000000086dc>] syscall_exit+0x0/0x40
other info that might help us debug this:
2 locks held by ip/2214:
#0: (rtnl_mutex){--..}, at: [<c0000000003c1ad0>] .rtnl_lock+0x28/0x44
#1: (&port->port_lock){--..}, at: [<d0000000007b57bc>] .ehea_open+0x44/0xcc [ehea]
stack backtrace:
Call Trace:
[c0000000f4d0f030] [c000000000010b9c] .show_stack+0x78/0x1c8 (unreliable)
[c0000000f4d0f0e0] [c000000000010d0c] .dump_stack+0x20/0x34
[c0000000f4d0f160] [c0000000000a7644] .print_circular_bug_tail+0x84/0xa8
[c0000000f4d0f230] [c0000000000a9fe4] .__lock_acquire+0xb80/0xee0
[c0000000f4d0f320] [c0000000000aa41c] .lock_acquire+0xd8/0x124
[c0000000f4d0f3e0] [c000000000452008] .mutex_lock_nested+0x168/0x420
[c0000000f4d0f4d0] [d0000000007b4fa8] .ehea_up+0x6c/0x6f8 [ehea]
[c0000000f4d0f5e0] [d0000000007b57e4] .ehea_open+0x6c/0xcc [ehea]
[c0000000f4d0f680] [c0000000003b62b0] .dev_open+0xec/0x160
[c0000000f4d0f710] [c0000000003b46a4] .dev_change_flags+0x10c/0x210
[c0000000f4d0f7c0] [c0000000004162b0] .devinet_ioctl+0x2cc/0x778
[c0000000f4d0f8d0] [c0000000004173e0] .inet_ioctl+0xdc/0x134
[c0000000f4d0f950] [c0000000003a4464] .sock_ioctl+0x2dc/0x338
[c0000000f4d0f9f0] [c00000000012d12c] .vfs_ioctl+0x64/0xfc
[c0000000f4d0fa90] [c00000000012d614] .do_vfs_ioctl+0x450/0x494
[c0000000f4d0fb50] [c00000000012d6d0] .sys_ioctl+0x78/0xc0
[c0000000f4d0fc10] [c00000000016413c] .dev_ifsioc+0x1e8/0x450
[c0000000f4d0fd30] [c000000000163588] .compat_sys_ioctl+0x3ec/0x484
[c0000000f4d0fe30] [c0000000000086dc] syscall_exit+0x0/0x40
ehea: eth0: Physical port up
ehea: External switch port is backup port
BUG: sleeping function called from invalid context at kernel/mutex.c:209
in_atomic():1, irqs_disabled():0
INFO: lockdep is turned off.
Call Trace:
[c0000000f4d0f200] [c000000000010b9c] .show_stack+0x78/0x1c8 (unreliable)
[c0000000f4d0f2b0] [c000000000010d0c] .dump_stack+0x20/0x34
[c0000000f4d0f330] [c00000000006dfc0] .__might_sleep+0x104/0x124
[c0000000f4d0f3c0] [c000000000451ef0] .mutex_lock_nested+0x50/0x420
[c0000000f4d0f4b0] [d0000000007b2f80] .ehea_set_multicast_list+0x64/0x1d8 [ehea]
[c0000000f4d0f560] [c0000000003b2de4] .__dev_set_rx_mode+0xd0/0xf0
[c0000000f4d0f5f0] [c0000000003b2e44] .dev_set_rx_mode+0x40/0x70
[c0000000f4d0f680] [c0000000003b62ec] .dev_open+0x128/0x160
[c0000000f4d0f710] [c0000000003b46a4] .dev_change_flags+0x10c/0x210
[c0000000f4d0f7c0] [c0000000004162b0] .devinet_ioctl+0x2cc/0x778
[c0000000f4d0f8d0] [c0000000004173e0] .inet_ioctl+0xdc/0x134
[c0000000f4d0f950] [c0000000003a4464] .sock_ioctl+0x2dc/0x338
[c0000000f4d0f9f0] [c00000000012d12c] .vfs_ioctl+0x64/0xfc
[c0000000f4d0fa90] [c00000000012d614] .do_vfs_ioctl+0x450/0x494
[c0000000f4d0fb50] [c00000000012d6d0] .sys_ioctl+0x78/0xc0
[c0000000f4d0fc10] [c00000000016413c] .dev_ifsioc+0x1e8/0x450
[c0000000f4d0fd30] [c000000000163588] .compat_sys_ioctl+0x3ec/0x484
[c0000000f4d0fe30] [c0000000000086dc] syscall_exit+0x0/0x40
[ OK ]
Starting auditd: [ OK ]
Starting system logger: [ OK ]
Starting kernel logger: [ OK ]
Starting ctrmc: WARNING: initlog is deprecated and will be removed in a future release
WARNING: initlog is deprecated and will be removed in a future release
[ OK ]
Starting irqbalance: [ OK ]
Starting portmap: [ OK ]
Starting NFS statd: [ OK ]
Starting RPC idmapd: [ OK ]
Starting system message bus: [ OK ]
[ OK ] Bluetooth services:[ OK ]
Mounting other filesystems: [ OK ]
Starting PC/SC smart card daemon (pcscd): [ OK ]
Starting hidd: [ OK ]
Starting autofs: Loading autofs4: [ OK ]
Starting automount: [ OK ]
[ OK ]
Starting hpiod: [ OK ]
Starting hpssd: [ OK ]
Starting iprinit: Starting ipr initialization daemon[ OK ]
[ OK ]
Starting iprupdate: Checking ipr microcode levels
Completed ipr microcode updates[ OK ]
[ OK ]
Starting rtas_errd (platform error handling) daemon: [ OK ]
Starting iprdump: Starting ipr dump daemon[ OK ]
[ OK ]
Starting sshd: BUG: sleeping function called from invalid context at kernel/mutex.c:209
in_atomic():1, irqs_disabled():0
INFO: lockdep is turned off.
Call Trace:
[c00000010ac5f1e0] [c000000000010b9c] .show_stack+0x78/0x1c8 (unreliable)
[c00000010ac5f290] [c000000000010d0c] .dump_stack+0x20/0x34
[c00000010ac5f310] [c00000000006dfc0] .__might_sleep+0x104/0x124
[c00000010ac5f3a0] [c000000000451ef0] .mutex_lock_nested+0x50/0x420
[c00000010ac5f490] [d0000000007b2f80] .ehea_set_multicast_list+0x64/0x1d8 [ehea]
[c00000010ac5f540] [c0000000003b2de4] .__dev_set_rx_mode+0xd0/0xf0
[c00000010ac5f5d0] [c0000000003b98a4] .dev_mc_add+0x7c/0xc0
[c00000010ac5f680] [d000000000827efc] .igmp6_group_added+0x94/0x208 [ipv6]
[c00000010ac5f740] [d0000000008284e4] .ipv6_dev_mc_inc+0x400/0x44c [ipv6]
[c00000010ac5f7e0] [d00000000080c59c] .ipv6_add_dev+0x2ec/0x358 [ipv6]
[c00000010ac5f8a0] [d00000000080d2b8] .addrconf_notify+0xbc/0x928 [ipv6]
[c00000010ac5fa50] [c0000000003b717c] .register_netdevice_notifier+0x94/0x29c
[c00000010ac5fb00] [d000000000839358] .addrconf_init+0xa4/0x1ac [ipv6]
[c00000010ac5fb90] [d0000000008390e0] .inet6_init+0x248/0x3dc [ipv6]
[c00000010ac5fc30] [c0000000000b5294] .sys_init_module+0x19a0/0x1b80
[c00000010ac5fe30] [c0000000000086dc] syscall_exit+0x0/0x40
[ OK ]
Starting cups: [ OK ]
Starting xinetd: [ OK ]
Starting NFS services: [ OK ]
Starting NFS quotas: [ OK ]
Starting NFS daemon: NFSD: Using /var/lib/nfs/v4recovery as the NFSv4 state recovery directory
[ OK ]
Starting NFS mountd: [ OK ]
Starting vsftpd for vsftpd: [ OK ]
Starting sendmail: [ OK ]
Starting sm-client: [ OK ]
Starting console mouse services: [ OK ]
Starting crond: [ OK ]
Starting xfs: [ OK ]
Starting anacron: [ OK ]
Starting atd: [ OK ]
Starting yum-updatesd: [ OK ]
Starting Avahi daemon... BUG: sleeping function called from invalid context at kernel/mutex.c:209
in_atomic():1, irqs_disabled():0
INFO: lockdep is turned off.
Call Trace:
[c00000010608f200] [c000000000010b9c] .show_stack+0x78/0x1c8 (unreliable)
[c00000010608f2b0] [c000000000010d0c] .dump_stack+0x20/0x34
[c00000010608f330] [c00000000006dfc0] .__might_sleep+0x104/0x124
[c00000010608f3c0] [c000000000451ef0] .mutex_lock_nested+0x50/0x420
[c00000010608f4b0] [d0000000007b2f80] .ehea_set_multicast_list+0x64/0x1d8 [ehea]
[c00000010608f560] [c0000000003b2de4] .__dev_set_rx_mode+0xd0/0xf0
[c00000010608f5f0] [c0000000003b98a4] .dev_mc_add+0x7c/0xc0
[c00000010608f6a0] [d000000000827efc] .igmp6_group_added+0x94/0x208 [ipv6]
[c00000010608f760] [d0000000008284e4] .ipv6_dev_mc_inc+0x400/0x44c [ipv6]
[c00000010608f800] [d000000000828e9c] .ipv6_sock_mc_join+0x1e0/0x288 [ipv6]
[c00000010608f8c0] [d000000000818338] .do_ipv6_setsockopt+0x91c/0xcfc [ipv6]
[c00000010608faf0] [d0000000008189a0] .ipv6_setsockopt+0x90/0x120 [ipv6]
[c00000010608fba0] [d00000000081d408] .udpv6_setsockopt+0x40/0x5c [ipv6]
[c00000010608fc20] [c0000000003a4bf4] .sock_common_setsockopt+0x40/0x58
[c00000010608fca0] [c0000000003a1ae8] .sys_setsockopt+0xc0/0x110
[c00000010608fd60] [c0000000003a4054] .sys_socketcall+0x1bc/0x21c
[c00000010608fe30] [c0000000000086dc] syscall_exit+0x0/0x40
[ OK ]
0xc0000000003c1ad0 is in rtnl_lock (net/core/rtnetlink.c:66).
61
62 static DEFINE_MUTEX(rtnl_mutex);
63
64 void rtnl_lock(void)
65 {
66 mutex_lock(&rtnl_mutex);
67 }
68
69 void __rtnl_unlock(void)
70 {
0x4fa8 is in ehea_up (drivers/net/ehea/ehea_main.c:2462).
2457 struct ehea_port *port = netdev_priv(dev);
2458
2459 if (port->state == EHEA_PORT_UP)
2460 return 0;
2461
2462 mutex_lock(&ehea_fw_handles.lock);
2463
2464 ret = ehea_port_res_setup(port, port->num_def_qps,
2465 port->num_add_tx_qps);
2466 if (ret) {
0x57bc is in ehea_open (drivers/net/ehea/ehea_main.c:2552).
2547 static int ehea_open(struct net_device *dev)
2548 {
2549 int ret;
2550 struct ehea_port *port = netdev_priv(dev);
2551
2552 mutex_lock(&port->port_lock);
2553
2554 if (netif_msg_ifup(port))
2555 ehea_info("enabling port %s", dev->name);
2556
--
Thanks & Regards,
Kamalesh Babulal,
Linux Technology Center,
IBM, ISTL.
^ permalink raw reply
* [PATCH] powerpc/86xx: mpc8610_hpcd: fix interrupt trigger type for ULi IDE
From: Anton Vorontsov @ 2008-07-01 13:04 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev, Timur Tabi
i8259 PIC is disabled on MPC8610HPCD, and ULi IDE is configured to use
PCI sideband interrupt that is specified in the device tree.
Current HPCD's device tree specify that IDE interrupt is low to high
sensitive, but in practice ULi IDE throws active-high interrupts (not
active-low as all normal PCI devices).
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
This is for -next, since the bug could be triggered only on RT kernels
with hardirq preemption.
arch/powerpc/boot/dts/mpc8610_hpcd.dts | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/boot/dts/mpc8610_hpcd.dts b/arch/powerpc/boot/dts/mpc8610_hpcd.dts
index 65a5f64..981941e 100644
--- a/arch/powerpc/boot/dts/mpc8610_hpcd.dts
+++ b/arch/powerpc/boot/dts/mpc8610_hpcd.dts
@@ -363,7 +363,7 @@
0xe000 0 0 4 &mpic 1 1
/* IDSEL 0x1f */
- 0xf800 0 0 1 &mpic 3 0
+ 0xf800 0 0 1 &mpic 3 2
0xf800 0 0 2 &mpic 0 1
>;
--
1.5.5.4
^ permalink raw reply related
* Re: [PATCH 4/5] Helper routines for parsing drconf memory
From: Nathan Fontenot @ 2008-07-01 13:54 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <18536.54376.368328.736714@cargo.ozlabs.ibm.com>
Paul Mackerras wrote:
> Nathan Fontenot writes:
>
>> This patch pulls several pieces of exisitng code for parsing memory under
>> the ibm,dynamic-reconfiguration-memory node of the device tree into helper
>> routines. This is in preparation for the next patch that will also use these
>> same helper routines. There are no functional changes in this patch.
>
> I went to apply this, but it is whitespace-damaged...
>
Hmmm... I am having problems getting this to apply to the latest mainline cleanly.
I'll update the patchset and re-submit.
-Nathan
^ permalink raw reply
* Re: [patch 1/6] mm: Allow architectures to define additional protection bits
From: Dave Kleikamp @ 2008-07-01 13:54 UTC (permalink / raw)
To: Andrew Morton; +Cc: Hugh Dickins, linux-mm, Paul Mackerras, Linuxppc-dev
In-Reply-To: <20080701015301.3dc8749b.akpm@linux-foundation.org>
On Tue, 2008-07-01 at 01:53 -0700, Andrew Morton wrote:
> On Wed, 18 Jun 2008 17:32:55 -0500 shaggy@linux.vnet.ibm.com wrote:
>
> > This patch allows architectures to define functions to deal with
> > additional protections bits for mmap() and mprotect().
> >
> > arch_calc_vm_prot_bits() maps additonal protection bits to vm_flags
> > arch_vm_get_page_prot() maps additional vm_flags to the vma's vm_page_prot
> > arch_validate_prot() checks for valid values of the protection bits
>
> It'd be simpler if Paul were to merge this. It doesn't conflict with
> any pending work.
That works for me. Paul, I'll send you an updated patchset.
> Acked-by: Andrew Morton <akpm@linux-foundation.org>
>
> > Note: vm_get_page_prot() is now pretty ugly.
>
> It is. But afacit it generates the same code for non-powerpc.
>
> > Suggestions?
>
> nfi. Let us rub the Hugh-summoning lamp.
>
> > Signed-off-by: Dave Kleikamp <shaggy@linux.vnet.ibm.com>
> > ---
> >
> > include/linux/mman.h | 28 +++++++++++++++++++++++++++-
> > mm/mmap.c | 5 +++--
> > mm/mprotect.c | 2 +-
> > 3 files changed, 31 insertions(+), 4 deletions(-)
> >
> > Index: linux-2.6.26-rc5/include/linux/mman.h
> > ===================================================================
> > --- linux-2.6.26-rc5.orig/include/linux/mman.h
> > +++ linux-2.6.26-rc5/include/linux/mman.h
> > @@ -34,6 +34,31 @@ static inline void vm_unacct_memory(long
> > }
> >
> > /*
> > + * Allow architectures to handle additional protection bits
> > + */
> > +
> > +#ifndef arch_calc_vm_prot_bits
> > +#define arch_calc_vm_prot_bits(prot) 0
> > +#endif
> > +
> > +#ifndef arch_vm_get_page_prot
> > +#define arch_vm_get_page_prot(vm_flags) __pgprot(0)
> > +#endif
> > +
> > +#ifndef arch_validate_prot
> > +/*
> > + * This is called from mprotect(). PROT_GROWSDOWN and PROT_GROWSUP have
> > + * already been masked out.
> > + *
> > + * Returns true if the prot flags are valid
> > + */
> > +static inline int arch_validate_prot(unsigned long prot)
> > +{
> > + return (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM)) == 0;
> > +}
>
> Officially we should now have
>
> #define arch_validate_prot arch_validate_prot
>
> here.
No problem.
> > +#endif
> > +
> > +/*
> > * Optimisation macro. It is equivalent to:
> > * (x & bit1) ? bit2 : 0
> > * but this version is faster.
> > @@ -51,7 +76,8 @@ calc_vm_prot_bits(unsigned long prot)
> > {
> > return _calc_vm_trans(prot, PROT_READ, VM_READ ) |
> > _calc_vm_trans(prot, PROT_WRITE, VM_WRITE) |
> > - _calc_vm_trans(prot, PROT_EXEC, VM_EXEC );
> > + _calc_vm_trans(prot, PROT_EXEC, VM_EXEC) |
> > + arch_calc_vm_prot_bits(prot);
> > }
> >
> > /*
> > Index: linux-2.6.26-rc5/mm/mmap.c
> > ===================================================================
> > --- linux-2.6.26-rc5.orig/mm/mmap.c
> > +++ linux-2.6.26-rc5/mm/mmap.c
> > @@ -72,8 +72,9 @@ pgprot_t protection_map[16] = {
> >
> > pgprot_t vm_get_page_prot(unsigned long vm_flags)
> > {
> > - return protection_map[vm_flags &
> > - (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
> > + return __pgprot(pgprot_val(protection_map[vm_flags &
> > + (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) |
> > + pgprot_val(arch_vm_get_page_prot(vm_flags)));
> > }
> > EXPORT_SYMBOL(vm_get_page_prot);
> >
> > Index: linux-2.6.26-rc5/mm/mprotect.c
> > ===================================================================
> > --- linux-2.6.26-rc5.orig/mm/mprotect.c
> > +++ linux-2.6.26-rc5/mm/mprotect.c
> > @@ -239,7 +239,7 @@ sys_mprotect(unsigned long start, size_t
> > end = start + len;
> > if (end <= start)
> > return -ENOMEM;
> > - if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
> > + if (!arch_validate_prot(prot))
> > return -EINVAL;
> >
> > reqprot = prot;
> >
> > --
--
David Kleikamp
IBM Linux Technology Center
^ permalink raw reply
* [PATCH] IB/ehca: Make device table externally visible
From: Joachim Fenkes @ 2008-07-01 14:14 UTC (permalink / raw)
To: LinuxPPC-Dev, LKML, OF-General, Roland Dreier, OF-EWG
Cc: Christoph Raisch, Stefan Roscher
In-Reply-To: <48499C11.7030504@gmail.com>
This gives ehca an autogenerated modalias and therefore enables automatic loading.
Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com>
---
drivers/infiniband/hw/ehca/ehca_main.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 482103e..598844d 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -923,6 +923,7 @@ static struct of_device_id ehca_device_table[] =
},
{},
};
+MODULE_DEVICE_TABLE(of, ehca_device_table);
static struct of_platform_driver ehca_driver = {
.name = "ehca",
--
1.5.5
^ permalink raw reply related
* Re: [PATCH] powerpc: fixup lwsync at runtime
From: Kumar Gala @ 2008-07-01 14:48 UTC (permalink / raw)
To: michael; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <1214893753.8055.13.camel@localhost>
On Jul 1, 2008, at 1:29 AM, Michael Ellerman wrote:
> On Tue, 2008-07-01 at 00:32 -0500, Kumar Gala wrote:
>> To allow for a single kernel image on e500 v1/v2/mc we need to
>> fixup lwsync
>> at runtime. On e500v1/v2 lwsync causes an illop so we need to
>> patch up
>> the code. We default to 'sync' since that is always safe and if
>> the cpu
>> is capable we will replace 'sync' with 'lwsync'.
>>
>> We introduce CPU_FTR_LWSYNC as a way to determine at runtime if
>> this is
>> needed. This flag could be moved elsewhere since we dont really
>> use it
>> for the normal CPU_FTR purpose.
>>
>> Finally we only store the relative offset in the fixup section to
>> keep it
>> as small as possible rather than using a full fixup_entry.
>
> How many entries are we talking? I guess it's not much bother to
> have a
> separate section.
On the order of 1000 entries for an SMP build.
>> diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/
>> setup_32.c
>> index 9e83add..0109e7f 100644
>> --- a/arch/powerpc/kernel/setup_32.c
>> +++ b/arch/powerpc/kernel/setup_32.c
>> @@ -101,6 +101,10 @@ unsigned long __init early_init(unsigned long
>> dt_ptr)
>> PTRRELOC(&__start___ftr_fixup),
>> PTRRELOC(&__stop___ftr_fixup));
>>
>> + do_lwsync_fixups(spec->cpu_features,
>> + PTRRELOC(&__start___lwsync_fixup),
>> + PTRRELOC(&__stop___lwsync_fixup));
>> +
>
> This could be changed to use cur_cpu_spec->cpu_features, and then all
> the call sites would be passing that, which would mean
> do_lwsync_fixups() could just check cur_cpu_spec->cpu_features
> directly.
cur_cpu_spec and spec at this point arent the same thing.
will post a new version w/fixes.
- k
^ permalink raw reply
* Re: AZFS file system proposal
From: Arnd Bergmann @ 2008-07-01 14:59 UTC (permalink / raw)
To: Maxim Shchetynin; +Cc: linux-fsdevel, linuxppc-dev, linux-kernel
In-Reply-To: <20080618160629.6cd749a8@mercedes-benz.boeblingen.de.ibm.com>
On Wednesday 18 June 2008, Maxim Shchetynin wrote:
> AZFS patch updated accordinly to comments of Christoph Hellwig and Dmitri Vorobiev.
Sorry for my not commenting earlier on this. I'm finally collecting my
2.6.27 patches and stumbled over it again. There are a few details
that I hope we can fix up quickly, other than that, it looks good now,
great work!
> Subject: azfs: initial submit of azfs, a non-buffered filesystem
Please make the patch subject the actual subject of your email next time,
and put the introductory text below the Signed-off-by: lines, separated
by a "---" line. That will make the standard tools work without extra
effort on my side. Also, please always Cc the person you want to merge
the patch, in this case probably me.
> diff -Nuar linux-2.6.26-rc6/fs/Makefile linux-2.6.26-rc6-azfs/fs/Makefile
> --- linux-2.6.26-rc6/fs/Makefile 2008-06-12 23:22:24.000000000 +0200
> +++ linux-2.6.26-rc6-azfs/fs/Makefile 2008-06-16 11:17:50.000000000 +0200
> @@ -119,3 +119,4 @@
> obj-$(CONFIG_DEBUG_FS) += debugfs/
> obj-$(CONFIG_OCFS2_FS) += ocfs2/
> obj-$(CONFIG_GFS2_FS) += gfs2/
> +obj-$(CONFIG_AZ_FS) += azfs.o
> diff -Nuar linux-2.6.26-rc6/fs/azfs.c linux-2.6.26-rc6-azfs/fs/azfs.c
> --- linux-2.6.26-rc6/fs/azfs.c 1970-01-01 01:00:00.000000000 +0100
> +++ linux-2.6.26-rc6-azfs/fs/azfs.c 2008-06-18 15:56:13.252266896 +0200
All other file systems are in separate directories, so it would be better
to rename fs/azfs.c to fs/azfs/inode.c
> +#define AZFS_FILESYSTEM_NAME "azfs"
> +#define AZFS_FILESYSTEM_FLAGS FS_REQUIRES_DEV
> +
> +#define AZFS_SUPERBLOCK_MAGIC 0xABBA1972
> +#define AZFS_SUPERBLOCK_FLAGS MS_NOEXEC | \
> + MS_SYNCHRONOUS | \
> + MS_DIRSYNC | \
> + MS_ACTIVE
Why MS_NOEXEC? What happens on a remount if the user does not specifies
-o remount,exec?
> +/**
> + * azfs_block_find - get real address of a part of a file
> + * @inode: inode
> + * @direction: data direction
> + * @from: offset for read/write operation
> + * @size: pointer to a value of the amount of data to be read/written
> + */
> +static unsigned long
> +azfs_block_find(struct inode *inode, enum azfs_direction direction,
> + unsigned long from, unsigned long *size)
> +{
> + struct azfs_super *super;
> + struct azfs_znode *znode;
> + struct azfs_block *block;
> + unsigned long block_id, west, east;
> +
> + super = inode->i_sb->s_fs_info;
> + znode = I2Z(inode);
> +
> + if (from + *size > znode->size) {
> + i_size_write(inode, from + *size);
> + inode->i_op->truncate(inode);
> + }
> +
> + read_lock(&znode->lock);
> +
> + if (list_empty(&znode->block_list)) {
> + read_unlock(&znode->lock);
> + return 0;
> + }
> +
> + block_id = from >> super->block_shift;
> +
> + for_each_block(block, &znode->block_list) {
> + if (block->count > block_id)
> + break;
> + block_id -= block->count;
> + }
> +
> + west = from % super->block_size;
> + east = ((block->count - block_id) << super->block_shift) - west;
> +
> + if (*size > east)
> + *size = east;
> +
> + block_id = ((block->id + block_id) << super->block_shift) + west;
> +
> + read_unlock(&znode->lock);
> +
> + block_id += direction == AZFS_MMAP ? super->ph_addr : super->io_addr;
> +
> + return block_id;
> +}
This overloading of the return type to mean either a pointer or an offset
on the block device is rather confusing. Why not just return the raw block_id
before the last += and leave that part up to the caller?
static void __iomem *
azfs_block_addr(struct inode *inode, enum azfs_direction direction,
unsigned long from, unsigned long *size)
{
struct azfs_super *super;
unsigned long offset;
void __iomem *p;
super = inode->i_sb->s_fs_info;
offset = azfs_block_find(inode, super, 0, from, size);
p = super->ph_addr + offset;
return p;
}
> + target = iov->iov_base;
> + todo = min((loff_t) iov->iov_len, i_size_read(inode) - pos);
> +
> + for (step = todo; step; step -= size) {
> + size = step;
> + pin = azfs_block_find(inode, AZFS_READ, pos, &size);
> + if (!pin) {
> + rc = -ENOSPC;
> + goto out;
> + }
> + if (copy_to_user(target, (void*) pin, size)) {
> + rc = -EFAULT;
> + goto out;
> + }
Question to the powerpc folks: is copy_to_user safe for an __iomem source?
Should there be two copies (memcpy_fromio and copy_to_user) instead?
> + page_prot = pgprot_val(vma->vm_page_prot);
> + page_prot |= (_PAGE_NO_CACHE | _PAGE_RW);
> + page_prot &= ~_PAGE_GUARDED;
> + vma->vm_page_prot = __pgprot(page_prot);
The pgprot modifications rely on powerpc specific flags, but the
file system should not really need to be powerpc only.
The flags we want are more or less the same as PAGE_AGP, because
both are I/O mapped memory that needs to be uncached but should
not be guarded, for performance reasons.
Maybe we can introduce a new PAGE_IOMEM here that we can use
in all places that need something like this. In spufs we need
the same flags for the local store mappings.
I wouldn't hold up merging the file system for this problem, but
until it is solved, the Kconfig entry should probably have
a "depends on PPC".
Arnd <><
^ permalink raw reply
* Re: [PATCH 2/2] Add the of_find_i2c_device_by_node function, V4
From: Jean Delvare @ 2008-07-01 15:05 UTC (permalink / raw)
To: Jon Smirl; +Cc: Linuxppc-dev, Paul Mackerras, i2c
In-Reply-To: <20080630230128.12482.79570.stgit@terra>
Hi Jon,
On Mon, 30 Jun 2008 19:01:28 -0400, Jon Smirl wrote:
> Add the of_find_i2c_device_by_node function. This allows you to
> follow a reference in the device to an i2c device node and then
> locate the linux device instantiated by the device tree. Example
> use, an i2s codec controlled by i2c.
> ---
>
> drivers/i2c/i2c-core.c | 2 +-
> drivers/of/of_i2c.c | 37 ++++++++++++++++++++++++++-----------
> include/linux/i2c.h | 3 +++
> include/linux/of_i2c.h | 2 ++
> 4 files changed, 32 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
> index d0175f4..e3abe1b 100644
> --- a/drivers/i2c/i2c-core.c
> +++ b/drivers/i2c/i2c-core.c
> @@ -208,7 +208,7 @@ static struct device_attribute i2c_dev_attrs[] = {
> { },
> };
>
> -static struct bus_type i2c_bus_type = {
> +struct bus_type i2c_bus_type = {
> .name = "i2c",
> .dev_attrs = i2c_dev_attrs,
> .match = i2c_device_match,
What if i2c-core is built as a module? Don't you need to export the
symbol then?
> diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
> index 715a444..ca69a16 100644
> --- a/drivers/of/of_i2c.c
> +++ b/drivers/of/of_i2c.c
> @@ -75,7 +75,7 @@ static int of_find_i2c_driver(struct device_node *node,
> void of_register_i2c_devices(struct i2c_adapter *adap,
> struct device_node *adap_node)
> {
> - void *result;
> + struct i2c_client *i2c_dev;
> struct device_node *node;
>
> for_each_child_of_node(adap_node, node) {
> @@ -90,29 +90,44 @@ void of_register_i2c_devices(struct i2c_adapter *adap,
> continue;
> }
>
> - info.irq = irq_of_parse_and_map(node, 0);
> - if (info.irq == NO_IRQ)
> - info.irq = -1;
> -
> - if (of_find_i2c_driver(node, &info) < 0) {
> - irq_dispose_mapping(info.irq);
> + if (of_find_i2c_driver(node, &info) < 0)
> continue;
> - }
>
> + info.irq = irq_of_parse_and_map(node, 0);
> info.addr = *addr;
>
> - request_module(info.type);
> + request_module("%s", info.type);
A separate fix for this issue was already sent by Maximilian Attems a
few days go:
http://lists.lm-sensors.org/pipermail/i2c/2008-June/004030.html
>
> - result = i2c_new_device(adap, &info);
> - if (result == NULL) {
> + i2c_dev = i2c_new_device(adap, &info);
> + if (i2c_dev == NULL) {
> printk(KERN_ERR
> "of-i2c: Failed to load driver for %s\n",
> info.type);
> irq_dispose_mapping(info.irq);
> continue;
> }
> +
> + i2c_dev->dev.archdata.of_node = of_node_get(node);
> }
> }
> EXPORT_SYMBOL(of_register_i2c_devices);
>
> +static int of_dev_node_match(struct device *dev, void *data)
> +{
> + return dev->archdata.of_node == data;
> +}
> +
> +struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
> +{
> + struct device *dev;
> +
> + dev = bus_find_device(&i2c_bus_type, NULL, node,
> + of_dev_node_match);
> + if (!dev)
> + return NULL;
> +
> + return to_i2c_client(dev);
> +}
> +EXPORT_SYMBOL(of_find_i2c_device_by_node);
> +
> MODULE_LICENSE("GPL");
> diff --git a/include/linux/i2c.h b/include/linux/i2c.h
> index fb9af6a..186b22d 100644
> --- a/include/linux/i2c.h
> +++ b/include/linux/i2c.h
> @@ -92,6 +92,9 @@ extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
> extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client,
> u8 command, u8 length,
> const u8 *values);
> +
> +/* Base of the i2c bus */
> +extern struct bus_type i2c_bus_type;
>
> /*
> * A driver is capable of handling one or more physical devices present on
> diff --git a/include/linux/of_i2c.h b/include/linux/of_i2c.h
> index bd2a870..17d5897 100644
> --- a/include/linux/of_i2c.h
> +++ b/include/linux/of_i2c.h
> @@ -16,5 +16,7 @@
>
> void of_register_i2c_devices(struct i2c_adapter *adap,
> struct device_node *adap_node);
> +struct i2c_client *of_find_i2c_device_by_node(struct device_node *node);
> +
>
> #endif /* __LINUX_OF_I2C_H */
I'm fine with this patch. In particular, exporting i2c_bus_type is OK.
It was un-exported only because it had no user left, but it can be
exported again if needed.
I'm not the one to push this upstream though, as the patch is
essentially an openfirmware patch. That would be something for Jochen
Friedrich and Paul Mackerras I guess. Would be nice to have a
MAINTAINERS entry for OF...
--
Jean Delvare
^ permalink raw reply
* Re: linux-next: manual merge of the net tree
From: Stephen Rothwell @ 2008-07-01 15:09 UTC (permalink / raw)
To: David Miller
Cc: linuxppc-dev, linux-next, Paul Mackerras, Jason Jin, Jeff Garzik
In-Reply-To: <20080701171940.6f282113.sfr@canb.auug.org.au>
[-- Attachment #1: Type: text/plain, Size: 391 bytes --]
On Tue, 1 Jul 2008 17:19:40 +1000 Stephen Rothwell <sfr@canb.auug.org.au> wrote:
>
> Hi Dave,
>
> Today's linux-next merge of the net tree got a conflict in between
^
Documentation/powerpc/booting-without-of.txt
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Re: [PATCH 2/2] Add the of_find_i2c_device_by_node function, V4
From: Jon Smirl @ 2008-07-01 15:12 UTC (permalink / raw)
To: Jean Delvare; +Cc: Linuxppc-dev, Paul Mackerras, i2c
In-Reply-To: <20080701170544.72051418@hyperion.delvare>
On 7/1/08, Jean Delvare <khali@linux-fr.org> wrote:
> I'm fine with this patch. In particular, exporting i2c_bus_type is OK.
> It was un-exported only because it had no user left, but it can be
> exported again if needed.
Another solution would be to move drivers/of/of_i2c into the i2c
directory and make it part of i2c core on powerpc builds.
> I'm not the one to push this upstream though, as the patch is
> essentially an openfirmware patch. That would be something for Jochen
> Friedrich and Paul Mackerras I guess. Would be nice to have a
> MAINTAINERS entry for OF...
>
> --
>
> Jean Delvare
>
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply
* [PATCH v2 1/2] powerpc: Fix building of feature-fixup tests on ppc32
From: Kumar Gala @ 2008-07-01 15:16 UTC (permalink / raw)
To: linuxppc-dev
We need to use PPC_LCMPI otherwise we get compile errors like:
arch/powerpc/lib/feature-fixups-test.S: Assembler messages:
arch/powerpc/lib/feature-fixups-test.S:142: Error: Unrecognized opcode: `cmpdi'
arch/powerpc/lib/feature-fixups-test.S:149: Error: Unrecognized opcode: `cmpdi'
arch/powerpc/lib/feature-fixups-test.S:164: Error: Unrecognized opcode: `cmpdi'
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
arch/powerpc/lib/feature-fixups-test.S | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/lib/feature-fixups-test.S b/arch/powerpc/lib/feature-fixups-test.S
index 10d038b..0549be0 100644
--- a/arch/powerpc/lib/feature-fixups-test.S
+++ b/arch/powerpc/lib/feature-fixups-test.S
@@ -139,14 +139,14 @@ globl(ftr_fixup_test6)
1: or 1,1,1
BEGIN_FTR_SECTION
or 5,5,5
-2: cmpdi r3,0
+2: PPC_LCMPI r3,0
beq 4f
blt 2b
b 1b
b 4f
FTR_SECTION_ELSE
2: or 2,2,2
- cmpdi r3,1
+ PPC_LCMPI r3,1
beq 3f
blt 2b
b 3f
@@ -161,7 +161,7 @@ globl(end_ftr_fixup_test6)
globl(ftr_fixup_test6_expected)
1: or 1,1,1
2: or 2,2,2
- cmpdi r3,1
+ PPC_LCMPI r3,1
beq 3f
blt 2b
b 3f
--
1.5.5.1
^ permalink raw reply related
* [PATCH v2 2/2] powerpc: fixup lwsync at runtime
From: Kumar Gala @ 2008-07-01 15:16 UTC (permalink / raw)
To: linuxppc-dev
To allow for a single kernel image on e500 v1/v2/mc we need to fixup lwsync
at runtime. On e500v1/v2 lwsync causes an illop so we need to patch up
the code. We default to 'sync' since that is always safe and if the cpu
is capable we will replace 'sync' with 'lwsync'.
We introduce CPU_FTR_LWSYNC as a way to determine at runtime if this is
needed. This flag could be moved elsewhere since we dont really use it
for the normal CPU_FTR purpose.
Finally we only store the relative offset in the fixup section to keep it
as small as possible rather than using a full fixup_entry.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
* Moved and fixed up LWSYNC macros to feature-fixups.h
* Added lwsync test case to feature-fixups
* Reworked synch.h to be usable in asm code.
- k
arch/powerpc/kernel/module.c | 6 +++++
arch/powerpc/kernel/setup_32.c | 4 +++
arch/powerpc/kernel/setup_64.c | 2 +
arch/powerpc/kernel/vdso.c | 10 ++++++++
arch/powerpc/kernel/vdso32/vdso32.lds.S | 3 ++
arch/powerpc/kernel/vdso64/vdso64.lds.S | 3 ++
arch/powerpc/kernel/vmlinux.lds.S | 6 +++++
arch/powerpc/lib/feature-fixups-test.S | 15 ++++++++++++
arch/powerpc/lib/feature-fixups.c | 36 +++++++++++++++++++++++++++++
include/asm-powerpc/code-patching.h | 3 +-
include/asm-powerpc/cputable.h | 21 +++++++++--------
include/asm-powerpc/feature-fixups.h | 10 ++++++++
include/asm-powerpc/synch.h | 38 ++++++++++++++++++------------
13 files changed, 131 insertions(+), 26 deletions(-)
diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c
index 40dd52d..af07003 100644
--- a/arch/powerpc/kernel/module.c
+++ b/arch/powerpc/kernel/module.c
@@ -86,6 +86,12 @@ int module_finalize(const Elf_Ehdr *hdr,
(void *)sect->sh_addr + sect->sh_size);
#endif
+ sect = find_section(hdr, sechdrs, "__lwsync_fixup");
+ if (sect != NULL)
+ do_lwsync_fixups(cur_cpu_spec->cpu_features,
+ (void *)sect->sh_addr,
+ (void *)sect->sh_addr + sect->sh_size);
+
return 0;
}
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 9e83add..0109e7f 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -101,6 +101,10 @@ unsigned long __init early_init(unsigned long dt_ptr)
PTRRELOC(&__start___ftr_fixup),
PTRRELOC(&__stop___ftr_fixup));
+ do_lwsync_fixups(spec->cpu_features,
+ PTRRELOC(&__start___lwsync_fixup),
+ PTRRELOC(&__stop___lwsync_fixup));
+
return KERNELBASE + offset;
}
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 098fd96..04d8de9 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -363,6 +363,8 @@ void __init setup_system(void)
&__start___ftr_fixup, &__stop___ftr_fixup);
do_feature_fixups(powerpc_firmware_features,
&__start___fw_ftr_fixup, &__stop___fw_ftr_fixup);
+ do_lwsync_fixups(cur_cpu_spec->cpu_features,
+ &__start___lwsync_fixup, &__stop___lwsync_fixup);
/*
* Unflatten the device-tree passed by prom_init or kexec
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index ce245a8..f177c60 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -571,6 +571,11 @@ static __init int vdso_fixup_features(struct lib32_elfinfo *v32,
if (start64)
do_feature_fixups(powerpc_firmware_features,
start64, start64 + size64);
+
+ start64 = find_section64(v64->hdr, "__lwsync_fixup", &size64);
+ if (start64)
+ do_lwsync_fixups(cur_cpu_spec->cpu_features,
+ start64, start64 + size64);
#endif /* CONFIG_PPC64 */
start32 = find_section32(v32->hdr, "__ftr_fixup", &size32);
@@ -585,6 +590,11 @@ static __init int vdso_fixup_features(struct lib32_elfinfo *v32,
start32, start32 + size32);
#endif /* CONFIG_PPC64 */
+ start32 = find_section32(v32->hdr, "__lwsync_fixup", &size32);
+ if (start32)
+ do_lwsync_fixups(cur_cpu_spec->cpu_features,
+ start32, start32 + size32);
+
return 0;
}
diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S
index 2717935..be3b6a4 100644
--- a/arch/powerpc/kernel/vdso32/vdso32.lds.S
+++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S
@@ -33,6 +33,9 @@ SECTIONS
. = ALIGN(8);
__ftr_fixup : { *(__ftr_fixup) }
+ . = ALIGN(8);
+ __lwsync_fixup : { *(__lwsync_fixup) }
+
#ifdef CONFIG_PPC64
. = ALIGN(8);
__fw_ftr_fixup : { *(__fw_ftr_fixup) }
diff --git a/arch/powerpc/kernel/vdso64/vdso64.lds.S b/arch/powerpc/kernel/vdso64/vdso64.lds.S
index e608d1b..d0b2526 100644
--- a/arch/powerpc/kernel/vdso64/vdso64.lds.S
+++ b/arch/powerpc/kernel/vdso64/vdso64.lds.S
@@ -35,6 +35,9 @@ SECTIONS
__ftr_fixup : { *(__ftr_fixup) }
. = ALIGN(8);
+ __lwsync_fixup : { *(__lwsync_fixup) }
+
+ . = ALIGN(8);
__fw_ftr_fixup : { *(__fw_ftr_fixup) }
/*
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 3c07811..6856f6c 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -127,6 +127,12 @@ SECTIONS
*(__ftr_fixup)
__stop___ftr_fixup = .;
}
+ . = ALIGN(8);
+ __lwsync_fixup : AT(ADDR(__lwsync_fixup) - LOAD_OFFSET) {
+ __start___lwsync_fixup = .;
+ *(__lwsync_fixup)
+ __stop___lwsync_fixup = .;
+ }
#ifdef CONFIG_PPC64
. = ALIGN(8);
__fw_ftr_fixup : AT(ADDR(__fw_ftr_fixup) - LOAD_OFFSET) {
diff --git a/arch/powerpc/lib/feature-fixups-test.S b/arch/powerpc/lib/feature-fixups-test.S
index 0549be0..cb73748 100644
--- a/arch/powerpc/lib/feature-fixups-test.S
+++ b/arch/powerpc/lib/feature-fixups-test.S
@@ -10,6 +10,7 @@
#include <asm/feature-fixups.h>
#include <asm/ppc_asm.h>
+#include <asm/synch.h>
.text
@@ -725,3 +726,17 @@ MAKE_MACRO_TEST_EXPECTED(FTR);
MAKE_MACRO_TEST(FW_FTR);
MAKE_MACRO_TEST_EXPECTED(FW_FTR);
#endif
+
+globl(lwsync_fixup_test)
+1: or 1,1,1
+ LWSYNC
+globl(end_lwsync_fixup_test)
+
+globl(lwsync_fixup_test_expected_LWSYNC)
+1: or 1,1,1
+ lwsync
+
+globl(lwsync_fixup_test_expected_SYNC)
+1: or 1,1,1
+ sync
+
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c
index 48e1ed8..4e43702 100644
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -110,6 +110,22 @@ void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end)
}
}
+void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
+{
+ unsigned int *start, *end, *dest;
+
+ if (!(value & CPU_FTR_LWSYNC))
+ return ;
+
+ start = fixup_start;
+ end = fixup_end;
+
+ for (; start < end; start++) {
+ dest = (void *)start + *start;
+ patch_instruction(dest, PPC_LWSYNC_INSTR);
+ }
+}
+
#ifdef CONFIG_FTR_FIXUP_SELFTEST
#define check(x) \
@@ -295,6 +311,25 @@ static void test_fw_macros(void)
#endif
}
+static void test_lwsync_macros(void)
+{
+ extern void lwsync_fixup_test;
+ extern void end_lwsync_fixup_test;
+ extern void lwsync_fixup_test_expected_LWSYNC;
+ extern void lwsync_fixup_test_expected_SYNC;
+ unsigned long size = &end_lwsync_fixup_test -
+ &lwsync_fixup_test;
+
+ /* The fixups have already been done for us during boot */
+ if (cur_cpu_spec->cpu_features & CPU_FTR_LWSYNC) {
+ check(memcmp(&lwsync_fixup_test,
+ &lwsync_fixup_test_expected_LWSYNC, size) == 0);
+ } else {
+ check(memcmp(&lwsync_fixup_test,
+ &lwsync_fixup_test_expected_SYNC, size) == 0);
+ }
+}
+
static int __init test_feature_fixups(void)
{
printk(KERN_DEBUG "Running feature fixup self-tests ...\n");
@@ -307,6 +342,7 @@ static int __init test_feature_fixups(void)
test_alternative_case_with_external_branch();
test_cpu_macros();
test_fw_macros();
+ test_lwsync_macros();
return 0;
}
diff --git a/include/asm-powerpc/code-patching.h b/include/asm-powerpc/code-patching.h
index ef3a5d1..107d9b9 100644
--- a/include/asm-powerpc/code-patching.h
+++ b/include/asm-powerpc/code-patching.h
@@ -12,7 +12,8 @@
#include <asm/types.h>
-#define PPC_NOP_INSTR 0x60000000
+#define PPC_NOP_INSTR 0x60000000
+#define PPC_LWSYNC_INSTR 0x7c2004ac
/* Flags for create_branch:
* "b" == create_branch(addr, target, 0);
diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h
index 4e4491c..3171ac9 100644
--- a/include/asm-powerpc/cputable.h
+++ b/include/asm-powerpc/cputable.h
@@ -156,6 +156,7 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
#define CPU_FTR_UNIFIED_ID_CACHE ASM_CONST(0x0000000001000000)
#define CPU_FTR_SPE ASM_CONST(0x0000000002000000)
#define CPU_FTR_NEED_PAIRED_STWCX ASM_CONST(0x0000000004000000)
+#define CPU_FTR_LWSYNC ASM_CONST(0x0000000008000000)
/*
* Add the 64-bit processor unique features in the top half of the word;
@@ -369,43 +370,43 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
CPU_FTR_NODSISRALIGN)
#define CPU_FTRS_E500MC (CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | \
CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_BIG_PHYS | CPU_FTR_NODSISRALIGN | \
- CPU_FTR_L2CSR)
+ CPU_FTR_L2CSR | CPU_FTR_LWSYNC)
#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN)
/* 64-bit CPUs */
-#define CPU_FTRS_POWER3 (CPU_FTR_USE_TB | \
+#define CPU_FTRS_POWER3 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | CPU_FTR_PPC_LE)
-#define CPU_FTRS_RS64 (CPU_FTR_USE_TB | \
+#define CPU_FTRS_RS64 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | \
CPU_FTR_MMCRA | CPU_FTR_CTRL)
-#define CPU_FTRS_POWER4 (CPU_FTR_USE_TB | \
+#define CPU_FTRS_POWER4 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_MMCRA)
-#define CPU_FTRS_PPC970 (CPU_FTR_USE_TB | \
+#define CPU_FTRS_PPC970 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA)
-#define CPU_FTRS_POWER5 (CPU_FTR_USE_TB | \
+#define CPU_FTRS_POWER5 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_MMCRA | CPU_FTR_SMT | \
CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
CPU_FTR_PURR)
-#define CPU_FTRS_POWER6 (CPU_FTR_USE_TB | \
+#define CPU_FTRS_POWER6 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_MMCRA | CPU_FTR_SMT | \
CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
CPU_FTR_DSCR)
-#define CPU_FTRS_POWER7 (CPU_FTR_USE_TB | \
+#define CPU_FTRS_POWER7 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_MMCRA | CPU_FTR_SMT | \
CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
CPU_FTR_DSCR)
-#define CPU_FTRS_CELL (CPU_FTR_USE_TB | \
+#define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE | CPU_FTR_CELL_TB_BUG)
-#define CPU_FTRS_PA6T (CPU_FTR_USE_TB | \
+#define CPU_FTRS_PA6T (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_CI_LARGE_PAGE | \
CPU_FTR_PURR | CPU_FTR_REAL_LE | CPU_FTR_NO_SLBIE_B)
diff --git a/include/asm-powerpc/feature-fixups.h b/include/asm-powerpc/feature-fixups.h
index ab30129..a102996 100644
--- a/include/asm-powerpc/feature-fixups.h
+++ b/include/asm-powerpc/feature-fixups.h
@@ -113,4 +113,14 @@ label##5: \
#endif /* __ASSEMBLY__ */
+/* LWSYNC feature sections */
+#define START_LWSYNC_SECTION(label) label##1:
+#define MAKE_LWSYNC_SECTION_ENTRY(label, sect) \
+label##2: \
+ .pushsection sect,"a"; \
+ .align 2; \
+label##3: \
+ .long label##1b-label##3b; \
+ .popsection;
+
#endif /* __ASM_POWERPC_FEATURE_FIXUPS_H */
diff --git a/include/asm-powerpc/synch.h b/include/asm-powerpc/synch.h
index 42a1ef5..45963e8 100644
--- a/include/asm-powerpc/synch.h
+++ b/include/asm-powerpc/synch.h
@@ -3,34 +3,42 @@
#ifdef __KERNEL__
#include <linux/stringify.h>
+#include <asm/feature-fixups.h>
-#if defined(__powerpc64__) || defined(CONFIG_PPC_E500MC)
-#define __SUBARCH_HAS_LWSYNC
-#endif
+#ifndef __ASSEMBLY__
+extern unsigned int __start___lwsync_fixup, __stop___lwsync_fixup;
+extern void do_lwsync_fixups(unsigned long value, void *fixup_start,
+ void *fixup_end);
+
+static inline void eieio(void)
+{
+ __asm__ __volatile__ ("eieio" : : : "memory");
+}
+
+static inline void isync(void)
+{
+ __asm__ __volatile__ ("isync" : : : "memory");
+}
+#endif /* __ASSEMBLY__ */
-#ifdef __SUBARCH_HAS_LWSYNC
+#if defined(__powerpc64__)
# define LWSYNC lwsync
+#elif defined(CONFIG_E500)
+# define LWSYNC \
+ START_LWSYNC_SECTION(96); \
+ sync; \
+ MAKE_LWSYNC_SECTION_ENTRY(96, __lwsync_fixup);
#else
# define LWSYNC sync
#endif
#ifdef CONFIG_SMP
#define ISYNC_ON_SMP "\n\tisync\n"
-#define LWSYNC_ON_SMP __stringify(LWSYNC) "\n"
+#define LWSYNC_ON_SMP stringify_in_c(LWSYNC) "\n"
#else
#define ISYNC_ON_SMP
#define LWSYNC_ON_SMP
#endif
-static inline void eieio(void)
-{
- __asm__ __volatile__ ("eieio" : : : "memory");
-}
-
-static inline void isync(void)
-{
- __asm__ __volatile__ ("isync" : : : "memory");
-}
-
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_SYNCH_H */
--
1.5.5.1
^ permalink raw reply related
* Cascaded interrupt controller causing unbalanced interrupt.
From: Welch, Martyn (GE EntSol, Intelligent Platforms) @ 2008-07-01 15:07 UTC (permalink / raw)
To: linuxppc-dev
Hi,
I'm having a spot of trouble writing a driver for a cascaded interrupt
handler used on one of our boards (8641D based board), patches to be
forth-coming as soon as I have access to this list without Outlook (I'm
working on it!).
I have attached the driver at the bottom of the email for reference
(sorry for the long email).
The driver is cascaded like this:
static void __init
gef_sbc610_init_irq(void)
{
struct mpic *mpic1;
struct device_node *np, *cascade_node = NULL;
struct resource res;
/* Determine MPIC address. */
np = of_find_node_by_type(NULL, "open-pic");
if (np == NULL)
return;
of_address_to_resource(np, 0, &res);
mpic1 = mpic_alloc(np, res.start,
MPIC_PRIMARY | MPIC_WANTS_RESET |
MPIC_BIG_ENDIAN,
0, 256, "mpic");
of_node_put(np);
BUG_ON(mpic1 == NULL);
mpic_init(mpic1);
/*
* There is a simple interrupt handler in the main FPGA,
this
* needs To be cascaded into the MPIC
*/
cascade_node = of_find_compatible_node(NULL, NULL,
"gef,fpga-pic");
if(!cascade_node) {
printk(KERN_WARNING "SBC610: No FPGA PIC\n");
return;
}
gef_pic_init(cascade_node);
of_node_put(cascade_node);
}
The cascaded interrupt controller is connected to the 8641D's mpic on
interrupts 8 & 9, from the DTS file:
gef_pic: pic@4,4000 {
#interrupt-cells = <2>;
interrupt-controller;
device_type = "interrupt-controller";
compatible = "gef,fpga-pic";
reg = <0x4 0x4000 0x20>;
interrupts = <0x8 0x1
0x9 0x1>;
interrupt-parent = <&mpic>;
};
The interrupts from the phys are connected to the cascaded interrupt
controller:
phy0: ethernet-phy@0 {
#interrupt-cells = <2>;
interrupt-parent = <&gef_pic>;
interrupts = <0x16 0x4>;
reg = <0x00000001>;
device_type = "ethernet-phy";
};
phy2: ethernet-phy@2 {
#interrupt-cells = <2>;
interrupt-parent = <&gef_pic>;
interrupts = <0x17 0x4>;
reg = <0x00000003>;
device_type = "ethernet-phy";
};
When I boot (with the debugging turned on) I see the following:
mpic: Setting up MPIC "mpic" version 1.2 at fef40000, max 2 CPUs
mpic: ISU size: 88, shift: 7, mask: 7f
mpic: Initializing for 88 sources
gef_pic: gef_pic_init(/localbus@fef05000/pic@4,4000)
gef_pic: cascade mapped to irq 16
gef_pic: Setting up GEF FPGA pic at fdbf4000
...
gef_pic: gef_pic_host_xlate()
gef_pic: Setting flags from intspec:4
gef_pic: gef_pic_host_map(/localbus@fef05000/pic@4,4000, 22, 16)
gef_pic: map virq 22, hwirq 0x16
gef_pic: gef_pic_host_xlate()
gef_pic: Setting flags from intspec:4
gef_pic: gef_pic_host_map(/localbus@fef05000/pic@4,4000, 23, 17)
gef_pic: map virq 23, hwirq 0x17
...
gef_pic: Unmasking virtual interrupt 22, hw:22
Unbalanced enable for IRQ 22
------------[ cut here ]------------
Badness at c0055868 [verbose debug info unavailable]
NIP: c0055868 LR: c0055868 CTR: c01b3eb0
REGS: ef85be60 TRAP: 0700 Not tainted (2.6.26-rc8-13367-g62635be)
MSR: 00021032 <ME,IR,DR> CR: 22000022 XER: 00000000
TASK = ef859970[10] 'events/1' THREAD: ef85a000 CPU: 1
GPR00: c0055868 ef85bf10 ef859970 00000020 00000001 00000001 00000000
00004000
GPR08: 00000001 00000000 000063f1 c03d0000 42000082 00000000 0ff4ce00
00000001
GPR16: c03c3040 c03a97f0 c03b0000 c03a97f0 ef843f9c ef843f98 c03b0000
00000000
GPR24: c0040000 c0330000 ef85a000 c01b1b40 c03c3a90 00009032 c03c3a60
c03c3a60
NIP [c0055868] __enable_irq+0x50/0x84
LR [c0055868] __enable_irq+0x50/0x84
Call Trace:
[ef85bf10] [c0055868] __enable_irq+0x50/0x84 (unreliable)
[ef85bf20] [c0055cf8] enable_irq+0x50/0x70
[ef85bf40] [c01b1ba8] phy_change+0x68/0x108
[ef85bf60] [c003ade4] run_workqueue+0xac/0x15c
[ef85bf90] [c003b330] worker_thread+0x74/0xd4
[ef85bfd0] [c003f3bc] kthread+0x48/0x84
[ef85bff0] [c00115f0] kernel_thread+0x44/0x60
Instruction dump:
419e0024 419a0044 3809ffff 901f001c 80010014 83e1000c 38210010 7c0803a6
4e800020 3c60c033 3863f3a0 4bfd28c5 <0fe00000> 80010014 83e1000c
38210010
...
gef_pic: Unmasking virtual interrupt 23, hw:23
Unbalanced enable for IRQ 23
------------[ cut here ]------------
Badness at c0055868 [verbose debug info unavailable]
NIP: c0055868 LR: c0055868 CTR: c01b3eb0
REGS: ef857e60 TRAP: 0700 Not tainted (2.6.26-rc8-13367-g62635be)
MSR: 00021032 <ME,IR,DR> CR: 22000022 XER: 00000000
TASK = ef84a050[9] 'events/0' THREAD: ef856000 CPU: 0
GPR00: c0055868 ef857f10 ef84a050 00000020 00000001 00000001 00000000
00004000
GPR08: 00000001 00000000 00006a3b c03d0000 42000082 00000000 0ff4ce00
00000001
GPR16: c03c3040 c03a97f0 c03b0000 c03a97f0 ef843f9c ef843f98 c03b0000
00000000
GPR24: c0040000 c0330000 ef856000 c01b1b40 c03c3af0 00009032 c03c3ac0
c03c3ac0
NIP [c0055868] __enable_irq+0x50/0x84
LR [c0055868] __enable_irq+0x50/0x84
Call Trace:
[ef857f10] [c0055868] __enable_irq+0x50/0x84 (unreliable)
[ef857f20] [c0055cf8] enable_irq+0x50/0x70
[ef857f40] [c01b1ba8] phy_change+0x68/0x108
[ef857f60] [c003ade4] run_workqueue+0xac/0x15c
[ef857f90] [c003b330] worker_thread+0x74/0xd4
[ef857fd0] [c003f3bc] kthread+0x48/0x84
[ef857ff0] [c00115f0] kernel_thread+0x44/0x60
Instruction dump:
419e0024 419a0044 3809ffff 901f001c 80010014 83e1000c 38210010 7c0803a6
4e800020 3c60c033 3863f3a0 4bfd28c5 <0fe00000> 80010014 83e1000c
38210010
The interrupts are reported as being setup like this:
# cat /proc/interrupts
CPU0 CPU1
17: 0 0 mpic Level ehci_hcd:usb1
19: 0 0 mpic Level ohci_hcd:usb2
20: 7 18 mpic Level sata_sil, ohci_hcd:usb3
22: 0 0 gefp Level phy_interrupt
23: 0 0 gefp Level phy_interrupt
29: 14 8 mpic Level enet_tx
30: 6 70 mpic Level enet_rx
31: 1 22 mpic Level enet_tx
32: 50 17 mpic Level enet_rx
33: 0 0 mpic Level enet_error
34: 0 0 mpic Level enet_error
42: 79 836 mpic Level serial
43: 1 57 mpic Level i2c-mpc, i2c-mpc
251: 14 70 mpic Edge IPI0 (call function)
252: 2609 2014 mpic Edge IPI1 (reschedule)
253: 0 0 mpic Edge IPI2 (unused)
254: 0 0 mpic Edge IPI3 (debugger break)
BAD: 514
I guess there is something wrong (the fact it hits a WARN_ON is a bit of
a give-away!), however I haven't been able to work out what and I've not
got a running example to compare it to.
Any suggestions would be gratefully received,
Martyn
----
Interrupt controller driver follows:
----
/*
* Interrupt handling for GE Fanuc's FPGA based PIC
*
* Author: Martyn Welch <martyn.welch@gefanuc.com>
*
* 2008 (c) GE Fanuc Intelligent Platforms Embedded Systems, Inc.
*
* This file is licensed under the terms of the GNU General Public
License
* version 2. This program is licensed "as is" without any warranty of
any
* kind, whether express or implied.
*/
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <asm/byteorder.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/irq.h>
#include "gef_pic.h"
#undef DEBUG
#define DEBUG
#ifdef DEBUG
#define DBG(fmt...) do { printk(KERN_DEBUG "gef_pic: " fmt); } while(0)
#else
#define DBG(fmt...) do { } while(0)
#endif
#define GEF_PIC_NUM_IRQS 32
/* Interrupt Controller Interface Registers */
#define GEF_PIC_INTR_STATUS 0x0000
#define GEF_PIC_INTR_MASK(cpu) (0x0010 + (0x4 * cpu))
#define GEF_PIC_CPU0_INTR_MASK GEF_PIC_INTR_MASK(0)
#define GEF_PIC_CPU1_INTR_MASK GEF_PIC_INTR_MASK(1)
#define GEF_PIC_MCP_MASK(cpu) (0x0018 + (0x4 * cpu))
#define GEF_PIC_CPU0_MCP_MASK GEF_PIC_MCP_MASK(0)
#define GEF_PIC_CPU1_MCP_MASK GEF_PIC_MCP_MASK(1)
#define gef_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq)
static DEFINE_SPINLOCK(gef_pic_lock);
static void __iomem *gef_pic_irq_reg_base;
static struct irq_host *gef_pic_irq_host;
static int gef_pic_cascade_irq;
/*
* Interrupt Controller Handling
*
* The interrupt controller handles interrupts for most on board
interrupts,
* apart from PCI interrupts. For example on SBC610:
*
* 0:14 RO Reserved
* 15 RO PCI Express Doorbell 3 Status
* 16 RO PCI Express Doorbell 2 Status
* 17 RO PCI Express Doorbell 1 Status
* 18 RO PCI Express Doorbell 0 Status
* 19 RO Real Time Clock Interrupt Status
* 20 RO Temperature Interrupt Status
* 21 RO Temperature Critical Interrupt Status
* 22 RO Ethernet PHY1 Interrupt Status
* 23 RO Ethernet PHY3 Interrupt Status
* 24 RO PEX8548 Interrupt Status
* 25 RO Reserved
* 26 RO Watchdog 0 Interrupt Status
* 27 RO Watchdog 1 Interrupt Status
* 28 RO AXIS Message FIFO A Interrupt Status
* 29 RO AXIS Message FIFO B Interrupt Status
* 30 RO AXIS Message FIFO C Interrupt Status
* 31 RO AXIS Message FIFO D Interrupt Status
*
* Interrupts can be generated forwarded to one of two output lines.
Nothing
* clever is done, so if the masks are incorrectly set a single input
interrupt
* could generate interrupts on both output lines!
*
* The dual lines are there to allow the chained interrupts to be easily
* passed into two different cores.
*
* Controller can also be configured to generate Machine checks (MCP),
again on
* two lines, to be attached to two different cores. It is suggested
that these
* should be masked out.
*/
void gef_pic_cascade(unsigned int irq, struct irq_desc *desc)
{
unsigned int cascade_irq;
DBG("gef_pic_cascade(%u, ->0x%p)\n", irq, desc);
/*
* See if we actually have an interrupt, call generic handling
code if
* we do.
*/
cascade_irq = gef_pic_get_irq();
if (cascade_irq != NO_IRQ) {
generic_handle_irq(cascade_irq);
}
desc->chip->eoi(irq);
}
static void gef_pic_mask(unsigned int virq)
{
unsigned long flags;
unsigned int hwirq;
u32 mask;
hwirq = gef_irq_to_hw(virq);
DBG("Masking virtual interrupt:%u, hw:%u\n", virq, hwirq);
spin_lock_irqsave(&gef_pic_lock, flags);
mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0));
mask &= ~(1 << hwirq);
out_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0), mask);
spin_unlock_irqrestore(&gef_pic_lock, flags);
}
static void gef_pic_mask_ack(unsigned int virq)
{
DBG("Masking and Acking virtual interrupt %u - just Mask\n",
virq);
/* Don't think we actually have to do anything to ack an
interrupt,
* we just need to clear down the devices interrupt and it will
go away
*/
gef_pic_mask(virq);
}
static void gef_pic_unmask(unsigned int virq)
{
unsigned long flags;
unsigned int hwirq;
u32 mask;
hwirq = gef_irq_to_hw(virq);
DBG("Unmasking virtual interrupt %u, hw:%u\n", virq, hwirq);
spin_lock_irqsave(&gef_pic_lock, flags);
mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0));
mask |= (1 << hwirq);
out_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0), mask);
spin_unlock_irqrestore(&gef_pic_lock, flags);
}
static struct irq_chip gef_pic_chip = {
.typename = "gefp",
.mask = gef_pic_mask,
.mask_ack = gef_pic_mask_ack,
.unmask = gef_pic_unmask,
};
/* When an interrupt is being configured, this call allows some
flexibilty
* in deciding which irq_chip structure is used
*/
static int gef_pic_host_map(struct irq_host *h, unsigned int virq,
irq_hw_number_t hwirq)
{
DBG("gef_pic_host_map(%s, %u, %lx)\n", h->of_node->full_name,
virq,
hwirq);
DBG("map virq %d, hwirq 0x%lx\n", virq, hwirq);
/* All interrupts are LEVEL sensitive */
get_irq_desc(virq)->status |= IRQ_LEVEL;
set_irq_chip_and_handler(virq, &gef_pic_chip, handle_level_irq);
return 0;
}
static int gef_pic_host_xlate(struct irq_host *h, struct device_node
*ct,
u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq, unsigned int
*out_flags)
{
DBG("gef_pic_host_xlate()\n");
*out_hwirq = intspec[0];
if (intsize > 1){
DBG("Setting flags from intspec:%u\n", intspec[1]);
*out_flags = intspec[1];
} else {
DBG("Setting flags to IRQ_TYPE_LEVEL_HIGH");
*out_flags = IRQ_TYPE_LEVEL_HIGH;
}
return 0;
}
static struct irq_host_ops gef_pic_host_ops = {
.map = gef_pic_host_map,
.xlate = gef_pic_host_xlate,
};
/*
* Initialisation of PIC, this should be called in BSP
*/
void __init gef_pic_init(struct device_node *np)
{
unsigned long flags;
DBG("gef_pic_init(%s)\n", np->full_name);
/* Setup an irq_host structure */
gef_pic_irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
GEF_PIC_NUM_IRQS,
&gef_pic_host_ops, NO_IRQ);
if (gef_pic_irq_host == NULL) {
DBG("Unable to allocate host\n");
return;
}
/* Map controller */
gef_pic_cascade_irq = irq_of_parse_and_map(np, 0);
if (gef_pic_cascade_irq == NO_IRQ) {
printk(KERN_ERR "SBC610: failed to map cascade
interrupt");
return;
}
DBG("cascade mapped to irq %d\n", gef_pic_cascade_irq);
/* Chain with parent controller */
set_irq_chained_handler(gef_pic_cascade_irq, gef_pic_cascade);
/* Map the devices registers into memory */
gef_pic_irq_reg_base = of_iomap(np, 0);
DBG("Setting up GEF FPGA pic at %p\n", gef_pic_irq_reg_base);
spin_lock_irqsave(&gef_pic_lock, flags);
/* Initialise everything as masked. */
out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU0_INTR_MASK, 0);
out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU1_INTR_MASK, 0);
out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU0_MCP_MASK, 0);
out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU1_MCP_MASK, 0);
spin_unlock_irqrestore(&gef_pic_lock, flags);
}
/*
* This is called when we receive an interrupt with apparently comes
from this
* chip - check, returning the (highest?) interrupt generated or return
NO_IRQ
*/
unsigned int gef_pic_get_irq(void)
{
u32 cause, mask, active;
unsigned int virq = NO_IRQ;
int hwirq;
DBG("gef_pic_get_irq()\n");
cause = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_STATUS);
DBG("cause=0x%8.8x\n", cause);
/* XXX - We really need some way of selecting between the two
interrupt
* outputs (CPUs) at the momment we will only register one and
use
* that exclusively
*/
mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0));
DBG("mask0=0x%8.8x\n", mask);
DBG("mask1=0x%8.8x\n", in_be32(gef_pic_irq_reg_base +
GEF_PIC_INTR_MASK(1)));
active = cause & mask;
DBG("active=0x%8.8x\n", active);
if (active) {
for (hwirq = GEF_PIC_NUM_IRQS - 1; hwirq > -1; hwirq--)
{
if (active & (0x1 << hwirq)) {
DBG("Local interrupt: %d\n", hwirq);
break;
}
}
virq = irq_linear_revmap(gef_pic_irq_host,
(irq_hw_number_t)hwirq);
}
DBG("gef_pic_get_irq() returning %u\n", virq);
return virq;
}
----
Martyn Welch MEng MPhil MIET
Principal Software Engineer
GE Fanuc Intelligent Platforms
Tove Valley Business Park, Towcester,
Northants, NN12 6PF, United Kingdom
Telephone: +44 (0) 1327 359444
Direct Dial: +44 (0) 1327 322748
Fax: +44 (0) 1327 322800
email: martyn.welch@gefanuc.com
web: www.gefanuc.com
GE Fanuc Intelligent Platforms Ltd, registered in England and Wales
(3828642) at 100 Barbirolli Square, Manchester, M2 3AB, VAT GB 729 849
476
GE Fanuc Intelligent Platforms Confidential and Proprietary. If you have
received this message in error please notify us immediately and
permanently remove it from your system and destroy any printed
hardcopies.
^ permalink raw reply
* Re: [PATCH2/2] [POWERPC] CPM1: implement GPIO LIB API on CPM1 Freescale SoC.
From: Jochen Friedrich @ 2008-07-01 15:40 UTC (permalink / raw)
To: Grant Likely; +Cc: Scott Wood, linuxppc-dev list
In-Reply-To: <fa686aa40804210730s2f356d92ib4247423d55911cd@mail.gmail.com>
Hi Grant,
sorry for the late response on this one.
> 2. You need to specifiy exact chip names in your compatible string.
> "fsl,cpm1-pario-<bank>" is a made up thing.
>> + for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank16")
>> + cpm1_gpiochip_add16(np);
>> +
>> + for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank32b")
>> + cpm1_gpiochip_add32(np);
>> +
>> + /* Port E uses CPM2 layout */
>> + for_each_compatible_node(np, NULL, "fsl,cpm1-pario-bank32e")
>> + cpm2_gpiochip_add32(np);
What do you suggest here?
All GPIO ports of CPM1/CPM2 are on the SoC, so the chip name is in fact the CPU itself
(like fsl,mpc866-pario-bank16).
Thanks,
Jochen
^ permalink raw reply
* Re: [PATCH 2/2] Add the of_find_i2c_device_by_node function, V4
From: Jochen Friedrich @ 2008-07-01 15:48 UTC (permalink / raw)
To: Jean Delvare; +Cc: Stephen Rothwell, Linuxppc-dev, Paul Mackerras, i2c
In-Reply-To: <20080701170544.72051418@hyperion.delvare>
Hi Jean,
> I'm not the one to push this upstream though, as the patch is
> essentially an openfirmware patch. That would be something for Jochen
> Friedrich and Paul Mackerras I guess. Would be nice to have a
> MAINTAINERS entry for OF...
Nope. I only did a small contribution to the OF stuff. I guess,
Grant Likely or Stephen Rothwell are the defacto maintainers for OF.
Thanks,
Jochen
^ permalink raw reply
* Re: Commits added to powerpc.git master and powerpc-next branches
From: Jochen Friedrich @ 2008-07-01 15:54 UTC (permalink / raw)
To: Laurent Pinchart; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <200807011049.32699.laurentp@cse-semaphore.com>
Hi Paul,
On Tuesday 01 July 2008, Paul Mackerras wrote:
> The following commits have been added to the master and powerpc-next
> branches of the powerpc.git repository. This includes patches pulled
> from Kumar's and Josh's trees.
Now that the I2C driver for CPM1/CPM2 boards is in the i2c tree, is there
any chance to get this one into 2.6.27?
[POWERPC] Add i2c pins to dts and board setup
http://patchwork.ozlabs.org/linuxppc/patch?person=1023&id=18603
Thanks,
Jochen
^ permalink raw reply
* RE: [PATCH 12/60] microblaze_v4: Generic dts file for platforms
From: Stephen Neuendorffer @ 2008-07-01 15:58 UTC (permalink / raw)
To: benh
Cc: linux-arch, alan, Michal Simek, vapier.adi, arnd, matthew,
microblaze-uclinux, linux-kernel, linuxppc-dev, will.newton, hpa,
John Linn, monstr, drepper, John Williams
In-Reply-To: <1214893302.20711.102.camel@pasglop>
Doing this at the binary level would be nice, but I see enough problems
just doing it at the source level and at least for my purposes, doing it
on a dtb would be overkill, I think. =
The main difficulty remains how to deal with cross references between
nodes in a reasonable way where the references cross from one fragment
to another.
Steve
> -----Original Message-----
> From: Benjamin Herrenschmidt [mailto:benh@kernel.crashing.org]
> Sent: Monday, June 30, 2008 11:22 PM
> To: Stephen Neuendorffer
> Cc: John Williams; grant.likely@secretlab.ca;
linux-arch@vger.kernel.org; Michal Simek;
> vapier.adi@gmail.com; arnd@arndb.de; matthew@wil.cx;
microblaze-uclinux@itee.uq.edu.au; linux-
> kernel@vger.kernel.org; linuxppc-dev@ozlabs.org;
will.newton@gmail.com; hpa@zytor.com; John Linn;
> monstr@seznam.cz; drepper@redhat.com; alan@lxorguk.ukuu.org.uk
> Subject: RE: [PATCH 12/60] microblaze_v4: Generic dts file for
platforms
> =
> =
> > As for the copyright, I haven't been able to find much information
on
> > whether or not generated files are even copyrightable. One might
> > argue that they
> > don't have sufficient 'creative value' to be copyrightable. Or
> > arguably, they are as copyrightable by the generator author as by
the
> > author or the .mhs file.
> > I admit in this case, I've followed the safe route by claiming a
> > copyright, which at least at Xilinx has significant precedent.
> =
> Also, thinking about your idea of sticking bits in BRAM etc...
> =
> what would be nice would be the ability to "merge" trees. We've been
> talking about that multiple times, it would be useful at several
levels:
> =
> - We could provide pre-made DTs for known CPUs (ie, 440GP, 440GX,
> 405EX, ...)
> - Boards can then include that, and then "override" some properties
> (clocks, PHY wiring, ...)
> - That could be done at the binary level too so that the BRAM
contains
> on "overlay" on top of the base ref. platform device-tree that comes
> with the kernel for example.
> =
> This is slightly different between doing that in the .dts source via
> some kind of #include vs. doing that by merging blobs but we could
make
> it be essentially be the same internally: The #include generates a
blob
> that is then "merged in".
> =
> Just random thoughts...
> =
> Ben.
> =
> =
This email and any attachments are intended for the sole use of the named r=
ecipient(s) and contain(s) confidential information that may be proprietary=
, privileged or copyrighted under applicable law. If you are not the intend=
ed recipient, do not read, copy, or forward this email message or any attac=
hments. Delete this email message and any attachments immediately.
^ permalink raw reply
* Re: [PATCH 1/2] Convert i2c-mpc from a platform driver into a of_platform driver, V4
From: Jean Delvare @ 2008-07-01 16:14 UTC (permalink / raw)
To: Jon Smirl; +Cc: Linuxppc-dev, i2c
In-Reply-To: <20080630230126.12482.87927.stgit@terra>
Hi Jon,
On Mon, 30 Jun 2008 19:01:26 -0400, Jon Smirl wrote:
> Convert i2c-mpc to an of_platform driver. Utilize the code in drivers/of-i2c.c
> to make i2c modules dynamically loadable by the device tree.
>
> Signed-off-by: Jon Smirl <jonsmirl@gmail.com>
> ---
>
> arch/powerpc/sysdev/fsl_soc.c | 122 -----------------------------------------
> drivers/i2c/busses/i2c-mpc.c | 104 ++++++++++++++++++++---------------
> 2 files changed, 60 insertions(+), 166 deletions(-)
>
> diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
> index 3a7054e..ebcec73 100644
> --- a/arch/powerpc/sysdev/fsl_soc.c
> +++ b/arch/powerpc/sysdev/fsl_soc.c
> @@ -414,128 +414,6 @@ err:
>
> arch_initcall(gfar_of_init);
>
> -#ifdef CONFIG_I2C_BOARDINFO
> -#include <linux/i2c.h>
> -struct i2c_driver_device {
> - char *of_device;
> - char *i2c_type;
> -};
> -
> -static struct i2c_driver_device i2c_devices[] __initdata = {
> - {"ricoh,rs5c372a", "rs5c372a"},
> - {"ricoh,rs5c372b", "rs5c372b"},
> - {"ricoh,rv5c386", "rv5c386"},
> - {"ricoh,rv5c387a", "rv5c387a"},
> - {"dallas,ds1307", "ds1307"},
> - {"dallas,ds1337", "ds1337"},
> - {"dallas,ds1338", "ds1338"},
> - {"dallas,ds1339", "ds1339"},
> - {"dallas,ds1340", "ds1340"},
> - {"stm,m41t00", "m41t00"},
> - {"dallas,ds1374", "rtc-ds1374"},
> -};
> -
> -static int __init of_find_i2c_driver(struct device_node *node,
> - struct i2c_board_info *info)
> -{
> - int i;
> -
> - for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) {
> - if (!of_device_is_compatible(node, i2c_devices[i].of_device))
> - continue;
> - if (strlcpy(info->type, i2c_devices[i].i2c_type,
> - I2C_NAME_SIZE) >= I2C_NAME_SIZE)
> - return -ENOMEM;
> - return 0;
> - }
> - return -ENODEV;
> -}
> -
> -static void __init of_register_i2c_devices(struct device_node *adap_node,
> - int bus_num)
> -{
> - struct device_node *node = NULL;
> -
> - while ((node = of_get_next_child(adap_node, node))) {
> - struct i2c_board_info info = {};
> - const u32 *addr;
> - int len;
> -
> - addr = of_get_property(node, "reg", &len);
> - if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) {
> - printk(KERN_WARNING "fsl_soc.c: invalid i2c device entry\n");
> - continue;
> - }
> -
> - info.irq = irq_of_parse_and_map(node, 0);
> - if (info.irq == NO_IRQ)
> - info.irq = -1;
> -
> - if (of_find_i2c_driver(node, &info) < 0)
> - continue;
> -
> - info.addr = *addr;
> -
> - i2c_register_board_info(bus_num, &info, 1);
> - }
> -}
> -
> -static int __init fsl_i2c_of_init(void)
> -{
> - struct device_node *np;
> - unsigned int i = 0;
> - struct platform_device *i2c_dev;
> - int ret;
> -
> - for_each_compatible_node(np, NULL, "fsl-i2c") {
> - struct resource r[2];
> - struct fsl_i2c_platform_data i2c_data;
> - const unsigned char *flags = NULL;
> -
> - memset(&r, 0, sizeof(r));
> - memset(&i2c_data, 0, sizeof(i2c_data));
> -
> - ret = of_address_to_resource(np, 0, &r[0]);
> - if (ret)
> - goto err;
> -
> - of_irq_to_resource(np, 0, &r[1]);
> -
> - i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2);
> - if (IS_ERR(i2c_dev)) {
> - ret = PTR_ERR(i2c_dev);
> - goto err;
> - }
> -
> - i2c_data.device_flags = 0;
> - flags = of_get_property(np, "dfsrr", NULL);
> - if (flags)
> - i2c_data.device_flags |= FSL_I2C_DEV_SEPARATE_DFSRR;
> -
> - flags = of_get_property(np, "fsl5200-clocking", NULL);
> - if (flags)
> - i2c_data.device_flags |= FSL_I2C_DEV_CLOCK_5200;
> -
> - ret =
> - platform_device_add_data(i2c_dev, &i2c_data,
> - sizeof(struct
> - fsl_i2c_platform_data));
> - if (ret)
> - goto unreg;
> -
> - of_register_i2c_devices(np, i++);
> - }
> -
> - return 0;
> -
> -unreg:
> - platform_device_unregister(i2c_dev);
> -err:
> - return ret;
> -}
> -
> -arch_initcall(fsl_i2c_of_init);
> -#endif
>
> #ifdef CONFIG_PPC_83xx
> static int __init mpc83xx_wdt_init(void)
> diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
> index a076129..4fdfb62 100644
> --- a/drivers/i2c/busses/i2c-mpc.c
> +++ b/drivers/i2c/busses/i2c-mpc.c
> @@ -17,7 +17,8 @@
> #include <linux/module.h>
> #include <linux/sched.h>
> #include <linux/init.h>
> -#include <linux/platform_device.h>
> +#include <linux/of_platform.h>
> +#include <linux/of_i2c.h>
>
> #include <asm/io.h>
> #include <linux/fsl_devices.h>
> @@ -25,13 +26,13 @@
> #include <linux/interrupt.h>
> #include <linux/delay.h>
>
> -#define MPC_I2C_ADDR 0x00
> +#define DRV_NAME "mpc-i2c"
> +
> #define MPC_I2C_FDR 0x04
> #define MPC_I2C_CR 0x08
> #define MPC_I2C_SR 0x0c
> #define MPC_I2C_DR 0x10
> #define MPC_I2C_DFSRR 0x14
> -#define MPC_I2C_REGION 0x20
>
> #define CCR_MEN 0x80
> #define CCR_MIEN 0x40
> @@ -315,102 +316,117 @@ static struct i2c_adapter mpc_ops = {
> .timeout = 1,
> };
>
> -static int fsl_i2c_probe(struct platform_device *pdev)
> +static int __devinit fsl_i2c_probe(struct of_device *op, const struct of_device_id *match)
> {
> int result = 0;
> struct mpc_i2c *i2c;
> - struct fsl_i2c_platform_data *pdata;
> - struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -
> - pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data;
>
> i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
> if (!i2c)
> return -ENOMEM;
>
> - i2c->irq = platform_get_irq(pdev, 0);
> - if (i2c->irq < 0)
> - i2c->irq = NO_IRQ; /* Use polling */
> + if (of_get_property(op->node, "dfsrr", NULL))
> + i2c->flags |= FSL_I2C_DEV_SEPARATE_DFSRR;
>
> - i2c->flags = pdata->device_flags;
> - init_waitqueue_head(&i2c->queue);
> + if (of_device_is_compatible(op->node, "fsl,mpc5200-i2c") ||
> + of_device_is_compatible(op->node, "mpc5200-i2c"))
> + i2c->flags |= FSL_I2C_DEV_CLOCK_5200;
>
> - i2c->base = ioremap((phys_addr_t)r->start, MPC_I2C_REGION);
> + init_waitqueue_head(&i2c->queue);
>
> + i2c->base = of_iomap(op->node, 0);
> if (!i2c->base) {
> printk(KERN_ERR "i2c-mpc - failed to map controller\n");
> result = -ENOMEM;
> goto fail_map;
> }
>
> - if (i2c->irq != NO_IRQ)
> - if ((result = request_irq(i2c->irq, mpc_i2c_isr,
> - IRQF_SHARED, "i2c-mpc", i2c)) < 0) {
> - printk(KERN_ERR
> - "i2c-mpc - failed to attach interrupt\n");
> - goto fail_irq;
> + i2c->irq = irq_of_parse_and_map(op->node, 0);
> + if (i2c->irq != NO_IRQ) { /* i2c->irq = NO_IRQ implies polling */
> + result = request_irq(i2c->irq, mpc_i2c_isr,
> + IRQF_SHARED, "i2c-mpc", i2c);
> + if (result < 0) {
> + printk(KERN_ERR "i2c-mpc - failed to attach interrupt\n");
> + goto fail_request;
> }
> -
> + }
> +
> mpc_i2c_setclock(i2c);
> - platform_set_drvdata(pdev, i2c);
> +
> + dev_set_drvdata(&op->dev, i2c);
>
> i2c->adap = mpc_ops;
> - i2c->adap.nr = pdev->id;
> i2c_set_adapdata(&i2c->adap, i2c);
> - i2c->adap.dev.parent = &pdev->dev;
> - if ((result = i2c_add_numbered_adapter(&i2c->adap)) < 0) {
> + i2c->adap.dev.parent = &op->dev;
> +
> + result = i2c_add_adapter(&i2c->adap);
> + if (result < 0) {
> printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
> goto fail_add;
> }
> + of_register_i2c_devices(&i2c->adap, op->node);
>
> return result;
>
> - fail_add:
> - if (i2c->irq != NO_IRQ)
> - free_irq(i2c->irq, i2c);
> - fail_irq:
> - iounmap(i2c->base);
> - fail_map:
> + fail_add:
> + dev_set_drvdata(&op->dev, NULL);
> + free_irq(i2c->irq, i2c);
> + fail_request:
> + irq_dispose_mapping(i2c->irq);
> + iounmap(i2c->base);
> + fail_map:
> kfree(i2c);
> return result;
> };
>
> -static int fsl_i2c_remove(struct platform_device *pdev)
> +static int __devexit fsl_i2c_remove(struct of_device *op)
> {
> - struct mpc_i2c *i2c = platform_get_drvdata(pdev);
> + struct mpc_i2c *i2c = dev_get_drvdata(&op->dev);
>
> i2c_del_adapter(&i2c->adap);
> - platform_set_drvdata(pdev, NULL);
> + dev_set_drvdata(&op->dev, NULL);
>
> if (i2c->irq != NO_IRQ)
> free_irq(i2c->irq, i2c);
>
> + irq_dispose_mapping(i2c->irq);
> iounmap(i2c->base);
> kfree(i2c);
> return 0;
> };
>
> -/* work with hotplug and coldplug */
> -MODULE_ALIAS("platform:fsl-i2c");
> +static const struct of_device_id mpc_i2c_of_match[] = {
> + {.compatible = "fsl-i2c",},
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, mpc_i2c_of_match);
> +
>
> /* Structure for a device driver */
> -static struct platform_driver fsl_i2c_driver = {
> - .probe = fsl_i2c_probe,
> - .remove = fsl_i2c_remove,
> - .driver = {
> - .owner = THIS_MODULE,
> - .name = "fsl-i2c",
> +static struct of_platform_driver mpc_i2c_driver = {
> + .match_table = mpc_i2c_of_match,
> + .probe = fsl_i2c_probe,
> + .remove = __devexit_p(fsl_i2c_remove),
> + .driver = {
> + .owner = THIS_MODULE,
> + .name = DRV_NAME,
> },
> };
>
> static int __init fsl_i2c_init(void)
> {
> - return platform_driver_register(&fsl_i2c_driver);
> + int rv;
> +
> + rv = of_register_platform_driver(&mpc_i2c_driver);
> + if (rv)
> + printk(KERN_ERR DRV_NAME
> + " of_register_platform_driver failed (%i)\n", rv);
> + return rv;
> }
>
> static void __exit fsl_i2c_exit(void)
> {
> - platform_driver_unregister(&fsl_i2c_driver);
> + of_unregister_platform_driver(&mpc_i2c_driver);
> }
>
> module_init(fsl_i2c_init);
Applied, after fixing the patch so that it applies, fixing it again so
that it is correct in the polling case, and fixing it again to make it
pass checkpatch.pl.
--
Jean Delvare
^ permalink raw reply
* Re: [PATCH 2/2] Add the of_find_i2c_device_by_node function, V4
From: Jon Smirl @ 2008-07-01 16:29 UTC (permalink / raw)
To: Jean Delvare; +Cc: Linuxppc-dev, Paul Mackerras, i2c
In-Reply-To: <20080701170544.72051418@hyperion.delvare>
On 7/1/08, Jean Delvare <khali@linux-fr.org> wrote:
> Hi Jon,
>
>
> On Mon, 30 Jun 2008 19:01:28 -0400, Jon Smirl wrote:
> > Add the of_find_i2c_device_by_node function. This allows you to
> > follow a reference in the device to an i2c device node and then
> > locate the linux device instantiated by the device tree. Example
> > use, an i2s codec controlled by i2c.
> > ---
> >
> > drivers/i2c/i2c-core.c | 2 +-
> > drivers/of/of_i2c.c | 37 ++++++++++++++++++++++++++-----------
> > include/linux/i2c.h | 3 +++
> > include/linux/of_i2c.h | 2 ++
> > 4 files changed, 32 insertions(+), 12 deletions(-)
> >
> > diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
> > index d0175f4..e3abe1b 100644
> > --- a/drivers/i2c/i2c-core.c
> > +++ b/drivers/i2c/i2c-core.c
> > @@ -208,7 +208,7 @@ static struct device_attribute i2c_dev_attrs[] = {
> > { },
> > };
> >
> > -static struct bus_type i2c_bus_type = {
> > +struct bus_type i2c_bus_type = {
> > .name = "i2c",
> > .dev_attrs = i2c_dev_attrs,
> > .match = i2c_device_match,
>
>
> What if i2c-core is built as a module? Don't you need to export the
> symbol then?
Jean, can you re-export i2c_bus_type and then I'll drop that part from
the patch? That way the patch won't hit multiple maintainers.
> > diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
> > index 715a444..ca69a16 100644
> > --- a/drivers/of/of_i2c.c
> > +++ b/drivers/of/of_i2c.c
> > @@ -75,7 +75,7 @@ static int of_find_i2c_driver(struct device_node *node,
> > void of_register_i2c_devices(struct i2c_adapter *adap,
> > struct device_node *adap_node)
> > {
> > - void *result;
> > + struct i2c_client *i2c_dev;
> > struct device_node *node;
> >
> > for_each_child_of_node(adap_node, node) {
> > @@ -90,29 +90,44 @@ void of_register_i2c_devices(struct i2c_adapter *adap,
> > continue;
> > }
> >
> > - info.irq = irq_of_parse_and_map(node, 0);
> > - if (info.irq == NO_IRQ)
> > - info.irq = -1;
> > -
> > - if (of_find_i2c_driver(node, &info) < 0) {
> > - irq_dispose_mapping(info.irq);
> > + if (of_find_i2c_driver(node, &info) < 0)
> > continue;
> > - }
> >
> > + info.irq = irq_of_parse_and_map(node, 0);
> > info.addr = *addr;
> >
> > - request_module(info.type);
> > + request_module("%s", info.type);
>
>
> A separate fix for this issue was already sent by Maximilian Attems a
> few days go:
> http://lists.lm-sensors.org/pipermail/i2c/2008-June/004030.html
>
>
> >
> > - result = i2c_new_device(adap, &info);
> > - if (result == NULL) {
> > + i2c_dev = i2c_new_device(adap, &info);
> > + if (i2c_dev == NULL) {
> > printk(KERN_ERR
> > "of-i2c: Failed to load driver for %s\n",
> > info.type);
> > irq_dispose_mapping(info.irq);
> > continue;
> > }
> > +
> > + i2c_dev->dev.archdata.of_node = of_node_get(node);
> > }
> > }
> > EXPORT_SYMBOL(of_register_i2c_devices);
> >
> > +static int of_dev_node_match(struct device *dev, void *data)
> > +{
> > + return dev->archdata.of_node == data;
> > +}
> > +
> > +struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
> > +{
> > + struct device *dev;
> > +
> > + dev = bus_find_device(&i2c_bus_type, NULL, node,
> > + of_dev_node_match);
> > + if (!dev)
> > + return NULL;
> > +
> > + return to_i2c_client(dev);
> > +}
> > +EXPORT_SYMBOL(of_find_i2c_device_by_node);
> > +
> > MODULE_LICENSE("GPL");
> > diff --git a/include/linux/i2c.h b/include/linux/i2c.h
> > index fb9af6a..186b22d 100644
> > --- a/include/linux/i2c.h
> > +++ b/include/linux/i2c.h
> > @@ -92,6 +92,9 @@ extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
> > extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client,
> > u8 command, u8 length,
> > const u8 *values);
> > +
> > +/* Base of the i2c bus */
> > +extern struct bus_type i2c_bus_type;
> >
> > /*
> > * A driver is capable of handling one or more physical devices present on
> > diff --git a/include/linux/of_i2c.h b/include/linux/of_i2c.h
> > index bd2a870..17d5897 100644
> > --- a/include/linux/of_i2c.h
> > +++ b/include/linux/of_i2c.h
> > @@ -16,5 +16,7 @@
> >
> > void of_register_i2c_devices(struct i2c_adapter *adap,
> > struct device_node *adap_node);
> > +struct i2c_client *of_find_i2c_device_by_node(struct device_node *node);
> > +
> >
> > #endif /* __LINUX_OF_I2C_H */
>
>
> I'm fine with this patch. In particular, exporting i2c_bus_type is OK.
> It was un-exported only because it had no user left, but it can be
> exported again if needed.
>
> I'm not the one to push this upstream though, as the patch is
> essentially an openfirmware patch. That would be something for Jochen
> Friedrich and Paul Mackerras I guess. Would be nice to have a
> MAINTAINERS entry for OF...
>
> --
>
> Jean Delvare
>
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply
* Re: [PATCH 2/2] Add the of_find_i2c_device_by_node function, V4
From: Jean Delvare @ 2008-07-01 16:29 UTC (permalink / raw)
To: Jon Smirl; +Cc: Linuxppc-dev, Paul Mackerras, i2c
In-Reply-To: <9e4733910807010812h30e49144v5b3012e6c156ecca@mail.gmail.com>
On Tue, 1 Jul 2008 11:12:58 -0400, Jon Smirl wrote:
> On 7/1/08, Jean Delvare <khali@linux-fr.org> wrote:
> > I'm fine with this patch. In particular, exporting i2c_bus_type is OK.
> > It was un-exported only because it had no user left, but it can be
> > exported again if needed.
>
> Another solution would be to move drivers/of/of_i2c into the i2c
> directory and make it part of i2c core on powerpc builds.
I don't think this is a good idea. Merging arch-specific code (or
half-arch-specific code in this case) into arch-neutral drivers ends up
being a pain to maintain. People will keep sending me patches for stuff
I don't know anything about and can't help with. Having of-specific
stuff in just one directory as is the case now sounds much better to
me. All it's missing is a MAINTAINERS entry.
--
Jean Delvare
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox