* Re: [PATCH 6/6] of/device: populate platform_device (of_device) resource table on allocation
From: Grant Likely @ 2010-06-10 17:21 UTC (permalink / raw)
To: Anton Vorontsov
Cc: sfr, microblaze-uclinux, devicetree-discuss, jeremy.kerr,
linuxppc-dev, M. Warner Losh
In-Reply-To: <20100610171029.GA18824@oksana.dev.rtsoft.ru>
On Thu, Jun 10, 2010 at 11:10 AM, Anton Vorontsov
<cbouatmailru@gmail.com> wrote:
> On Thu, Jun 10, 2010 at 10:30:26AM -0600, Grant Likely wrote:
> [...]
>> =A0 =A0 =A0 res =3D kzalloc((sizeof(*res) * num_res), GFP_KERNEL);
>> =A0 =A0 =A0 if (!res) {
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 kfree(ofdev); =A0/* or goto an error unwind =
label */
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 return NULL;
>> =A0 =A0 =A0 }
>> =A0 =A0 =A0 res =3D (struct resource *)&ofdev[1];
>
> You mean ofdev->resource =3D res; ?
Yeah, cut-and-paste error.
g.
^ permalink raw reply
* Re: [PATCH 0/5] Removing dead code
From: Joe Perches @ 2010-06-10 18:46 UTC (permalink / raw)
To: Christoph Egger, Robert P. J. Day; +Cc: linuxppc-dev, vamos, linux-kernel
In-Reply-To: <cover.1275925219.git.siccegge@cs.fau.de>
(cc's trimmed and rpjday added)
On Wed, 2010-06-09 at 11:58 +0200, Christoph Egger wrote:
> I've been running a check on the arch/powerpc sourcetree for
> config Items not defined in Kconfig and found5 such chases.
Are you aware of
http://www.crashcourse.ca/wiki/index.php/Kernel_cleanup_scripts
> [0] http://vamos1.informatik.uni-erlangen.de/
^ permalink raw reply
* Re: [PATCH][RFC] ibm_newemac and SIOCGMIIREG
From: Steven A. Falco @ 2010-06-10 19:47 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev
In-Reply-To: <201006101903.43882.arnd@arndb.de>
On 06/10/2010 01:03 PM, Arnd Bergmann wrote:
>
> On Thursday 10 June 2010, Steven A. Falco wrote:
>>> The ifreq structure passed into the ndo_ioctl function is in kernel
>>> space, it gets copied there by net/core/dev.c:dev_ioctl().
>>> emac_ioctl only accesses the data in that structure, so a copy_from_user
>>> is wrong here as far as I can tell.
>>
>> net/core/dev.c:dev_ioctl() does a copy_from_user on the overall structure,
>> but the structure contains a union, one member of which is an embedded
>> pointer to an array. This pointer member is only used in the case of these
>> two ioctls. Other ioctls use different union members, which are not pointers.
>
> Still unconvinced.
Ok - here is the user-space program I am using to test this. It simply
uses the ioctl to peek and poke the phy. If I run it on an unmodified
kernel, and I read the phy ID registers, i.e. registers 2 and 3, I get:
# ./phy -r -a 2
2: 0000
# ./phy -r -a 3
3: 0000
which is clearly wrong. Once I load my modified kernel, I get:
# ./phy -a 2
2: 0022
# ./phy -a 3
3: 1512
which is correct for the phy on my board (i.e. phy id is 00221512). If you
could try this program on a sequoia or similar, I'd be interested in whether
you see the problem.
------ cut here ------
#define _GNU_SOURCE
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <string.h>
#include <unistd.h>
#include <linux/mii.h>
#include <linux/sockios.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#define READING 0
#define WRITING 1
void use()
{
fprintf(stderr, "\nphy [OPTIONS]\n\n");
fprintf(stderr, " -a address (register within phy to access)\n");
fprintf(stderr, " -d device (something like eth0, eth1, etc.)\n");
fprintf(stderr, " -r (read the register)\n");
fprintf(stderr, " -w (write the register)\n");
fprintf(stderr, " -v value (the value to write)\n");
fprintf(stderr, " -h (this help message)\n");
}
int
main(int argc, char *argv[])
{
int fd;
struct ifreq request;
struct mii_ioctl_data data;
int opt;
int dir = READING;
char *pDev = "eth0";
uint32_t addr = 0;
uint32_t value = 0;
while((opt = getopt(argc, argv, "a:d:hrv:w")) != -1) {
switch(opt) {
case 'a':
addr = strtoul(optarg, NULL, 16);
break;
case 'd':
pDev = optarg;
break;
case 'h':
use();
exit(0);
case 'r':
dir = READING;
break;
case 'v':
value = strtoul(optarg, NULL, 16);
break;
case 'w':
dir = WRITING;
break;
default:
fprintf(stderr, "bad option\n");
use();
exit(1);
}
}
fd = socket(AF_INET, SOCK_DGRAM, 0);
if(fd < 0) {
fprintf(stderr, "no sock\n");
exit(1);
}
memset(&request, 0, sizeof(request));
memset(&data, 0, sizeof(data));
strncpy(request.ifr_name, pDev, sizeof(request.ifr_name));
data.reg_num = addr;
y
if(dir == READING) {
if(ioctl(fd, SIOCGMIIREG, &request) < 0) {
fprintf(stderr, "SIOCGMIIREG failed\n");
exit(1);
}
printf("%d: %04x\n", addr, data.val_out);
} else {
data.val_in = value;
if(ioctl(fd, SIOCSMIIREG, &request) < 0) {
fprintf(stderr, "SIOCSMIIREG failed\n");
exit(1);
}
}
exit(0);
}
------ cut here ------
>
> I don't see anywhere in the structure where we actually use a
> pointer from ifr_ifru. The if_mii function is defined as
>
> static inline struct mii_ioctl_data *if_mii(struct ifreq *rq)
> {
> return (struct mii_ioctl_data *) &rq->ifr_ifru;
> }
>
> That just returns a pointer to the ifr_ifru member itself,
But that pointer points to a separate "struct mii_ioctl_data"
in user space. In my test code above, I do:
request.ifr_data = (__caddr_t)&data;
where data is a "struct mii_ioctl_data" that is separate from the
"struct ifreq". It's not one monolithic structure, it is two
structures, one pointing to the other, both in user space.
> it does not read a __user pointer. Note how if_mii even
> returns a kernel pointer (struct mii_ioctl_data *), not
> a struct mii_ioctl_data __user *. You even added a cast
> that otherwise should not be needed.
I disagree - the structure, as shown in "include/linux/if.h" has
"void __user *ifru_data", which is clearly a user pointer.
>
>> As I understand it, the copy_from_user in dev_ioctl does not recursively
>> copy the array. In fact it could not do so, because the pointer to array
>> is only 4 bytes long, while the array itself is 8 bytes long - so it would
>> not fit. I.e., dev_ioctl would have to allocate storage, and do a second
>> copy_from_user to retrieve the array. It would have to clean up after the
>> emac_ioctl ran. And it would have to do this only for these specific
>> ioctl calls which use the array pointer in the union.
>>
>> Also, the result has to be returned to the user in the same array, which
>> needs a copy_to_user of the array data, which is also not done in dev_ioctl.
>
> There is no array, and no pointer in struct ifreq
struct ifreq {
.....
union {
.....
void __user * ifru_data;
.....
} ifr_ifru;
};
I claim that "ifru_data" is a pointer to a user-space structure,
which for these two ioctls is defined as:
struct mii_ioctl_data {
__u16 phy_id;
__u16 reg_num;
__u16 val_in;
__u16 val_out;
};
I misspoke when calling this an array. In earlier versions of the
kernel code, this was simply an array of four __u16, but it is now a
struct. Doesn't really matter though - it is a separate structure from
the ifreq one. So in my test program, I have:
struct ifreq request;
struct mii_ioctl_data data;
.....
request.ifr_data = (__caddr_t)&data;
which is where I fill in the "struct ifreq" with my user pointer to my
"struct mii_ioctl_data".
The key is that the union does not have:
struct mii_ioctl_data ifru_data;
rather it has a pointer:
void __user * ifru_data;
and that is why the second copy_from_user is needed. It would have been
much nicer if the union contained the actual mii_ioctl_data structure,
but I guess the void pointer is more flexible.
>
>> So I think this second copy_from/copy_to needs to be done somewhere. I
>> added it in the emac_ioctl because that is where the command is fully
>> decoded. It also avoids the problem of allocating space for the copied
>> array. But other fixes are certainly possible as well, which is why I am
>> not sure I've hit on the "proper" fix.
>
> No other device driver implementing SIOCGMIIREG does any of this,
> so I'm pretty sure it's not the proper fix.
That is my main worry as well. However, my test program does not work
unless I modify the kernel. Perhaps there is something wrong with the
program, but I don't think so, based on the union definition as I showed
it above.
>
>> Thanks very much for reviewing - please let me know if my explanation is
>> unclear, or if you see a better way to fix this problem.
>
> In theory, your patch should break the code. Doing a direct access
> in place of a copy_to/from_user is a security hole but should still work,
> while adding a copy_to/from_user on a kernel pointer should always result
> in an EFAULT.
My patch does not give an EFAULT, as you will see if you are able to try
my test program. I won't claim that proves I am right however. :-)
Your statement that copy_to/from_user is just there for security is
something I did not know. Yet, that doesn't appear to be the case,
given my experiments.
I appreciate your patience - perhaps there is something unique about the
4xx CPU's that makes the direct access fail. I should add that my
kernel does have Xenomai patches added. I also don't know if that has
any bearing on the problem.
I'll try to resurrect my sequoia board with an unmodified kernel and
test further. One thing for sure - something strange is going on.
Steve
>
> Arnd
>
^ permalink raw reply
* Re: 2.6.35-rc2 : OOPS with LTP memcg regression test run.
From: Maciej Rutecki @ 2010-06-10 20:00 UTC (permalink / raw)
To: Sachin Sant; +Cc: linux-mm, linux-kernel, Linux/PPC Development
In-Reply-To: <4C0BB98E.9030101@in.ibm.com>
I created a Bugzilla entry at
https://bugzilla.kernel.org/show_bug.cgi?id=16178
for your bug report, please add your address to the CC list in there, thanks!
On niedziela, 6 czerwca 2010 o 17:06:54 Sachin Sant wrote:
> While executing LTP Controller tests(memcg regression) on
> a POWER6 box came across this following OOPS.
>
> Memory cgroup out of memory: kill process 9139 (memcg_test_1) score 3 or a
> child Killed process 9139 (memcg_test_1) vsz:3456kB, anon-rss:448kB,
> file-rss:1088kB Memory cgroup out of memory: kill process 9140
> (memcg_test_1) score 3 or a child Killed process 9140 (memcg_test_1)
> vsz:3456kB, anon-rss:448kB, file-rss:1088kB Unable to handle kernel paging
> request for data at address 0x720072007200720 Faulting instruction
> address: 0xc00000000015b778
> Oops: Kernel access of bad area, sig: 11 [#2]
> SMP NR_CPUS=1024 NUMA pSeries
> last sysfs file: /sys/devices/system/cpu/cpu1/cache/index1/shared_cpu_map
> Modules linked in: quota_v2 quota_tree ipv6 fuse loop dm_mod sr_mod cdrom
> sg sd_mod crc_t10dif ibmvscsic scsi_transport_srp scsi_tgt scsi_mod NIP:
> c00000000015b778 LR: c00000000015b740 CTR: 0000000000000000
> REGS: c000000009812ff0 TRAP: 0300 Tainted: G D
> (2.6.35-rc2-autotest) MSR: 8000000000009032 <EE,ME,IR,DR> CR: 44004424
> XER: 00000001
> DAR: 0720072007200720, DSISR: 0000000040000000
> TASK = c000000005fb1100[9155] 'umount' THREAD: c000000009810000 CPU: 0
> GPR00: 0000000000000000 c000000009813270 c000000000d3d7a0 0000000000000000
> GPR04: 0000000000008050 0000000000160000 0000000000000027 c00000000f2c6870
> GPR08: 00000000000006a5 c000000000b16870 c000000000cf0140 000000000e7b0000
> GPR12: 0000000024004428 c000000007440000 0000000000008000 fffffffffffff000
> GPR16: 0000000000000000 c0000000098138f0 000000000000002d 0000000000000027
> GPR20: 0000000000000000 0000000000000027 0000000000000000 c000000007063138
> GPR24: ffffffffffffffff 0000000000000000 c00000000019bafc c00000000e02e000
> GPR28: 0000000000000001 0000000000008050 c000000000ca6b00 0720072007200720
> NIP [c00000000015b778] .kmem_cache_alloc+0xb0/0x13c
> LR [c00000000015b740] .kmem_cache_alloc+0x78/0x13c
> Call Trace:
> [c000000009813270] [c00000000015b740] .kmem_cache_alloc+0x78/0x13c
> (unreliable) [c000000009813310] [c00000000019bafc]
> .alloc_buffer_head+0x2c/0x78 [c000000009813390] [c00000000019c99c]
> .alloc_page_buffers+0x60/0x114 [c000000009813450] [c00000000019ca78]
> .create_empty_buffers+0x28/0x140 [c0000000098134e0] [c00000000019f2ec]
> .__block_prepare_write+0xe4/0x4f0 [c000000009813610] [c00000000019f94c]
> .block_write_begin_newtrunc+0xa8/0x120 [c0000000098136d0]
> [c00000000019fea0] .block_write_begin+0x34/0x8c [c000000009813770]
> [c00000000022b458] .ext3_write_begin+0x13c/0x298 [c000000009813880]
> [c000000000117500] .generic_file_buffered_write+0x13c/0x320
> [c0000000098139b0] [c000000000119c80]
> .__generic_file_aio_write+0x378/0x3dc [c000000009813ab0]
> [c000000000119d68] .generic_file_aio_write+0x84/0xfc [c000000009813b60]
> [c00000000016e460] .do_sync_write+0xac/0x10c
> [c000000009813ce0] [c00000000016f204] .vfs_write+0xd0/0x1dc
> [c000000009813d80] [c00000000016f418] .SyS_write+0x58/0xa0
> [c000000009813e30] [c0000000000085b4] syscall_exit+0x0/0x40
> Instruction dump:
> 38600000 409e0090 38000000 8b8d0212 980d0212 e96d0040 e93b0000 7ce95a14
> 7fe9582a 2fbf0000 419e0014 e81b001a <7c1f002a> 7c09592a 4800001c 7f46d378
> ---[ end trace f24cb0cb5729d2bb ]---
>
> And few more of these. Previous snapshot release
> 2.6.35-rc1-git5(6c5de280b6...) was good.
>
> Thanks
> -Sachin
>
--
Maciej Rutecki
http://www.maciek.unixy.pl
^ permalink raw reply
* Re: [PATCH][RFC] ibm_newemac and SIOCGMIIREG
From: Arnd Bergmann @ 2010-06-10 20:35 UTC (permalink / raw)
To: Steven A. Falco; +Cc: linuxppc-dev
In-Reply-To: <4C11414F.5070602@harris.com>
On Thursday 10 June 2010 21:47:27 Steven A. Falco wrote:
> On 06/10/2010 01:03 PM, Arnd Bergmann wrote:
> > Still unconvinced.
>
> Ok - here is the user-space program I am using to test this. It simply
> uses the ioctl to peek and poke the phy. If I run it on an unmodified
> kernel, and I read the phy ID registers, i.e. registers 2 and 3, I get:
>
> # ./phy -r -a 2
> 2: 0000
> # ./phy -r -a 3
> 3: 0000
>
> which is clearly wrong. Once I load my modified kernel, I get:
>
> # ./phy -a 2
> 2: 0022
> # ./phy -a 3
> 3: 1512
>
> which is correct for the phy on my board (i.e. phy id is 00221512). If you
> could try this program on a sequoia or similar, I'd be interested in whether
> you see the problem.
It seems that your program is wrong. On my PC here, it also shows zero,
while mii-tool works fine.
> int
> main(int argc, char *argv[])
> {
> int fd;
> struct ifreq request;
> struct mii_ioctl_data data;
This should be
struct mii_ioctl_data *data = &request.ifr_ifru
> > I don't see anywhere in the structure where we actually use a
> > pointer from ifr_ifru. The if_mii function is defined as
> >
> > static inline struct mii_ioctl_data *if_mii(struct ifreq *rq)
> > {
> > return (struct mii_ioctl_data *) &rq->ifr_ifru;
> > }
> >
> > That just returns a pointer to the ifr_ifru member itself,
>
> But that pointer points to a separate "struct mii_ioctl_data"
> in user space. In my test code above, I do:
>
> request.ifr_data = (__caddr_t)&data;
>
> where data is a "struct mii_ioctl_data" that is separate from the
> "struct ifreq". It's not one monolithic structure, it is two
> structures, one pointing to the other, both in user space.
Only in your code, when you look at mii-tool, it does (correctly)
static int mdio_read(int skfd, int location)
{
struct mii_data *mii = (struct mii_data *)&ifr.ifr_data;
mii->reg_num = location;
if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0) {
fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name,
strerror(errno));
return -1;
}
return mii->val_out;
}
> > it does not read a __user pointer. Note how if_mii even
> > returns a kernel pointer (struct mii_ioctl_data *), not
> > a struct mii_ioctl_data __user *. You even added a cast
> > that otherwise should not be needed.
>
> I disagree - the structure, as shown in "include/linux/if.h" has
> "void __user *ifru_data", which is clearly a user pointer.
This is used for SIOCSHWTSTAMP, SIOCBONDINFOQUERY, SIOCETHTOOL
and possibly a few others but not SIOCGMIIREG.
> and that is why the second copy_from_user is needed. It would have been
> much nicer if the union contained the actual mii_ioctl_data structure,
> but I guess the void pointer is more flexible.
No, the void pointer is broken for a number of reasons, that's why
we don't use it.
> My patch does not give an EFAULT, as you will see if you are able to try
> my test program. I won't claim that proves I am right however. :-)
>
> Your statement that copy_to/from_user is just there for security is
> something I did not know. Yet, that doesn't appear to be the case,
> given my experiments.
Right, I misread one line of your patch: when you do
if (copy_from_user(user_data, (char __user *)data, sizeof(user_data)))
return -EFAULT;
user_data->val_out = emac_mdio_read(ndev, dev->phy.address,
user_data->reg_num);
if (copy_to_user((char __user *)rq->ifr_data, user_data, sizeof(user_data)))
You actually copy in from a different pointer than you copy out to.
The first one is a cast from a kernel to a user pointer, which
should actually result in -EFAULT (I don't known why it doesn't)
while the second one is where you change the interface to match
your (broken) program.
Arnd
^ permalink raw reply
* Re: [PATCH][RFC] ibm_newemac and SIOCGMIIREG
From: Steven A. Falco @ 2010-06-10 21:26 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev
In-Reply-To: <201006102235.48632.arnd@arndb.de>
On 06/10/2010 04:35 PM, Arnd Bergmann wrote:
>
> It seems that your program is wrong. On my PC here, it also shows zero,
> while mii-tool works fine.
>
You are correct. I didn't realize I should embed the data
in the ifr_data area - I thought I needed to pass a pointer.
Now I see why you avoid that. And since IFNAMSIZ is 16,
there is enough space for the struct mii_ioctl_data. A bit
dirty, but it obviously works.
Anyway, thanks very much for taking the time to debug my
program, and set me straight. Naturally, I withdraw the
patch. :-)
Steve
>
> Arnd
^ permalink raw reply
* [PATCH 1/2] powerpc: Migration code reorganization / hibernation prep
From: Brian King @ 2010-06-10 21:47 UTC (permalink / raw)
To: benh; +Cc: brking, linuxppc-dev
Partition hibernation will use some of the same code as is
currently used for Live Partition Migration. This function
further abstracts this code such that code outside of rtas.c
can utilize it. It also changes the error field in the suspend
me data structure to be an atomic type, since it is set and
checked on different cpus without any barriers or locking.
Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/rtas.h | 10 +++
arch/powerpc/kernel/rtas.c | 106 ++++++++++++++++++++++++++--------------
2 files changed, 81 insertions(+), 35 deletions(-)
diff -puN arch/powerpc/include/asm/rtas.h~powerpc_rtas_hibernate_prep arch/powerpc/include/asm/rtas.h
--- linux-2.6/arch/powerpc/include/asm/rtas.h~powerpc_rtas_hibernate_prep 2010-05-25 13:05:48.000000000 -0500
+++ linux-2.6-bjking1/arch/powerpc/include/asm/rtas.h 2010-05-25 13:05:48.000000000 -0500
@@ -63,6 +63,14 @@ struct rtas_t {
struct device_node *dev; /* virtual address pointer */
};
+struct rtas_suspend_me_data {
+ atomic_t working; /* number of cpus accessing this struct */
+ atomic_t done;
+ int token; /* ibm,suspend-me */
+ atomic_t error;
+ struct completion *complete; /* wait on this until working == 0 */
+};
+
/* RTAS event classes */
#define RTAS_INTERNAL_ERROR 0x80000000 /* set bit 0 */
#define RTAS_EPOW_WARNING 0x40000000 /* set bit 1 */
@@ -174,6 +182,8 @@ extern int rtas_set_indicator(int indica
extern int rtas_set_indicator_fast(int indicator, int index, int new_value);
extern void rtas_progress(char *s, unsigned short hex);
extern void rtas_initialize(void);
+extern int rtas_suspend_cpu(struct rtas_suspend_me_data *data);
+extern int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data);
struct rtc_time;
extern unsigned long rtas_get_boot_time(void);
diff -puN arch/powerpc/kernel/rtas.c~powerpc_rtas_hibernate_prep arch/powerpc/kernel/rtas.c
--- linux-2.6/arch/powerpc/kernel/rtas.c~powerpc_rtas_hibernate_prep 2010-05-25 13:05:48.000000000 -0500
+++ linux-2.6-bjking1/arch/powerpc/kernel/rtas.c 2010-05-25 13:05:48.000000000 -0500
@@ -47,14 +47,6 @@ struct rtas_t rtas = {
};
EXPORT_SYMBOL(rtas);
-struct rtas_suspend_me_data {
- atomic_t working; /* number of cpus accessing this struct */
- atomic_t done;
- int token; /* ibm,suspend-me */
- int error;
- struct completion *complete; /* wait on this until working == 0 */
-};
-
DEFINE_SPINLOCK(rtas_data_buf_lock);
EXPORT_SYMBOL(rtas_data_buf_lock);
@@ -714,14 +706,54 @@ void rtas_os_term(char *str)
static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE;
#ifdef CONFIG_PPC_PSERIES
-static void rtas_percpu_suspend_me(void *info)
+static int __rtas_suspend_last_cpu(struct rtas_suspend_me_data *data, int wake_when_done)
+{
+ u16 slb_size = mmu_slb_size;
+ int rc = H_MULTI_THREADS_ACTIVE;
+ int cpu;
+
+ atomic_inc(&data->working);
+
+ slb_set_size(SLB_MIN_SIZE);
+ printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n", smp_processor_id());
+
+ while (rc == H_MULTI_THREADS_ACTIVE && !atomic_read(&data->done) &&
+ !atomic_read(&data->error))
+ rc = rtas_call(data->token, 0, 1, NULL);
+
+ if (rc || atomic_read(&data->error)) {
+ printk(KERN_DEBUG "ibm,suspend-me returned %d\n", rc);
+ slb_set_size(slb_size);
+ }
+
+ if (atomic_read(&data->error))
+ rc = atomic_read(&data->error);
+
+ atomic_set(&data->error, rc);
+
+ if (wake_when_done) {
+ atomic_set(&data->done, 1);
+
+ for_each_online_cpu(cpu)
+ plpar_hcall_norets(H_PROD, get_hard_smp_processor_id(cpu));
+ }
+
+ if (atomic_dec_return(&data->working) == 0)
+ complete(data->complete);
+
+ return rc;
+}
+
+int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data)
+{
+ return __rtas_suspend_last_cpu(data, 0);
+}
+
+static int __rtas_suspend_cpu(struct rtas_suspend_me_data *data, int wake_when_done)
{
long rc = H_SUCCESS;
unsigned long msr_save;
- u16 slb_size = mmu_slb_size;
int cpu;
- struct rtas_suspend_me_data *data =
- (struct rtas_suspend_me_data *)info;
atomic_inc(&data->working);
@@ -729,7 +761,7 @@ static void rtas_percpu_suspend_me(void
msr_save = mfmsr();
mtmsr(msr_save & ~(MSR_EE));
- while (rc == H_SUCCESS && !atomic_read(&data->done))
+ while (rc == H_SUCCESS && !atomic_read(&data->done) && !atomic_read(&data->error))
rc = plpar_hcall_norets(H_JOIN);
mtmsr(msr_save);
@@ -741,33 +773,37 @@ static void rtas_percpu_suspend_me(void
/* All other cpus are in H_JOIN, this cpu does
* the suspend.
*/
- slb_set_size(SLB_MIN_SIZE);
- printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n",
- smp_processor_id());
- data->error = rtas_call(data->token, 0, 1, NULL);
-
- if (data->error) {
- printk(KERN_DEBUG "ibm,suspend-me returned %d\n",
- data->error);
- slb_set_size(slb_size);
- }
+ return __rtas_suspend_last_cpu(data, wake_when_done);
} else {
printk(KERN_ERR "H_JOIN on cpu %i failed with rc = %ld\n",
smp_processor_id(), rc);
- data->error = rc;
+ atomic_set(&data->error, rc);
}
- atomic_set(&data->done, 1);
+ if (wake_when_done) {
+ atomic_set(&data->done, 1);
- /* This cpu did the suspend or got an error; in either case,
- * we need to prod all other other cpus out of join state.
- * Extra prods are harmless.
- */
- for_each_online_cpu(cpu)
- plpar_hcall_norets(H_PROD, get_hard_smp_processor_id(cpu));
+ /* This cpu did the suspend or got an error; in either case,
+ * we need to prod all other other cpus out of join state.
+ * Extra prods are harmless.
+ */
+ for_each_online_cpu(cpu)
+ plpar_hcall_norets(H_PROD, get_hard_smp_processor_id(cpu));
+ }
out:
if (atomic_dec_return(&data->working) == 0)
complete(data->complete);
+ return rc;
+}
+
+int rtas_suspend_cpu(struct rtas_suspend_me_data *data)
+{
+ return __rtas_suspend_cpu(data, 0);
+}
+
+static void rtas_percpu_suspend_me(void *info)
+{
+ __rtas_suspend_cpu((struct rtas_suspend_me_data *)info, 1);
}
static int rtas_ibm_suspend_me(struct rtas_args *args)
@@ -802,22 +838,22 @@ static int rtas_ibm_suspend_me(struct rt
atomic_set(&data.working, 0);
atomic_set(&data.done, 0);
+ atomic_set(&data.error, 0);
data.token = rtas_token("ibm,suspend-me");
- data.error = 0;
data.complete = &done;
/* Call function on all CPUs. One of us will make the
* rtas call
*/
if (on_each_cpu(rtas_percpu_suspend_me, &data, 0))
- data.error = -EINVAL;
+ atomic_set(&data.error, -EINVAL);
wait_for_completion(&done);
- if (data.error != 0)
+ if (atomic_read(&data.error) != 0)
printk(KERN_ERR "Error doing global join\n");
- return data.error;
+ return atomic_read(&data.error);
}
#else /* CONFIG_PPC_PSERIES */
static int rtas_ibm_suspend_me(struct rtas_args *args)
_
^ permalink raw reply
* [PATCH 2/2] powerpc: Partition hibernation support
From: Brian King @ 2010-06-10 21:47 UTC (permalink / raw)
To: benh; +Cc: brking, linuxppc-dev
Enables support for HMC initiated partition hibernation. This is
a firmware assisted hibernation, since the firmware handles writing
the memory out to disk, along with other partition information,
so we just mimic suspend to ram.
Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
---
arch/powerpc/Kconfig | 2
arch/powerpc/include/asm/hvcall.h | 1
arch/powerpc/include/asm/machdep.h | 1
arch/powerpc/platforms/pseries/Makefile | 4
arch/powerpc/platforms/pseries/hotplug-cpu.c | 3
arch/powerpc/platforms/pseries/suspend.c | 214 +++++++++++++++++++++++++++
6 files changed, 224 insertions(+), 1 deletion(-)
diff -puN /dev/null arch/powerpc/platforms/pseries/suspend.c
--- /dev/null 2009-12-15 17:58:07.000000000 -0600
+++ linux-2.6-bjking1/arch/powerpc/platforms/pseries/suspend.c 2010-05-27 10:10:28.000000000 -0500
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2010 Brian King IBM Corporation
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/delay.h>
+#include <linux/suspend.h>
+#include <asm/firmware.h>
+#include <asm/hvcall.h>
+#include <asm/machdep.h>
+#include <asm/mmu.h>
+#include <asm/rtas.h>
+
+static u64 stream_id;
+static struct sys_device suspend_sysdev;
+static DECLARE_COMPLETION(suspend_work);
+static struct rtas_suspend_me_data suspend_data;
+static atomic_t suspending;
+
+/**
+ * pseries_suspend_begin - First phase of hibernation
+ *
+ * Check to ensure we are in a valid state to hibernate
+ *
+ * Return value:
+ * 0 on success / other on failure
+ **/
+static int pseries_suspend_begin(suspend_state_t state)
+{
+ long vasi_state, rc;
+ unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+
+ /* Make sure the state is valid */
+ rc = plpar_hcall(H_VASI_STATE, retbuf, stream_id);
+
+ vasi_state = retbuf[0];
+
+ if (rc) {
+ pr_err("pseries_suspend_begin: vasi_state returned %ld\n",rc);
+ return rc;
+ } else if (vasi_state == H_VASI_ENABLED) {
+ return -EAGAIN;
+ } else if (vasi_state != H_VASI_SUSPENDING) {
+ pr_err("pseries_suspend_begin: vasi_state returned state %ld\n",
+ vasi_state);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/**
+ * pseries_suspend_cpu - Suspend a single CPU
+ *
+ * Makes the H_JOIN call to suspend the CPU
+ *
+ **/
+static int pseries_suspend_cpu(void)
+{
+ if (atomic_read(&suspending))
+ return rtas_suspend_cpu(&suspend_data);
+ return 0;
+}
+
+/**
+ * pseries_suspend_enter - Final phase of hibernation
+ *
+ * Return value:
+ * 0 on success / other on failure
+ **/
+static int pseries_suspend_enter(suspend_state_t state)
+{
+ int rc = rtas_suspend_last_cpu(&suspend_data);
+
+ atomic_set(&suspending, 0);
+ atomic_set(&suspend_data.done, 1);
+ return rc;
+}
+
+/**
+ * pseries_prepare_late - Prepare to suspend all other CPUs
+ *
+ * Return value:
+ * 0 on success / other on failure
+ **/
+static int pseries_prepare_late(void)
+{
+ atomic_set(&suspending, 1);
+ atomic_set(&suspend_data.working, 0);
+ atomic_set(&suspend_data.done, 0);
+ atomic_set(&suspend_data.error, 0);
+ suspend_data.complete = &suspend_work;
+ INIT_COMPLETION(suspend_work);
+ return 0;
+}
+
+/**
+ * store_hibernate - Initiate partition hibernation
+ * @classdev: sysdev class struct
+ * @attr: class device attribute struct
+ * @buf: buffer
+ * @count: buffer size
+ *
+ * Write the stream ID received from the HMC to this file
+ * to trigger hibernating the partition
+ *
+ * Return value:
+ * number of bytes printed to buffer / other on failure
+ **/
+static ssize_t store_hibernate(struct sysdev_class *classdev,
+ struct sysdev_class_attribute *attr,
+ const char *buf, size_t count)
+{
+ int rc;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ stream_id = simple_strtoul(buf, NULL, 16);
+
+ do {
+ rc = pseries_suspend_begin(PM_SUSPEND_MEM);
+ if (rc == -EAGAIN)
+ ssleep(1);
+ } while (rc == -EAGAIN);
+
+ if (!rc)
+ rc = pm_suspend(PM_SUSPEND_MEM);
+
+ stream_id = 0;
+
+ if (!rc)
+ rc = count;
+ return rc;
+}
+
+static SYSDEV_CLASS_ATTR(hibernate, S_IWUSR, NULL, store_hibernate);
+
+static struct sysdev_class suspend_sysdev_class = {
+ .name = "power",
+};
+
+static struct platform_suspend_ops pseries_suspend_ops = {
+ .valid = suspend_valid_only_mem,
+ .begin = pseries_suspend_begin,
+ .prepare_late = pseries_prepare_late,
+ .enter = pseries_suspend_enter,
+};
+
+/**
+ * pseries_suspend_sysfs_register - Register with sysfs
+ *
+ * Return value:
+ * 0 on success / other on failure
+ **/
+static int pseries_suspend_sysfs_register(struct sys_device *sysdev)
+{
+ int rc;
+
+ if ((rc = sysdev_class_register(&suspend_sysdev_class)))
+ return rc;
+
+ sysdev->id = 0;
+ sysdev->cls = &suspend_sysdev_class;
+
+ if ((rc = sysdev_class_create_file(&suspend_sysdev_class, &attr_hibernate)))
+ goto class_unregister;
+
+ return 0;
+
+class_unregister:
+ sysdev_class_unregister(&suspend_sysdev_class);
+ return rc;
+}
+
+/**
+ * pseries_suspend_init - initcall for pSeries suspend
+ *
+ * Return value:
+ * 0 on success / other on failure
+ **/
+static int __init pseries_suspend_init(void)
+{
+ int rc;
+
+ if (!machine_is(pseries) || !firmware_has_feature(FW_FEATURE_LPAR))
+ return 0;
+
+ suspend_data.token = rtas_token("ibm,suspend-me");
+ if (suspend_data.token == RTAS_UNKNOWN_SERVICE)
+ return 0;
+
+ if ((rc = pseries_suspend_sysfs_register(&suspend_sysdev)))
+ return rc;
+
+ ppc_md.suspend_disable_cpu = pseries_suspend_cpu;
+ suspend_set_ops(&pseries_suspend_ops);
+ return 0;
+}
+
+__initcall(pseries_suspend_init);
diff -puN arch/powerpc/Kconfig~powerpc_allarch_pseries_hibernation arch/powerpc/Kconfig
--- linux-2.6/arch/powerpc/Kconfig~powerpc_allarch_pseries_hibernation 2010-05-27 10:10:28.000000000 -0500
+++ linux-2.6-bjking1/arch/powerpc/Kconfig 2010-05-27 10:10:28.000000000 -0500
@@ -218,7 +218,7 @@ config ARCH_HIBERNATION_POSSIBLE
config ARCH_SUSPEND_POSSIBLE
def_bool y
depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \
- PPC_85xx || PPC_86xx
+ PPC_85xx || PPC_86xx || PPC_PSERIES
config PPC_DCR_NATIVE
bool
diff -puN arch/powerpc/platforms/pseries/Makefile~powerpc_allarch_pseries_hibernation arch/powerpc/platforms/pseries/Makefile
--- linux-2.6/arch/powerpc/platforms/pseries/Makefile~powerpc_allarch_pseries_hibernation 2010-05-27 10:10:28.000000000 -0500
+++ linux-2.6-bjking1/arch/powerpc/platforms/pseries/Makefile 2010-05-27 10:10:28.000000000 -0500
@@ -26,3 +26,7 @@ obj-$(CONFIG_HCALL_STATS) += hvCall_inst
obj-$(CONFIG_PHYP_DUMP) += phyp_dump.o
obj-$(CONFIG_CMM) += cmm.o
obj-$(CONFIG_DTL) += dtl.o
+
+ifeq ($(CONFIG_PPC_PSERIES),y)
+obj-$(CONFIG_SUSPEND) += suspend.o
+endif
diff -puN arch/powerpc/include/asm/hvcall.h~powerpc_allarch_pseries_hibernation arch/powerpc/include/asm/hvcall.h
--- linux-2.6/arch/powerpc/include/asm/hvcall.h~powerpc_allarch_pseries_hibernation 2010-05-27 10:10:28.000000000 -0500
+++ linux-2.6-bjking1/arch/powerpc/include/asm/hvcall.h 2010-05-27 10:10:28.000000000 -0500
@@ -74,6 +74,7 @@
#define H_NOT_ENOUGH_RESOURCES -44
#define H_R_STATE -45
#define H_RESCINDEND -46
+#define H_MULTI_THREADS_ACTIVE -9005
/* Long Busy is a condition that can be returned by the firmware
diff -puN arch/powerpc/include/asm/machdep.h~powerpc_allarch_pseries_hibernation arch/powerpc/include/asm/machdep.h
--- linux-2.6/arch/powerpc/include/asm/machdep.h~powerpc_allarch_pseries_hibernation 2010-05-27 10:10:28.000000000 -0500
+++ linux-2.6-bjking1/arch/powerpc/include/asm/machdep.h 2010-05-27 10:10:28.000000000 -0500
@@ -266,6 +266,7 @@ struct machdep_calls {
void (*suspend_disable_irqs)(void);
void (*suspend_enable_irqs)(void);
#endif
+ int (*suspend_disable_cpu)(void);
#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
ssize_t (*cpu_probe)(const char *, size_t);
diff -puN arch/powerpc/platforms/pseries/hotplug-cpu.c~powerpc_allarch_pseries_hibernation arch/powerpc/platforms/pseries/hotplug-cpu.c
--- linux-2.6/arch/powerpc/platforms/pseries/hotplug-cpu.c~powerpc_allarch_pseries_hibernation 2010-05-27 10:10:28.000000000 -0500
+++ linux-2.6-bjking1/arch/powerpc/platforms/pseries/hotplug-cpu.c 2010-05-27 10:10:28.000000000 -0500
@@ -116,6 +116,9 @@ static void pseries_mach_cpu_die(void)
if (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) {
set_cpu_current_state(cpu, CPU_STATE_INACTIVE);
+ if (ppc_md.suspend_disable_cpu)
+ ppc_md.suspend_disable_cpu();
+
cede_latency_hint = 2;
get_lppaca()->idle = 1;
_
^ permalink raw reply
* Re: [PATCH V4] powerpc/mpc512x: Add gpio driver
From: Grant Likely @ 2010-06-10 21:48 UTC (permalink / raw)
To: Anatolij Gustschin
Cc: linuxppc-dev, Wolfgang Denk, Detlev Zundel, Matthias Fuchs
In-Reply-To: <1276186867-29094-1-git-send-email-agust@denx.de>
On Thu, Jun 10, 2010 at 10:21 AM, Anatolij Gustschin <agust@denx.de> wrote:
> From: Matthias Fuchs <matthias.fuchs@esd.eu>
>
> This patch adds a gpio driver for MPC512X PowerPCs.
>
> It has been tested on our CAN-CBX-CPU5201 module that
> uses a MPC5121 CPU. This platform comes with a couple of
> LEDs and configuration switches that have been used for testing.
>
> Signed-off-by: Matthias Fuchs <matthias.fuchs@esd.eu>
> Signed-off-by: Anatolij Gustschin <agust@denx.de>
Hi Anatolij,
Can you please rework this one on top of my next-devicetree branch.
Change have been made to the of-gpio apis.
g.
> ---
> Please consider this patch for inclusion in 2.6.36. Thanks!
>
> v4: - actually v3 was rebased but without shadow
> =A0 =A0 =A0registers init code as stated in the v3 changelog.
> =A0 =A0 =A0Correct it now.
>
> v3: - rebase to apply on current mainline tree
> =A0 =A0- v2 switched to shadow registers but these are
> =A0 =A0 =A0not pre-initialized (zero). As a result, setting
> =A0 =A0 =A0pin direction or ODR register will clear other bits
> =A0 =A0 =A0in direction and ODR registers. Fix this bug by adding
> =A0 =A0 =A0shadow registers initialization code.
>
> v2: - move driver to arch/powerpc/platforms/512x directory
> =A0 =A0- Kconfig changes are now in arch/powerpc/platform/512x/Kconfig
> =A0 =A0- put struct mpc512x_gpio_regs in driver's .c file
> =A0 =A0- rename GPIO_MASK into MPC512x_GPIO_MASK
> =A0 =A0- use shadow registers instead of r/m/w-operations
> =A0 =A0- don't use arch_initcall but call mpc512x_add_gpiochips()
> =A0 =A0 =A0from mpc512x platform setup code.
>
> =A0arch/powerpc/platforms/512x/Kconfig =A0 =A0 =A0 =A0 =A0| =A0 =A09 +
> =A0arch/powerpc/platforms/512x/Makefile =A0 =A0 =A0 =A0 | =A0 =A01 +
> =A0arch/powerpc/platforms/512x/mpc512x.h =A0 =A0 =A0 =A0| =A0 =A03 +
> =A0arch/powerpc/platforms/512x/mpc512x_gpio.c =A0 | =A0204 ++++++++++++++=
++++++++++++
> =A0arch/powerpc/platforms/512x/mpc512x_shared.c | =A0 =A03 +
> =A05 files changed, 220 insertions(+), 0 deletions(-)
> =A0create mode 100644 arch/powerpc/platforms/512x/mpc512x_gpio.c
>
> diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms=
/512x/Kconfig
> index 4dac9b0..bd763ee 100644
> --- a/arch/powerpc/platforms/512x/Kconfig
> +++ b/arch/powerpc/platforms/512x/Kconfig
> @@ -30,3 +30,12 @@ config MPC5121_GENERIC
>
> =A0 =A0 =A0 =A0 =A0Compatible boards include: =A0Protonic LVT base boards=
(ZANMCU
> =A0 =A0 =A0 =A0 =A0and VICVT2).
> +
> +config MPC512x_GPIO
> + =A0 =A0 =A0 bool "MPC512x GPIO support"
> + =A0 =A0 =A0 depends on PPC_MPC512x
> + =A0 =A0 =A0 select GENERIC_GPIO
> + =A0 =A0 =A0 select ARCH_REQUIRE_GPIOLIB
> + =A0 =A0 =A0 help
> + =A0 =A0 =A0 =A0 Say Y here if you're going to use hardware that connect=
s to the
> + =A0 =A0 =A0 =A0 MPC512x GPIOs.
> diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platform=
s/512x/Makefile
> index 90be2f5..12518e3 100644
> --- a/arch/powerpc/platforms/512x/Makefile
> +++ b/arch/powerpc/platforms/512x/Makefile
> @@ -4,3 +4,4 @@
> =A0obj-y =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0+=3D clock.o =
mpc512x_shared.o
> =A0obj-$(CONFIG_MPC5121_ADS) =A0 =A0 =A0+=3D mpc5121_ads.o mpc5121_ads_cp=
ld.o
> =A0obj-$(CONFIG_MPC5121_GENERIC) =A0+=3D mpc5121_generic.o
> +obj-$(CONFIG_MPC512x_GPIO) =A0 =A0 +=3D mpc512x_gpio.o
> diff --git a/arch/powerpc/platforms/512x/mpc512x.h b/arch/powerpc/platfor=
ms/512x/mpc512x.h
> index b2daca0..4a1b094 100644
> --- a/arch/powerpc/platforms/512x/mpc512x.h
> +++ b/arch/powerpc/platforms/512x/mpc512x.h
> @@ -16,4 +16,7 @@ extern void __init mpc512x_init(void);
> =A0extern int __init mpc5121_clk_init(void);
> =A0void __init mpc512x_declare_of_platform_devices(void);
> =A0extern void mpc512x_restart(char *cmd);
> +#ifdef CONFIG_MPC512x_GPIO
> +extern int mpc512x_add_gpiochips(void);
> +#endif
> =A0#endif =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* __MPC512X_H_=
_ */
> diff --git a/arch/powerpc/platforms/512x/mpc512x_gpio.c b/arch/powerpc/pl=
atforms/512x/mpc512x_gpio.c
> new file mode 100644
> index 0000000..13b2478
> --- /dev/null
> +++ b/arch/powerpc/platforms/512x/mpc512x_gpio.c
> @@ -0,0 +1,204 @@
> +/*
> + * MPC512x gpio driver
> + *
> + * Copyright (c) 2010 Matthias Fuchs <matthias.fuchs@esd.eu>, esd gmbh
> + *
> + * derived from ppc4xx gpio driver
> + *
> + * Copyright (c) 2008 Harris Corporation
> + * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
> + * Copyright (c) MontaVista Software, Inc. 2008.
> + *
> + * Author: Steve Falco <sfalco@harris.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2
> + * as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. =A0See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA =A002111-130=
7 =A0USA
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/spinlock.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_gpio.h>
> +#include <linux/gpio.h>
> +#include <linux/types.h>
> +
> +#define MPC512x_GPIO_MASK(gpio) (0x80000000 >> (gpio))
> +
> +struct mpc512x_gpio_regs {
> + =A0 =A0 =A0 u32 gpdir;
> + =A0 =A0 =A0 u32 gpodr;
> + =A0 =A0 =A0 u32 gpdat;
> + =A0 =A0 =A0 u32 gpier;
> + =A0 =A0 =A0 u32 gpimr;
> + =A0 =A0 =A0 u32 gpicr1;
> + =A0 =A0 =A0 u32 gpicr2;
> +};
> +
> +struct mpc512x_chip {
> + =A0 =A0 =A0 struct of_mm_gpio_chip mm_gc;
> + =A0 =A0 =A0 spinlock_t lock;
> +
> + =A0 =A0 =A0 /* shadow registers */
> + =A0 =A0 =A0 u32 dat;
> + =A0 =A0 =A0 u32 odr;
> + =A0 =A0 =A0 u32 dir;
> +};
> +
> +/*
> + * GPIO LIB API implementation for GPIOs
> + *
> + * There are a maximum of 32 gpios in each gpio controller.
> + */
> +static inline struct mpc512x_chip *
> +to_mpc512x_gpiochip(struct of_mm_gpio_chip *mm_gc)
> +{
> + =A0 =A0 =A0 return container_of(mm_gc, struct mpc512x_chip, mm_gc);
> +}
> +
> +static int mpc512x_gpio_get(struct gpio_chip *gc, unsigned int gpio)
> +{
> + =A0 =A0 =A0 struct of_mm_gpio_chip *mm_gc =3D to_of_mm_gpio_chip(gc);
> + =A0 =A0 =A0 struct mpc512x_gpio_regs __iomem *regs =3D mm_gc->regs;
> +
> + =A0 =A0 =A0 return in_be32(®s->gpdat) & MPC512x_GPIO_MASK(gpio);
> +}
> +
> +static inline void
> +__mpc512x_gpio_set(struct of_mm_gpio_chip *mm_gc, unsigned int gpio, int=
val)
> +{
> + =A0 =A0 =A0 struct mpc512x_chip *chip =3D to_mpc512x_gpiochip(mm_gc);
> + =A0 =A0 =A0 struct mpc512x_gpio_regs __iomem *regs =3D mm_gc->regs;
> +
> +
> + =A0 =A0 =A0 if (val)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 chip->dat |=3D MPC512x_GPIO_MASK(gpio);
> + =A0 =A0 =A0 else
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 chip->dat &=3D ~MPC512x_GPIO_MASK(gpio);
> +
> + =A0 =A0 =A0 out_be32(®s->gpdat, chip->dat);
> +}
> +
> +static void
> +mpc512x_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
> +{
> + =A0 =A0 =A0 struct of_mm_gpio_chip *mm_gc =3D to_of_mm_gpio_chip(gc);
> + =A0 =A0 =A0 struct mpc512x_chip *chip =3D to_mpc512x_gpiochip(mm_gc);
> + =A0 =A0 =A0 unsigned long flags;
> +
> + =A0 =A0 =A0 spin_lock_irqsave(&chip->lock, flags);
> +
> + =A0 =A0 =A0 __mpc512x_gpio_set(mm_gc, gpio, val);
> +
> + =A0 =A0 =A0 spin_unlock_irqrestore(&chip->lock, flags);
> +
> + =A0 =A0 =A0 pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
> +}
> +
> +static int mpc512x_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
> +{
> + =A0 =A0 =A0 struct of_mm_gpio_chip *mm_gc =3D to_of_mm_gpio_chip(gc);
> + =A0 =A0 =A0 struct mpc512x_chip *chip =3D to_mpc512x_gpiochip(mm_gc);
> + =A0 =A0 =A0 struct mpc512x_gpio_regs __iomem *regs =3D mm_gc->regs;
> + =A0 =A0 =A0 unsigned long flags;
> +
> + =A0 =A0 =A0 spin_lock_irqsave(&chip->lock, flags);
> +
> + =A0 =A0 =A0 /* Disable open-drain function */
> + =A0 =A0 =A0 chip->odr &=3D ~MPC512x_GPIO_MASK(gpio);
> + =A0 =A0 =A0 out_be32(®s->gpodr, chip->odr);
> +
> + =A0 =A0 =A0 /* Float the pin */
> + =A0 =A0 =A0 chip->dir &=3D ~MPC512x_GPIO_MASK(gpio);
> + =A0 =A0 =A0 out_be32(®s->gpdir, chip->dir);
> +
> + =A0 =A0 =A0 spin_unlock_irqrestore(&chip->lock, flags);
> +
> + =A0 =A0 =A0 return 0;
> +}
> +
> +static int
> +mpc512x_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
> +{
> + =A0 =A0 =A0 struct of_mm_gpio_chip *mm_gc =3D to_of_mm_gpio_chip(gc);
> + =A0 =A0 =A0 struct mpc512x_chip *chip =3D to_mpc512x_gpiochip(mm_gc);
> + =A0 =A0 =A0 struct mpc512x_gpio_regs __iomem *regs =3D mm_gc->regs;
> + =A0 =A0 =A0 unsigned long flags;
> +
> + =A0 =A0 =A0 spin_lock_irqsave(&chip->lock, flags);
> +
> + =A0 =A0 =A0 /* First set initial value */
> + =A0 =A0 =A0 __mpc512x_gpio_set(mm_gc, gpio, val);
> +
> + =A0 =A0 =A0 /* Disable open-drain function */
> + =A0 =A0 =A0 chip->odr &=3D ~MPC512x_GPIO_MASK(gpio);
> + =A0 =A0 =A0 out_be32(®s->gpodr, chip->odr);
> +
> + =A0 =A0 =A0 /* Drive the pin */
> + =A0 =A0 =A0 chip->dir |=3D MPC512x_GPIO_MASK(gpio);
> + =A0 =A0 =A0 out_be32(®s->gpdir, chip->dir);
> +
> + =A0 =A0 =A0 spin_unlock_irqrestore(&chip->lock, flags);
> +
> + =A0 =A0 =A0 pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
> +
> + =A0 =A0 =A0 return 0;
> +}
> +
> +void __init mpc512x_add_gpiochips(void)
> +{
> + =A0 =A0 =A0 struct device_node *np;
> +
> + =A0 =A0 =A0 for_each_compatible_node(np, NULL, "fsl,mpc5121-gpio") {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 int ret;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct mpc512x_chip *chip;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct of_mm_gpio_chip *mm_gc;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct of_gpio_chip *of_gc;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct gpio_chip *gc;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct mpc512x_gpio_regs __iomem *regs;
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 chip =3D kzalloc(sizeof(*chip), GFP_KERNEL)=
;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!chip) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ret =3D -ENOMEM;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto err;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 spin_lock_init(&chip->lock);
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 mm_gc =3D &chip->mm_gc;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 of_gc =3D &mm_gc->of_gc;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 gc =3D &of_gc->gc;
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 gc->ngpio =3D 32;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 gc->direction_input =3D mpc512x_gpio_dir_in=
;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 gc->direction_output =3D mpc512x_gpio_dir_o=
ut;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 gc->get =3D mpc512x_gpio_get;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 gc->set =3D mpc512x_gpio_set;
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 ret =3D of_mm_gpiochip_add(np, mm_gc);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (ret)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto err;
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 regs =3D mm_gc->regs;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 chip->dat =3D in_be32(®s->gpdat);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 chip->dir =3D in_be32(®s->gpdir);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 chip->odr =3D in_be32(®s->gpodr);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue;
> +err:
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 pr_err("%s: registration failed with status=
%d\n",
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0np->full_name, ret);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 kfree(chip);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* try others anyway */
> + =A0 =A0 =A0 }
> +}
> diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/=
platforms/512x/mpc512x_shared.c
> index 707e572..15da1bc 100644
> --- a/arch/powerpc/platforms/512x/mpc512x_shared.c
> +++ b/arch/powerpc/platforms/512x/mpc512x_shared.c
> @@ -178,4 +178,7 @@ void __init mpc512x_init(void)
> =A0 =A0 =A0 =A0mpc5121_clk_init();
> =A0 =A0 =A0 =A0mpc512x_restart_init();
> =A0 =A0 =A0 =A0mpc512x_psc_fifo_init();
> +#ifdef CONFIG_MPC512x_GPIO
> + =A0 =A0 =A0 mpc512x_add_gpiochips();
> +#endif
> =A0}
> --
> 1.7.0.4
>
>
--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Re: [PATCH V4] powerpc/mpc512x: Add gpio driver
From: Anatolij Gustschin @ 2010-06-10 22:01 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev, Wolfgang Denk, Detlev Zundel, Matthias Fuchs
In-Reply-To: <AANLkTik7pTXHdY9_sjL9Lyz68gk2qRUs0NaGpj_7nL7K@mail.gmail.com>
Hi Grant,
On Thu, 10 Jun 2010 15:48:42 -0600
Grant Likely <grant.likely@secretlab.ca> wrote:
> On Thu, Jun 10, 2010 at 10:21 AM, Anatolij Gustschin <agust@denx.de> wrote:
> > From: Matthias Fuchs <matthias.fuchs@esd.eu>
> >
> > This patch adds a gpio driver for MPC512X PowerPCs.
> >
> > It has been tested on our CAN-CBX-CPU5201 module that
> > uses a MPC5121 CPU. This platform comes with a couple of
> > LEDs and configuration switches that have been used for testing.
> >
> > Signed-off-by: Matthias Fuchs <matthias.fuchs@esd.eu>
> > Signed-off-by: Anatolij Gustschin <agust@denx.de>
>
> Hi Anatolij,
>
> Can you please rework this one on top of my next-devicetree branch.
> Change have been made to the of-gpio apis.
Ok, I'll look at it.
Anatolij
^ permalink raw reply
* Re: [PATCH 2/2 v2] sound/soc: mpc5200_psc_ac97: Use gpio pins for cold reset.
From: Grant Likely @ 2010-06-10 22:02 UTC (permalink / raw)
To: Eric Millbrandt; +Cc: Mark Brown, linuxppc-dev
In-Reply-To: <1276097965-6592-1-git-send-email-emillbrandt@dekaresearch.com>
On Wed, Jun 9, 2010 at 9:39 AM, Eric Millbrandt
<emillbrandt@dekaresearch.com> wrote:
> The implementation of the ac97 "cold" reset is flawed. =A0If the sync and
> output lines are high when reset is asserted the attached ac97 device
> may go into test mode. =A0Avoid this by reconfiguring the psc to gpio mod=
e
> and generating the reset manually.
Hi Eric,
Thanks for the patch. Given a) that this is essentially a silicon
bug, b) that AC97 only works on PSCs 1 & 2 which cannot be relocated
to different pins, c) that I really want to avoid giving drivers
access to port_config even through an API, and d) All mpc5200 AC97
systems will probably have the same issue, I think this is something
that shouldn't require a change to the device tree, and can probably
be contained within arch/powerpc/platforms/52xx.
Overall, I have no problem with the function of the change, but I'd
like to see these two changes:
- Add a helper function ot arch/powerpc/platforms/52xx to perform an
AC97 reset using GPIOs (select GPIO in port_config, toggle reset,
select PSC in port_config). Something like
mpc5200_psc_ac97_gpio_reset(int psc_number). Just move the GPIO bits.
The PSC mode setting can be left in the driver.
- Go ahead and hardcode the GPIO numbers into the platform code. It
is definitely a hardware bug workaround, and it isn't something that
would normally be described in the device tree (though you probably
need to make the gpio_lock spinlock non-static to maintain mutual
exclusion).
g.
^ permalink raw reply
* Re: [PATCH 0/2] mpc5200 ac97 gpio reset
From: Grant Likely @ 2010-06-10 22:07 UTC (permalink / raw)
To: Mark Brown; +Cc: linuxppc-dev, Wolfgang Denk, Eric Millbrandt
In-Reply-To: <20100609103046.GC5618@opensource.wolfsonmicro.com>
On Wed, Jun 9, 2010 at 4:30 AM, Mark Brown
<broonie@opensource.wolfsonmicro.com> wrote:
> On Wed, Jun 09, 2010 at 08:13:30AM +0200, Wolfgang Denk wrote:
>> In message <AANLkTimIs90kR5uqhdBQ02oSd94dn08sOITm51Ylrl4-@mail.gmail.com=
> you wrote:
>
>> > Would making a change in uboot be a better solution? Eric, can you
>> > verify if changing uboot also fixes the problem?
>
>> To me it seems better if the driver itself does what needs to be done
>> instead of relying on specific settings that may or may not be done in
>> U-Boot. Keep in mind that drivers may be loaded as modules, and that
>> we even see cases where the same port serves multiple purposes by
>> loading different driver modules (yes, this is not exactly a clever
>> idea, but hardware designers come up with such solutions).
>
> I do tend to agree that having the driver be able to cope with things is
> a bit more robust - it's not terribly discoverable for users and people
> are often justifiably nervous about updating their bootloader.
>
> It might, however, be sensible to make the GPIO based reset be optional
> based on having the OF data for the GPIOs. =A0That way existing DTs will
> work without changes and systems that can use the reset implementation
> in the controller will be able to do so.
To me, this seems firmly in the realm of silicon bug workaround.
Considering that the pins aren't relocatable (ie, the GPIO numbers
never change), I've got no problem having the GPIO reset logic added
to arch/powerpc/platforms/52xx and hard coding the GPIO numbers.
I completely agree that it should not require a firmware update to get
the hardware to work correctly.
g.
^ permalink raw reply
* Re: [PATCH 1/2] powerpc/5200: Export port-config
From: Grant Likely @ 2010-06-10 22:11 UTC (permalink / raw)
To: Eric Millbrandt; +Cc: Mark Brown, linuxppc-dev
In-Reply-To: <1276015562-28928-2-git-send-email-emillbrandt@dekaresearch.com>
On Tue, Jun 8, 2010 at 10:46 AM, Eric Millbrandt
<emillbrandt@dekaresearch.com> wrote:
> Allow device drivers to safely modify port-config. =A0This allows device =
drivers
> access to gpio pins to manually bit-bang slave devices.
>
> Signed-off-by: Eric Millbrandt <emillbrandt@dekaresearch.com>
Unfortunately, still too much exposure of port-config to drivers for
my liking. I'd be happier with an API that requests the mode for a
specific pin group instead of directly masking & setting bits....
but of course I've also just said in my other email that I'd be happy
with all of the GPIO AC97reset logic being contained in
arch/powerpc/platforms/52xx which kind of makes the comment moot. :-)
g.
> ---
> =A0arch/powerpc/include/asm/mpc52xx.h =A0 =A0 =A0 =A0 =A0 | =A0 =A02 +
> =A0arch/powerpc/platforms/52xx/mpc52xx_common.c | =A0 61 ++++++++++++++++=
++++++++++
> =A02 files changed, 63 insertions(+), 0 deletions(-)
^ permalink raw reply
* RE: Port Linux to ML510
From: kostas padarnitsas @ 2010-06-10 23:12 UTC (permalink / raw)
To: skrishnakar; +Cc: linuxppc-dev
In-Reply-To: <AANLkTimQNPb0WAvAk6mNAsy25k0OZ482EwLCD0wlukvl@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1994 bytes --]
Hi Srikant,
Thanks for your help. I checked the driver versions and they seem ok. The problem is that when I download the linux image the program counter is not set to the address of boot sector of linux kernel, so linux doesn't boot. On the other hand with the ML507 everything works perfectly. Any idea??
Thanks in advance,Kostas
Date: Thu, 10 Jun 2010 12:34:56 +0530
Subject: Re: Port Linux to ML510
From: skrishnakar@gmail.com
To: kpada84@hotmail.com
CC: linuxppc-dev@lists.ozlabs.org
Hi kostas,
You need to verify that the driver version of serial and Ethernet (probably X-LLTEMAC) provided in the virtex440.dts matches version used in kernel. Look for "compatible = <version>" in the drivers. You can probably use EDK 11.2 as it is the latest from Xilinx.
Have you generated your own DTS and Bitstream (download.bit) files ?
If not then you should look for suitable download.bit for you kernel.
-Srikant
2010/6/10 kostas padarnitsas <kpada84@hotmail.com>
Hello,
I am trying to port Linux to PowerPC on the ML510 Xilinx board. I am using EDK 10.1.3 to build the hardware and also device tree generator and the linux kernel from xilinx git. I followed the tutorial from http://xilinx.wikidot.com/powerpc-linux but I have no output. I have attached my .mhs file and the .dts. Any ideas what may cause this problem because I did the same thing with ML507 and it was working perfectly?
Thanks in advance,Kostas
Your E-mail and More On-the-Go. Get Windows Live Hotmail Free. Sign up now.
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev
--
"The Good You Do, The Best You GET"
Regards
Srikanth Krishnakar
**********************
_________________________________________________________________
Hotmail: Free, trusted and rich email service.
https://signup.live.com/signup.aspx?id=60969
[-- Attachment #2: Type: text/html, Size: 2888 bytes --]
^ permalink raw reply
* Re: [PATCH 0/2] mpc5200 ac97 gpio reset
From: Mark Brown @ 2010-06-10 23:14 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev, Wolfgang Denk, Eric Millbrandt
In-Reply-To: <AANLkTinascmPq38PptPH3tRJS-P8IqO9tdLbVb5erLRY@mail.gmail.com>
On 10 Jun 2010, at 23:07, Grant Likely wrote:
> To me, this seems firmly in the realm of silicon bug workaround.
> Considering that the pins aren't relocatable (ie, the GPIO numbers
> never change), I've got no problem having the GPIO reset logic added
> to arch/powerpc/platforms/52xx and hard coding the GPIO numbers.
Since the pins are fixed I agree - I was assuming that the DT updates
were there because there were multiple pin mux options for the AC'97
controller so we needed the DT to say which were in use on the board.
^ permalink raw reply
* Re: [PATCH 0/2] mpc5200 ac97 gpio reset
From: Grant Likely @ 2010-06-10 23:31 UTC (permalink / raw)
To: Mark Brown; +Cc: linuxppc-dev, Wolfgang Denk, Eric Millbrandt
In-Reply-To: <333E09B4-32C5-483A-9C1F-A1206AF937B0@opensource.wolfsonmicro.com>
On Thu, Jun 10, 2010 at 5:14 PM, Mark Brown
<broonie@opensource.wolfsonmicro.com> wrote:
> On 10 Jun 2010, at 23:07, Grant Likely wrote:
>
>> To me, this seems firmly in the realm of silicon bug workaround.
>> Considering that the pins aren't relocatable (ie, the GPIO numbers
>> never change), I've got no problem having the GPIO reset logic added
>> to arch/powerpc/platforms/52xx and hard coding the GPIO numbers.
>
> Since the pins are fixed I agree - I was assuming that the DT updates
> were there because there were multiple pin mux options for the AC'97
> controller so we needed the DT to say which were in use on the board.
:-) I originally also made the same assumption, until I actually went
and looked at the data sheet.
g.
^ permalink raw reply
* Re: [PATCH 5/5] of/irq: merge of_irq_map_one()
From: Grant Likely @ 2010-06-10 23:36 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Stephen Rothwell, Michal Simek, microblaze-uclinux,
devicetree-discuss, linuxppc-dev
In-Reply-To: <1276152002.1962.55.camel@pasglop>
On Thu, Jun 10, 2010 at 12:40 AM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Fri, 2010-06-04 at 15:21 -0600, Grant Likely wrote:
>> Merge common implementation of of_irq_map_one(). =A0Rename it to
>> __of_irq_map_one() so that arch code can either use the stock
>> implementation, or override it to handle platform quirks.
>
> Similar comment to before, I think the breakup of functions causes more
> complication and bloat than just keeping the quirks in the generic code.
Okay. I had been trying to avoid #ifdefs in the common code, but
you're probably right. I'll rework.
g.
^ permalink raw reply
* Re: [PATCH 5/5] hvc_console: Fix race between hvc_close and hvc_remove
From: Stephen Rothwell @ 2010-06-11 0:53 UTC (permalink / raw)
To: John Kacur
Cc: Rusty Russell, Clark Williams, Greg Kroah-Hartman,
Arnaldo Carvalho de Melo, linuxppc-dev, Amit Shah,
Thomas Gleixner, Luis Claudio R. Goncalves, Alan Cox
In-Reply-To: <1276167780-23002-6-git-send-email-jkacur@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 536 bytes --]
Hi John,
On Thu, 10 Jun 2010 13:03:00 +0200 John Kacur <jkacur@redhat.com> wrote:
>
> From: Amit Shah <amit.shah@redhat.com>
>
> Alan pointed out a race in the code where hvc_remove is invoked. The
> recent virtio_console work is the first user of hvc_remove().
I am not sure where this comes from (linuxppc-dev only got 5/5) but this
patch was applied to Linus' tree quite some time age (and fixed since
then).
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* Re: [PATCH 5/5] of/address: restrict 'no-ranges' kludge to powerpc
From: Benjamin Herrenschmidt @ 2010-06-11 1:12 UTC (permalink / raw)
To: Grant Likely; +Cc: Stephen Rothwell, devicetree-discuss, linuxppc-dev
In-Reply-To: <AANLkTikg1hLdV_OUjc3QIhFatP_iLfVClhzmyixmjje1@mail.gmail.com>
On Thu, 2010-06-10 at 08:28 -0600, Grant Likely wrote:
> On Thu, Jun 10, 2010 at 12:44 AM, Benjamin Herrenschmidt
> <benh@kernel.crashing.org> wrote:
> > On Tue, 2010-06-08 at 08:10 -0600, Grant Likely wrote:
> >> Certain Apple machines don't use the ranges property correctly, but the
> >> workaround should not be applied on other architectures. This patch
> >> disables the workaround for non-powerpc architectures.
> >
> > I'm half tempted to add it to the quirk list (which should really be
> > made generic) so I can disable it on more 'modern' powerpc as well.
>
> In the mean time, are you okay with this version of the patch?
For the time being yes.
Cheers,
Ben.
> g.
>
> >
> > Cheers,
> > Ben.
> >
> >> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> >> CC: Stephen Rothwell <sfr@canb.auug.org.au>
> >> CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> >> CC: linuxppc-dev@lists.ozlabs.org
> >> CC: devicetree-discuss@lists.ozlabs.org
> >> ---
> >> drivers/of/address.c | 11 ++++++++++-
> >> 1 files changed, 10 insertions(+), 1 deletions(-)
> >>
> >> diff --git a/drivers/of/address.c b/drivers/of/address.c
> >> index 0b04137..5c220c3 100644
> >> --- a/drivers/of/address.c
> >> +++ b/drivers/of/address.c
> >> @@ -346,12 +346,21 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
> >> * a 1:1 translation at that level. It's up to the caller not to try
> >> * to translate addresses that aren't supposed to be translated in
> >> * the first place. --BenH.
> >> + *
> >> + * As far as we know, this damage only exists on Apple machines, so
> >> + * This code is only enabled on powerpc. --gcl
> >> */
> >> ranges = of_get_property(parent, rprop, &rlen);
> >> +#if !defined(CONFIG_PPC)
> >> + if (ranges == NULL) {
> >> + pr_err("OF: no ranges; cannot translate\n");
> >> + return 1;
> >> + }
> >> +#endif /* !defined(CONFIG_PPC) */
> >> if (ranges == NULL || rlen == 0) {
> >> offset = of_read_number(addr, na);
> >> memset(addr, 0, pna * 4);
> >> - pr_debug("OF: no ranges, 1:1 translation\n");
> >> + pr_debug("OF: empty ranges; 1:1 translation\n");
> >> goto finish;
> >> }
> >>
> >
> >
> >
>
>
>
^ permalink raw reply
* Re: [PATCH 6/6] of/device: populate platform_device (of_device) resource table on allocation
From: Benjamin Herrenschmidt @ 2010-06-11 1:14 UTC (permalink / raw)
To: M. Warner Losh
Cc: sfr, microblaze-uclinux, devicetree-discuss, jeremy.kerr,
linuxppc-dev
In-Reply-To: <20100610.100140.8559628065321695.imp@bsdimp.com>
On Thu, 2010-06-10 at 10:01 -0600, M. Warner Losh wrote:
> : Oh, come on. Both constructions are binary equivalent.
> :
> : So how can people seriously be with *that* code:
> :
> : dev->resource = (void *)&dev[1];
> :
> : which, semantically, is a nonsense and asks for a fix.
>
> It isn't nonsense. That's just your opinion of it, nothing more.
No, it's dangerously fragile abuse of the C language which loses type
safety etc... It might be correct, but if somebody comes back in 2 year
to change something in that code, the chances of breaking it are higher
than having the type safe:
> : dev_obj->dev.resource = dev_obj->resource;
> :
Variant.
It's also less ugly.
> : simply makes sense.
>
> But this requires extra, bogus fields in the structure and creates a
> bogus sizeof issue.
>
> There are problems both ways. Yelling about it isn't going to make
> you any more right, or convince me that I'm wrong. It is an argument
> that is at least two decades old...
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH 0/2] Replace of_device with platform_device
From: Benjamin Herrenschmidt @ 2010-06-11 1:16 UTC (permalink / raw)
To: Grant Likely
Cc: Stephen Rothwell, Michal Simek, microblaze-uclinux, linuxppc-dev,
sparclinux, David Miller
In-Reply-To: <AANLkTik2j5iDwcgIl_WyajaSRqLx5WK8Zf-25FBJ92Ch@mail.gmail.com>
On Thu, 2010-06-10 at 10:46 -0600, Grant Likely wrote:
>
> It shouldn't need any fixing because I'm not touching the driver side
> of the equation (unlike the last breakage where macio_driver had its
> own copy of the match table which I missed). In fact, there aren't
> even any logic changes other than dealing with moving some of the
> structure members in the sparc arch code. If I did miss anything,
> then it should show up in build testing.
Ok, but I though you were actually replacing occurences of "of_device"
with "platform_device", and so was wondering why you aren't changing the
ones in macio. But yes, the #define you did might do the trick as long
as the resources are still named the same etc...
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH 5/5] of/irq: merge of_irq_map_one()
From: Benjamin Herrenschmidt @ 2010-06-11 1:17 UTC (permalink / raw)
To: Grant Likely
Cc: Stephen Rothwell, Michal Simek, microblaze-uclinux,
devicetree-discuss, linuxppc-dev
In-Reply-To: <AANLkTinmDFBvAjcjrgf3RHuiXgNxVV20yLzBaqhE5lrk@mail.gmail.com>
On Thu, 2010-06-10 at 17:36 -0600, Grant Likely wrote:
>
> Okay. I had been trying to avoid #ifdefs in the common code, but
> you're probably right. I'll rework.
Not even ifdef's ... just move the quirk map there. You can always
#define the quirk variable to 0 on archs that have no quirks, to
make it compile away if you believe it represents bloat, but they
are simple well localized things so I doubt it matters.
Cheers,
Ben.
^ permalink raw reply
* PCIe bus seems work while 'dma' can't under linux
From: jxnuxdy @ 2010-06-11 1:30 UTC (permalink / raw)
To: linuxppc-dev
Cc: Stephen Rothwell, Michal Simek, devicetree-discuss,
microblaze-uclinux
In-Reply-To: <1276219072.1962.82.camel@pasglop>
Hi guys,
I encountered a PCIe problem under linux, the two PCIe bus on my board seems work, at least I can access the registers through the PCIe bus, however the dma for the PCIe bus can't work, so I just dumped the pci device, but I am curiously to find there is no regions displayed on PCIe controlers, why? is it relate with my 'dma' issue then?
bash-2.04# cat /proc/pci
PCI devices found:
Bus 0, device 0, function 0:
Class 0b20 Header Type 01: PCI device 1957:0032 (rev 17).
Bus 1, device 0, function 0:
Class 0580 Header Type 00: PCI device 11ab:db90 (rev 1).
Prefetchable 64 bit memory at 0x80000000 [0x800fffff].
Prefetchable 64 bit memory at 0x84000000 [0x87ffffff].
Bus 9, device 0, function 0:
Class 0b20 Header Type 01: PCI device 1957:0032 (rev 17).
Bus 10, device 0, function 0:
Class 0580 Header Type 00: PCI device 11ab:db90 (rev 1).
Prefetchable 64 bit memory at 0xa0000000 [0xa00fffff].
Prefetchable 64 bit memory at 0xa4000000 [0xa7ffffff].
bash-2.04# lspci -vv
00:00.0 Power PC: Unknown device 1957:0032 (rev 11)
!!! Invalid class 0b20 for header type 01
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
Latency: 0, cache line size 08
Bus: primary=00, secondary=01, subordinate=06, sec-latency=0
I/O behind bridge: 00000000-00000fff
Memory behind bridge: 80000000-9fffffff
BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
Capabilities: [44] Power Management version 2
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold+)
Status: D0 PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [4c] #10 [0041]
01:00.0 Memory controller: Galileo Technology Ltd.: Unknown device db90 (rev 01)
Subsystem: Galileo Technology Ltd.: Unknown device 11ab
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
Latency: 0, cache line size 08
Interrupt: pin A routed to IRQ 0
Region 0: Memory at 80000000 (64-bit, prefetchable) [size=1M]
Region 2: Memory at 84000000 (64-bit, prefetchable) [size=64M]
Capabilities: [40] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [50] Message Signalled Interrupts: 64bit+ Queue=0/0 Enable-
Address: 0000000000000000 Data: 0000
Capabilities: [60] #10 [0011]
09:00.0 Power PC: Unknown device 1957:0032 (rev 11)
!!! Invalid class 0b20 for header type 01
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
Latency: 0, cache line size 08
Bus: primary=00, secondary=0a, subordinate=0f, sec-latency=0
I/O behind bridge: 00000000-00000fff
Memory behind bridge: a0000000-bfffffff
BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
Capabilities: [44] Power Management version 2
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold+)
Status: D0 PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [4c] #10 [0041]
0a:00.0 Memory controller: Galileo Technology Ltd.: Unknown device db90 (rev 01)
Subsystem: Galileo Technology Ltd.: Unknown device 11ab
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
Latency: 0, cache line size 08
Interrupt: pin A routed to IRQ 0
Region 0: Memory at a0000000 (64-bit, prefetchable) [size=1M]
Region 2: Memory at a4000000 (64-bit, prefetchable) [size=64M]
Capabilities: [40] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [50] Message Signalled Interrupts: 64bit+ Queue=0/0 Enable-
Address: 0000000000000000 Data: 0000
Capabilities: [60] #10 [0011]
bash-2.04#
Thanks
Denny
^ permalink raw reply
* Re: 2.6.35-rc2 : OOPS with LTP memcg regression test run.
From: KAMEZAWA Hiroyuki @ 2010-06-11 1:35 UTC (permalink / raw)
To: maciej.rutecki; +Cc: linux-mm, linux-kernel, Linux/PPC Development
In-Reply-To: <201006102200.57617.maciej.rutecki@gmail.com>
On Thu, 10 Jun 2010 22:00:57 +0200
Maciej Rutecki <maciej.rutecki@gmail.com> wrote:
> I created a Bugzilla entry at
> https://bugzilla.kernel.org/show_bug.cgi?id=16178
> for your bug report, please add your address to the CC list in there, thanks!
>
Hmm... It seems a panic in SLUB or SLAB.
Is .config available ?
-Kame
> On niedziela, 6 czerwca 2010 o 17:06:54 Sachin Sant wrote:
> > While executing LTP Controller tests(memcg regression) on
> > a POWER6 box came across this following OOPS.
> >
> > Memory cgroup out of memory: kill process 9139 (memcg_test_1) score 3 or a
> > child Killed process 9139 (memcg_test_1) vsz:3456kB, anon-rss:448kB,
> > file-rss:1088kB Memory cgroup out of memory: kill process 9140
> > (memcg_test_1) score 3 or a child Killed process 9140 (memcg_test_1)
> > vsz:3456kB, anon-rss:448kB, file-rss:1088kB Unable to handle kernel paging
> > request for data at address 0x720072007200720 Faulting instruction
> > address: 0xc00000000015b778
> > Oops: Kernel access of bad area, sig: 11 [#2]
> > SMP NR_CPUS=1024 NUMA pSeries
> > last sysfs file: /sys/devices/system/cpu/cpu1/cache/index1/shared_cpu_map
> > Modules linked in: quota_v2 quota_tree ipv6 fuse loop dm_mod sr_mod cdrom
> > sg sd_mod crc_t10dif ibmvscsic scsi_transport_srp scsi_tgt scsi_mod NIP:
> > c00000000015b778 LR: c00000000015b740 CTR: 0000000000000000
> > REGS: c000000009812ff0 TRAP: 0300 Tainted: G D
> > (2.6.35-rc2-autotest) MSR: 8000000000009032 <EE,ME,IR,DR> CR: 44004424
> > XER: 00000001
> > DAR: 0720072007200720, DSISR: 0000000040000000
> > TASK = c000000005fb1100[9155] 'umount' THREAD: c000000009810000 CPU: 0
> > GPR00: 0000000000000000 c000000009813270 c000000000d3d7a0 0000000000000000
> > GPR04: 0000000000008050 0000000000160000 0000000000000027 c00000000f2c6870
> > GPR08: 00000000000006a5 c000000000b16870 c000000000cf0140 000000000e7b0000
> > GPR12: 0000000024004428 c000000007440000 0000000000008000 fffffffffffff000
> > GPR16: 0000000000000000 c0000000098138f0 000000000000002d 0000000000000027
> > GPR20: 0000000000000000 0000000000000027 0000000000000000 c000000007063138
> > GPR24: ffffffffffffffff 0000000000000000 c00000000019bafc c00000000e02e000
> > GPR28: 0000000000000001 0000000000008050 c000000000ca6b00 0720072007200720
> > NIP [c00000000015b778] .kmem_cache_alloc+0xb0/0x13c
> > LR [c00000000015b740] .kmem_cache_alloc+0x78/0x13c
> > Call Trace:
> > [c000000009813270] [c00000000015b740] .kmem_cache_alloc+0x78/0x13c
> > (unreliable) [c000000009813310] [c00000000019bafc]
> > .alloc_buffer_head+0x2c/0x78 [c000000009813390] [c00000000019c99c]
> > .alloc_page_buffers+0x60/0x114 [c000000009813450] [c00000000019ca78]
> > .create_empty_buffers+0x28/0x140 [c0000000098134e0] [c00000000019f2ec]
> > .__block_prepare_write+0xe4/0x4f0 [c000000009813610] [c00000000019f94c]
> > .block_write_begin_newtrunc+0xa8/0x120 [c0000000098136d0]
> > [c00000000019fea0] .block_write_begin+0x34/0x8c [c000000009813770]
> > [c00000000022b458] .ext3_write_begin+0x13c/0x298 [c000000009813880]
> > [c000000000117500] .generic_file_buffered_write+0x13c/0x320
> > [c0000000098139b0] [c000000000119c80]
> > .__generic_file_aio_write+0x378/0x3dc [c000000009813ab0]
> > [c000000000119d68] .generic_file_aio_write+0x84/0xfc [c000000009813b60]
> > [c00000000016e460] .do_sync_write+0xac/0x10c
> > [c000000009813ce0] [c00000000016f204] .vfs_write+0xd0/0x1dc
> > [c000000009813d80] [c00000000016f418] .SyS_write+0x58/0xa0
> > [c000000009813e30] [c0000000000085b4] syscall_exit+0x0/0x40
> > Instruction dump:
> > 38600000 409e0090 38000000 8b8d0212 980d0212 e96d0040 e93b0000 7ce95a14
> > 7fe9582a 2fbf0000 419e0014 e81b001a <7c1f002a> 7c09592a 4800001c 7f46d378
> > ---[ end trace f24cb0cb5729d2bb ]---
> >
> > And few more of these. Previous snapshot release
> > 2.6.35-rc1-git5(6c5de280b6...) was good.
> >
> > Thanks
> > -Sachin
> >
>
> --
> Maciej Rutecki
> http://www.maciek.unixy.pl
>
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majordomo@kvack.org. For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
>
^ permalink raw reply
* Re: [PATCH 0/2] Replace of_device with platform_device
From: Grant Likely @ 2010-06-11 3:08 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Stephen Rothwell, Michal Simek, microblaze-uclinux, linuxppc-dev,
sparclinux, David Miller
In-Reply-To: <1276218990.1962.81.camel@pasglop>
On Thu, Jun 10, 2010 at 7:16 PM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Thu, 2010-06-10 at 10:46 -0600, Grant Likely wrote:
>>
>> It shouldn't need any fixing because I'm not touching the driver side
>> of the equation (unlike the last breakage where macio_driver had its
>> own copy of the match table which I missed). =A0In fact, there aren't
>> even any logic changes other than dealing with moving some of the
>> structure members in the sparc arch code. =A0If I did miss anything,
>> then it should show up in build testing.
>
> Ok, but I though you were actually replacing occurences of "of_device"
> with "platform_device", and so was wondering why you aren't changing the
> ones in macio. But yes, the #define you did might do the trick as long
> as the resources are still named the same etc...
I will, but it is a big job, so the #define lets me do it in chunks.
I made sure the member names in of_device were identical to
platform_device so that it works as a drop-in.
g.
^ 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