* dtc: Disable semantic checks by default
From: David Gibson @ 2007-10-18 7:22 UTC (permalink / raw)
To: Jon Loeliger; +Cc: linuxppc-dev
At present, dtc makes a lot of semantic checks on the device tree by
default, and will refuse to produce output if they fail. This means
people tend to need -f to force output despite failing semantic checks
rather a lot.
This patch splits the device tree checks into structural checks (no
bad or duplicate names or phandles) and semantic checks (everything
else). By default, only the structural checks are performed, and are
fatal. -f will force output even with structural errors (using this
in -Idts mode would essentially always be a bad idea, but it might be
useful in -Idtb mode for examining a malformed dtb).
Semantic checks are only performed if the new -c command line option
is supplied, and are always warnings only. Semantic checks will never
be performed on a tree with structural errors.
This patch is only a stopgap before implementing proper fine-grained
error/warning handling, but it should at least get rid of the
far-too-frequent need for -f for the time being.
This patch removes the -f from the dtc testcases now that it's no
longer necessary.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Index: dtc/dtc.c
===================================================================
--- dtc.orig/dtc.c 2007-10-18 16:09:18.000000000 +1000
+++ dtc/dtc.c 2007-10-18 17:06:27.000000000 +1000
@@ -112,19 +112,20 @@
char *inform = "dts";
char *outform = "dts";
char *outname = "-";
- int force = 0;
+ int force = 0, check = 0;
char *arg;
int opt;
FILE *inf = NULL;
FILE *outf = NULL;
int outversion = DEFAULT_FDT_VERSION;
int boot_cpuid_phys = 0xfeedbeef;
+ int structure_ok;
quiet = 0;
reservenum = 0;
minsize = 0;
- while ((opt = getopt(argc, argv, "hI:O:o:V:R:S:fqb:v")) != EOF) {
+ while ((opt = getopt(argc, argv, "hI:O:o:V:R:S:fcqb:v")) != EOF) {
switch (opt) {
case 'I':
inform = optarg;
@@ -147,6 +148,9 @@
case 'f':
force = 1;
break;
+ case 'c':
+ check = 1;
+ break;
case 'q':
quiet++;
break;
@@ -189,12 +193,25 @@
if (! bi || ! bi->dt)
die("Couldn't read input tree\n");
- if (! check_device_tree(bi->dt, outversion, boot_cpuid_phys)) {
- if ((force) && (quiet < 3))
- fprintf(stderr, "Input tree has errors, output forced\n");
- if (! force) {
- fprintf(stderr, "Input tree has errors, not writing output (use -f to force output)\n");
+ structure_ok = check_structure(bi->dt);
+ if (!structure_ok) {
+ if (!force) {
+ fprintf(stderr, "ERROR: Input tree has structural errors, aborting (use -f to force output)\n");
exit(1);
+ } else if (quiet < 3) {
+ fprintf(stderr, "Warning: Input tree has structural errors, output forced\n");
+ }
+ }
+
+ fixup_references(bi->dt);
+
+ if (check) {
+ if (!structure_ok) {
+ fprintf(stderr, "Warning: Skipping semantic checks due to structural errors\n");
+ } else {
+ if (!check_semantics(bi->dt, outversion,
+ boot_cpuid_phys))
+ fprintf(stderr, "Warning: Input tree has semantic errors\n");
}
}
Index: dtc/dtc.h
===================================================================
--- dtc.orig/dtc.h 2007-10-18 16:08:50.000000000 +1000
+++ dtc/dtc.h 2007-10-18 16:33:37.000000000 +1000
@@ -188,6 +188,10 @@
void add_property(struct node *node, struct property *prop);
void add_child(struct node *parent, struct node *child);
+int check_structure(struct node *dt);
+void fixup_references(struct node *dt);
+int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys);
+
int check_device_tree(struct node *dt, int outversion, int boot_cpuid_phys);
/* Boot info (tree plus memreserve information */
Index: dtc/livetree.c
===================================================================
--- dtc.orig/livetree.c 2007-10-18 16:06:05.000000000 +1000
+++ dtc/livetree.c 2007-10-18 16:33:41.000000000 +1000
@@ -149,6 +149,18 @@
return list;
}
+struct boot_info *build_boot_info(struct reserve_info *reservelist,
+ struct node *tree)
+{
+ struct boot_info *bi;
+
+ bi = xmalloc(sizeof(*bi));
+ bi->reservelist = reservelist;
+ bi->dt = tree;
+
+ return bi;
+}
+
/*
* Tree accessor functions
*/
@@ -248,13 +260,178 @@
return NULL;
}
+static cell_t get_node_phandle(struct node *root, struct node *node)
+{
+ static cell_t phandle = 1; /* FIXME: ick, static local */
+
+ if ((node->phandle != 0) && (node->phandle != -1))
+ return node->phandle;
+
+ assert(! get_property(node, "linux,phandle"));
+
+ while (get_node_by_phandle(root, phandle))
+ phandle++;
+
+ node->phandle = phandle;
+ add_property(node,
+ build_property("linux,phandle",
+ data_append_cell(empty_data, phandle),
+ NULL));
+
+ return node->phandle;
+}
+
/*
- * Tree checking functions
+ * Structural check functions
*/
#define ERRMSG(...) if (quiet < 2) fprintf(stderr, "ERROR: " __VA_ARGS__)
#define WARNMSG(...) if (quiet < 1) fprintf(stderr, "Warning: " __VA_ARGS__)
+#define DO_ERR(...) do {ERRMSG(__VA_ARGS__); ok = 0; } while (0)
+
+static int check_names(struct node *tree)
+{
+ struct node *child, *child2;
+ struct property *prop, *prop2;
+ int len = strlen(tree->name);
+ int ok = 1;
+
+ if (len == 0 && tree->parent)
+ DO_ERR("Empty, non-root nodename at %s\n", tree->fullpath);
+
+ if (len > MAX_NODENAME_LEN)
+ WARNMSG("Overlength nodename at %s\n", tree->fullpath);
+
+ for_each_property(tree, prop) {
+ /* check for duplicates */
+ /* FIXME: do this more efficiently */
+ for (prop2 = prop->next; prop2; prop2 = prop2->next) {
+ if (streq(prop->name, prop2->name)) {
+ DO_ERR("Duplicate propertyname %s in node %s\n",
+ prop->name, tree->fullpath);
+ }
+ }
+
+ /* check name length */
+ if (strlen(prop->name) > MAX_PROPNAME_LEN)
+ WARNMSG("Property name %s is too long in %s\n",
+ prop->name, tree->fullpath);
+ }
+
+ for_each_child(tree, child) {
+ /* Check for duplicates */
+
+ for (child2 = child->next_sibling;
+ child2;
+ child2 = child2->next_sibling) {
+ if (streq(child->name, child2->name))
+ DO_ERR("Duplicate node name %s\n",
+ child->fullpath);
+ }
+ if (! check_names(child))
+ ok = 0;
+ }
+
+ return ok;
+}
+
+static int check_phandles(struct node *root, struct node *node)
+{
+ struct property *prop;
+ struct node *child, *other;
+ cell_t phandle;
+ int ok = 1;
+
+ prop = get_property(node, "linux,phandle");
+ if (prop) {
+ phandle = propval_cell(prop);
+ if ((phandle == 0) || (phandle == -1)) {
+ DO_ERR("%s has invalid linux,phandle %x\n",
+ node->fullpath, phandle);
+ } else {
+ other = get_node_by_phandle(root, phandle);
+ if (other)
+ DO_ERR("%s has duplicated phandle %x (seen before at %s)\n",
+ node->fullpath, phandle, other->fullpath);
+
+ node->phandle = phandle;
+ }
+ }
+
+ for_each_child(node, child)
+ ok = ok && check_phandles(root, child);
+
+ return 1;
+}
+
+int check_structure(struct node *dt)
+{
+ int ok = 1;
+
+ ok = ok && check_names(dt);
+ ok = ok && check_phandles(dt, dt);
+
+ return ok;
+}
+
+/*
+ * Reference fixup functions
+ */
+
+static void apply_fixup(struct node *root, struct property *prop,
+ struct fixup *f)
+{
+ struct node *refnode;
+ cell_t phandle;
+
+ if (f->ref[0] == '/') {
+ /* Reference to full path */
+ refnode = get_node_by_path(root, f->ref);
+ if (! refnode)
+ die("Reference to non-existent node \"%s\"\n", f->ref);
+ } else {
+ refnode = get_node_by_label(root, f->ref);
+ if (! refnode)
+ die("Reference to non-existent node label \"%s\"\n", f->ref);
+ }
+
+ phandle = get_node_phandle(root, refnode);
+
+ assert(f->offset + sizeof(cell_t) <= prop->val.len);
+
+ *((cell_t *)(prop->val.val + f->offset)) = cpu_to_be32(phandle);
+}
+
+static void fixup_phandles(struct node *root, struct node *node)
+{
+ struct property *prop;
+ struct node *child;
+
+ for_each_property(node, prop) {
+ struct fixup *f = prop->val.refs;
+
+ while (f) {
+ apply_fixup(root, prop, f);
+ prop->val.refs = f->next;
+ fixup_free(f);
+ f = prop->val.refs;
+ }
+ }
+
+ for_each_child(node, child)
+ fixup_phandles(root, child);
+}
+
+void fixup_references(struct node *dt)
+{
+ fixup_phandles(dt, dt);
+}
+
+/*
+ * Semantic check functions
+ */
+
static int must_be_one_cell(struct property *prop, struct node *node)
{
if (prop->val.len != sizeof(cell_t)) {
@@ -315,82 +492,24 @@
{"device_type", must_be_string},
};
-#define DO_ERR(...) do {ERRMSG(__VA_ARGS__); ok = 0; } while (0)
-
static int check_properties(struct node *node)
{
- struct property *prop, *prop2;
+ struct property *prop;
+ struct node *child;
+ int i;
int ok = 1;
- for_each_property(node, prop) {
- int i;
-
- /* check for duplicates */
- /* FIXME: do this more efficiently */
- for (prop2 = prop->next; prop2; prop2 = prop2->next) {
- if (streq(prop->name, prop2->name)) {
- DO_ERR("Duplicate propertyname %s in node %s\n",
- prop->name, node->fullpath);
- }
- }
-
- /* check name length */
- if (strlen(prop->name) > MAX_PROPNAME_LEN)
- WARNMSG("Property name %s is too long in %s\n",
- prop->name, node->fullpath);
-
- /* check this property */
- for (i = 0; i < ARRAY_SIZE(prop_checker_table); i++) {
+ for_each_property(node, prop)
+ for (i = 0; i < ARRAY_SIZE(prop_checker_table); i++)
if (streq(prop->name, prop_checker_table[i].propname))
if (! prop_checker_table[i].check_fn(prop, node)) {
ok = 0;
break;
}
- }
- }
-
- return ok;
-}
-
-static int check_node_name(struct node *node)
-{
- int ok = 1;
- int len = strlen(node->name);
-
- if (len == 0 && node->parent)
- DO_ERR("Empty, non-root nodename at %s\n", node->fullpath);
-
- if (len > MAX_NODENAME_LEN)
- DO_ERR("Overlength nodename at %s\n", node->fullpath);
-
-
- return ok;
-}
-static int check_structure(struct node *tree)
-{
- struct node *child, *child2;
- int ok = 1;
-
- if (! check_node_name(tree))
- ok = 0;
-
- if (! check_properties(tree))
- ok = 0;
-
- for_each_child(tree, child) {
- /* Check for duplicates */
-
- for (child2 = child->next_sibling;
- child2;
- child2 = child2->next_sibling) {
- if (streq(child->name, child2->name))
- DO_ERR("Duplicate node name %s\n",
- child->fullpath);
- }
- if (! check_structure(child))
+ for_each_child(node, child)
+ if (! check_properties(child))
ok = 0;
- }
return ok;
}
@@ -638,115 +757,12 @@
return ok;
}
-static int check_phandles(struct node *root, struct node *node)
+int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys)
{
- struct property *prop;
- struct node *child, *other;
- cell_t phandle;
int ok = 1;
- prop = get_property(node, "linux,phandle");
- if (prop) {
- phandle = propval_cell(prop);
- if ((phandle == 0) || (phandle == -1)) {
- DO_ERR("%s has invalid linux,phandle %x\n",
- node->fullpath, phandle);
- } else {
- other = get_node_by_phandle(root, phandle);
- if (other)
- DO_ERR("%s has duplicated phandle %x (seen before at %s)\n",
- node->fullpath, phandle, other->fullpath);
-
- node->phandle = phandle;
- }
- }
-
- for_each_child(node, child)
- ok = ok && check_phandles(root, child);
-
- return 1;
-}
-
-static cell_t get_node_phandle(struct node *root, struct node *node)
-{
- static cell_t phandle = 1; /* FIXME: ick, static local */
-
- if ((node->phandle != 0) && (node->phandle != -1))
- return node->phandle;
-
- assert(! get_property(node, "linux,phandle"));
-
- while (get_node_by_phandle(root, phandle))
- phandle++;
-
- node->phandle = phandle;
- add_property(node,
- build_property("linux,phandle",
- data_append_cell(empty_data, phandle),
- NULL));
-
- return node->phandle;
-}
-
-static void apply_fixup(struct node *root, struct property *prop,
- struct fixup *f)
-{
- struct node *refnode;
- cell_t phandle;
-
- if (f->ref[0] == '/') {
- /* Reference to full path */
- refnode = get_node_by_path(root, f->ref);
- if (! refnode)
- die("Reference to non-existent node \"%s\"\n", f->ref);
- } else {
- refnode = get_node_by_label(root, f->ref);
- if (! refnode)
- die("Reference to non-existent node label \"%s\"\n", f->ref);
- }
-
- phandle = get_node_phandle(root, refnode);
-
- assert(f->offset + sizeof(cell_t) <= prop->val.len);
-
- *((cell_t *)(prop->val.val + f->offset)) = cpu_to_be32(phandle);
-}
-
-static void fixup_phandles(struct node *root, struct node *node)
-{
- struct property *prop;
- struct node *child;
-
- for_each_property(node, prop) {
- struct fixup *f = prop->val.refs;
-
- while (f) {
- apply_fixup(root, prop, f);
- prop->val.refs = f->next;
- fixup_free(f);
- f = prop->val.refs;
- }
- }
-
- for_each_child(node, child)
- fixup_phandles(root, child);
-}
-
-int check_device_tree(struct node *dt, int outversion, int boot_cpuid_phys)
-{
- int ok = 1;
-
- if (! check_structure(dt))
- return 0;
-
+ ok = ok && check_properties(dt);
ok = ok && check_addr_size_reg(dt, -1, -1);
- ok = ok && check_phandles(dt, dt);
-
- fixup_phandles(dt, dt);
-
- if (! ok)
- return 0;
-
ok = ok && check_root(dt);
ok = ok && check_cpus(dt, outversion, boot_cpuid_phys);
ok = ok && check_memory(dt);
@@ -756,15 +772,3 @@
return 1;
}
-
-struct boot_info *build_boot_info(struct reserve_info *reservelist,
- struct node *tree)
-{
- struct boot_info *bi;
-
- bi = xmalloc(sizeof(*bi));
- bi->reservelist = reservelist;
- bi->dt = tree;
-
- return bi;
-}
Index: dtc/tests/run_tests.sh
===================================================================
--- dtc.orig/tests/run_tests.sh 2007-10-18 16:30:21.000000000 +1000
+++ dtc/tests/run_tests.sh 2007-10-18 16:30:30.000000000 +1000
@@ -101,11 +101,11 @@
}
dtc_tests () {
- run_test dtc.sh -f -I dts -O dtb -o dtc_tree1.test.dtb test_tree1.dts
+ run_test dtc.sh -I dts -O dtb -o dtc_tree1.test.dtb test_tree1.dts
tree1_tests dtc_tree1.test.dtb
tree1_tests_rw dtc_tree1.test.dtb
- run_test dtc.sh -f -I dts -O dtb -o dtc_escapes.test.dtb escapes.dts
+ run_test dtc.sh -I dts -O dtb -o dtc_escapes.test.dtb escapes.dts
run_test string_escapes dtc_escapes.test.dtb
}
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* Re: PPC440EPx GPIO control help
From: Dell Query @ 2007-10-18 2:05 UTC (permalink / raw)
To: David Hawkins, linuxppc-embedded
In-Reply-To: <4716360B.3080502@ovro.caltech.edu>
[-- Attachment #1: Type: text/plain, Size: 725 bytes --]
Hi David,
I'll take a look at the PDF file you sent me.
Thanks,
dell
David Hawkins <dwh@ovro.caltech.edu> wrote: Hi Dell,
If you do decide to look at kernel drivers, Jeff has sent you
code, and I also have a tutorial with example code you are
welcome to look at:
http://www.ovro.caltech.edu/~dwh/correlator/pdf/LNX-723-Hawkins.pdf
http://www.ovro.caltech.edu/~dwh/correlator/software/driver_design.tar.gz
Feel free to ask questions. I recall writing some test driver
code for the 440EP Yosemite board too. I'm just not sure where
I put it ... :)
Cheers,
Dave
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
[-- Attachment #2: Type: text/html, Size: 961 bytes --]
^ permalink raw reply
* Re: [PATCH 2/2] Use of_get_pci_dev_node() in axon_msi.c
From: Stephen Rothwell @ 2007-10-18 5:22 UTC (permalink / raw)
To: Linas Vepstas; +Cc: sparclinux, Paul Mackerras, David S. Miller, linuxppc-dev
In-Reply-To: <20071017230449.GZ4891@austin.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 668 bytes --]
On Wed, 17 Oct 2007 18:04:49 -0500 linas@austin.ibm.com (Linas Vepstas) wrote:
>
> Is this really useful or wise?
Yes, it is. We are *replacing* an interface that does no ref counting
with one that does.
> As a matter of personal taste, I find stuff like this clutters
What has taste got to do with it? And as for cluttering, you can page
out the previous interface and page in the new one. :-)
> I don't much like this style, and I've been known to submit
> patches that remove stuff like this ...
What "style" are you referring to?
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH 5/5] IB/ehca: Enable large page MRs by default
From: Roland Dreier @ 2007-10-18 4:48 UTC (permalink / raw)
To: Joachim Fenkes
Cc: LKML, OF-EWG, LinuxPPC-Dev, Christoph Raisch, OF-General,
Stefan Roscher
In-Reply-To: <200710161731.59688.fenkes@de.ibm.com>
thanks, applied 1-5
^ permalink raw reply
* Re: [PATCH 1/2] [SPARC/64] Consolidate of_register_driver
From: David Miller @ 2007-10-18 4:18 UTC (permalink / raw)
To: sfr; +Cc: sparclinux, linuxppc-dev, wli
In-Reply-To: <20071017134123.cfe10b79.sfr@canb.auug.org.au>
From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Wed, 17 Oct 2007 13:41:23 +1000
> Also of_unregister_driver. These will be shortly also used by the
> PowerPC code.
>
> Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
I'll apply this and push it onward, thanks Stephen!
^ permalink raw reply
* libfdt: Add missing RW_CHECK_HEADER to fdt_del_node()
From: David Gibson @ 2007-10-18 4:17 UTC (permalink / raw)
To: Jon Loeliger; +Cc: linuxppc-dev
fdt_del_node(), unlike most of the rw functions does not check the
fdt's header with RW_CHECK_HEADER. However, it could make a mess of
things if the conditions in RW_CHECK_HEADER aren't met. So, this
patch adds the omitted check.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Index: dtc/libfdt/fdt_rw.c
===================================================================
--- dtc.orig/libfdt/fdt_rw.c 2007-10-16 10:44:53.000000000 +1000
+++ dtc/libfdt/fdt_rw.c 2007-10-18 14:14:47.000000000 +1000
@@ -329,6 +329,8 @@
{
int endoffset;
+ RW_CHECK_HEADER(fdt);
+
endoffset = _fdt_node_end_offset(fdt, nodeoffset);
if (endoffset < 0)
return endoffset;
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* dtc: Make helper macros in trees.S more flexible
From: David Gibson @ 2007-10-18 4:14 UTC (permalink / raw)
To: Jon Loeliger; +Cc: linuxppc-dev
This patch makes the helper macros in trees.S use separate labels for
the end of each dt subblock, rather than using only start labels.
This means that the macros can now be used to create trees with the
subblocks in non-standard orders.
In addition, it adds a bunch of extra ; after lines of asm code in
macros, making them safe to use in nested macros.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Index: dtc/tests/trees.S
===================================================================
--- dtc.orig/tests/trees.S 2007-10-17 10:27:35.000000000 +1000
+++ dtc/tests/trees.S 2007-10-18 14:09:06.000000000 +1000
@@ -5,7 +5,7 @@
.byte ((val) >> 24) & 0xff ; \
.byte ((val) >> 16) & 0xff ; \
.byte ((val) >> 8) & 0xff ; \
- .byte (val) & 0xff
+ .byte (val) & 0xff ;
#define FDTQUAD(val) \
.byte ((val) >> 56) & 0xff ; \
@@ -15,10 +15,10 @@
.byte ((val) >> 24) & 0xff ; \
.byte ((val) >> 16) & 0xff ; \
.byte ((val) >> 8) & 0xff ; \
- .byte (val) & 0xff
+ .byte (val) & 0xff ;
#define TREE_HDR(tree) \
- .balign 4 ; \
+ .balign 8 ; \
.globl _##tree ; \
_##tree: \
tree: \
@@ -30,17 +30,18 @@
FDTLONG(0x11) ; \
FDTLONG(0x10) ; \
FDTLONG(0) ; \
- FDTLONG(tree##_end - tree##_strings) ; \
- FDTLONG(tree##_strings - tree##_struct) ;
+ FDTLONG(tree##_strings_end - tree##_strings) ; \
+ FDTLONG(tree##_struct_end - tree##_struct) ;
#define RSVMAP_ENTRY(addr, len) \
FDTQUAD(addr) ; \
- FDTQUAD(len) ;
+ FDTQUAD(len) ; \
#define EMPTY_RSVMAP(tree) \
.balign 8 ; \
tree##_rsvmap: ; \
- RSVMAP_ENTRY(0, 0)
+ RSVMAP_ENTRY(0, 0) \
+tree##_rsvmap_end: ;
#define PROPHDR(tree, name, len) \
FDTLONG(FDT_PROP) ; \
@@ -50,26 +51,26 @@
#define PROP_INT(tree, name, val) \
PROPHDR(tree, name, 4) \
/* For ease of testing the property values go in native-endian */ \
- .long val
+ .long val ;
#define PROP_STR(tree, name, str) \
PROPHDR(tree, name, 55f - 54f) \
54: \
.string str ; \
55: \
- .balign 4
+ .balign 4 ;
#define BEGIN_NODE(name) \
FDTLONG(FDT_BEGIN_NODE) ; \
.string name ; \
- .balign 4
+ .balign 4 ;
#define END_NODE \
FDTLONG(FDT_END_NODE) ;
#define STRING(tree, name, str) \
-tree##_##name: \
- .string str
+tree##_##name: ; \
+ .string str ;
.data
@@ -80,6 +81,7 @@
RSVMAP_ENTRY(TEST_ADDR_1, TEST_SIZE_1)
RSVMAP_ENTRY(TEST_ADDR_2, TEST_SIZE_2)
RSVMAP_ENTRY(0, 0)
+test_tree1_rsvmap_end:
test_tree1_struct:
BEGIN_NODE("")
@@ -108,13 +110,16 @@
END_NODE
FDTLONG(FDT_END)
+test_tree1_struct_end:
test_tree1_strings:
STRING(test_tree1, compatible, "compatible")
STRING(test_tree1, prop_int, "prop-int")
STRING(test_tree1, prop_str, "prop-str")
+test_tree1_strings_end:
test_tree1_end:
+
TREE_HDR(truncated_property)
EMPTY_RSVMAP(truncated_property)
@@ -122,7 +127,10 @@
BEGIN_NODE("")
PROPHDR(truncated_property, prop_truncated, 4)
/* Oops, no actual property data here */
+truncated_property_struct_end:
truncated_property_strings:
STRING(truncated_property, prop_truncated, "truncated")
+truncated_property_strings_end:
+
truncated_property_end:
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* RE: [PATCH v3 2/9] ipic: add new interrupts introduced by new chip
From: Li Yang-r58472 @ 2007-10-18 4:09 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev, paulus
In-Reply-To: <BB3ACE22-7584-49D9-BEB0-DC355FA25BA1@kernel.crashing.org>
> -----Original Message-----
> From: Kumar Gala [mailto:galak@kernel.crashing.org]=20
> Sent: Wednesday, October 17, 2007 9:46 PM
> To: Li Yang-r58472
> Cc: paulus@samba.org; linuxppc-dev@ozlabs.org
> Subject: Re: [PATCH v3 2/9] ipic: add new interrupts=20
> introduced by new chip
>=20
>=20
> On Oct 12, 2007, at 8:28 AM, Li Yang wrote:
>=20
> > These interrupts are introduced by the latest Freescale SoC such as=20
> > MPC837x. The patch also adds comment to interrupts.
> >
> > Signed-off-by: Li Yang <leoli@freescale.com>
> > ---
> > arch/powerpc/sysdev/ipic.c | 224 +++++++++++++++++++++++++++++++++
> > +----------
> > arch/powerpc/sysdev/ipic.h | 7 +-
> > include/asm-powerpc/ipic.h | 12 ++-
> > 3 files changed, 186 insertions(+), 57 deletions(-)
> >
> > diff --git a/arch/powerpc/sysdev/ipic.c=20
> b/arch/powerpc/sysdev/ipic.c=20
> > index 05a56e5..cd8590d 100644
> > --- a/arch/powerpc/sysdev/ipic.c
> > +++ b/arch/powerpc/sysdev/ipic.c
> > @@ -33,7 +33,31 @@ static struct ipic * primary_ipic; static=20
> > DEFINE_SPINLOCK(ipic_lock);
> >
> > static struct ipic_info ipic_info[] =3D {
> > - [9] =3D {
> > + [1] =3D { /* PEX1 CNT */
>=20
> Remove the comments, they are not correct for all IPIC users=20
> and thus misleading.
We had discussed about this. The reason why I add these comments is
that IPIC register definition in our user manual only reference
interrupts by name rather than numbers. It will greatly enhance the
readability of the code, so that we can check easily if the current code
fits IPIC definition of a specific chip. Without comments the check
will be a disaster. :)
The comments are correct for all the in tree CPUs. It should be kept
up-to-date easily when adding new CPUs.
- Leo
^ permalink raw reply
* [PATCH] gianfar: fix compile warning
From: Grant Likely @ 2007-10-18 3:54 UTC (permalink / raw)
To: Li Yang, Jeff Garzik, linuxppc-dev, netdev
From: Grant Likely <grant.likely@secretlab.ca>
Eliminate an uninitialized variable warning. The code is correct, but
a pointer to the automatic variable 'addr' is passed to dma_alloc_coherent.
Since addr has never been initialized, and the compiler doesn't know
what dma_alloc_coherent will do with it, it complains.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
drivers/net/gianfar.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index cc288d8..c009ab6 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -696,7 +696,7 @@ int startup_gfar(struct net_device *dev)
{
struct txbd8 *txbdp;
struct rxbd8 *rxbdp;
- dma_addr_t addr;
+ dma_addr_t addr = 0;
unsigned long vaddr;
int i;
struct gfar_private *priv = netdev_priv(dev);
^ permalink raw reply related
* RE: [PATCH v3 4/9] add platform support for MPC837x MDS board
From: Li Yang-r58472 @ 2007-10-18 3:51 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev, paulus
In-Reply-To: <F5AD4702-2832-4408-81DB-0E78B1883D76@kernel.crashing.org>
> -----Original Message-----
> From: Kumar Gala [mailto:galak@kernel.crashing.org]=20
> Sent: Wednesday, October 17, 2007 9:47 PM
> To: Li Yang-r58472
> Cc: paulus@samba.org; linuxppc-dev@ozlabs.org
> Subject: Re: [PATCH v3 4/9] add platform support for MPC837x MDS board
>=20
>=20
> On Oct 12, 2007, at 8:28 AM, Li Yang wrote:
>=20
> > The MPC837x MDS is a new member of Freescale MDS reference system.
> >
> > Signed-off-by: Li Yang <leoli@freescale.com>
> > ---
> > arch/powerpc/platforms/83xx/Kconfig | 12 ++++
> > arch/powerpc/platforms/83xx/Makefile | 1 +
> > arch/powerpc/platforms/83xx/mpc837x_mds.c | 103 ++++++++++++++++++
> > +++++++++++
> > 3 files changed, 116 insertions(+), 0 deletions(-) create mode=20
> > 100644 arch/powerpc/platforms/83xx/mpc837x_mds.c
> >
> > diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/=20
> > platforms/83xx/Kconfig index ec305f1..0c61e7a 100644
> > --- a/arch/powerpc/platforms/83xx/Kconfig
> > +++ b/arch/powerpc/platforms/83xx/Kconfig
> > @@ -50,6 +50,11 @@ config MPC836x_MDS
> > help
> > This option enables support for the MPC836x MDS=20
> Processor Board.
> >
> > +config MPC837x_MDS
> > + bool "Freescale MPC837x MDS"
> > + select DEFAULT_UIMAGE
> > + help
> > + This option enables support for the MPC837x MDS=20
> Processor Board.
> > endchoice
> >
> > config PPC_MPC831x
> > @@ -75,3 +80,10 @@ config PPC_MPC836x
> > select PPC_UDBG_16550
> > select PPC_INDIRECT_PCI
> > default y if MPC836x_MDS
> > +
> > +config PPC_MPC837x
> > + bool
> > + select PPC_UDBG_16550
> > + select PPC_INDIRECT_PCI
> > + select FSL_SERDES
> > + default y if MPC837x_MDS
>=20
> Do we really need this Kconfig option for anything?
The chip series can be used on other boards. This option is a container
for CPU related selects and can be reused by other boards.
- Leo
^ permalink raw reply
* RE: [PATCH v4 9/9] add MPC837x MDS board default device tree
From: Li Yang-r58472 @ 2007-10-18 3:36 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev, paulus
In-Reply-To: <3E4B0158-F1E9-49A7-A8AF-AB444C222E4A@kernel.crashing.org>
> -----Original Message-----
> From: Kumar Gala [mailto:galak@kernel.crashing.org]=20
> Sent: Wednesday, October 17, 2007 9:55 PM
> To: Li Yang-r58472
> Cc: paulus@samba.org; linuxppc-dev@ozlabs.org
> Subject: Re: [PATCH v4 9/9] add MPC837x MDS board default device tree
>=20
>=20
> On Oct 15, 2007, at 9:56 AM, Li Yang wrote:
>=20
> > Signed-off-by: Li Yang <leoli@freescale.com>
> > ---
> > arch/powerpc/boot/dts/mpc8377_mds.dts | 281 ++++++++++++++++++++++
> > +++++++++
> > arch/powerpc/boot/dts/mpc8378_mds.dts | 263 ++++++++++++++++++++++
> > +++++++
> > arch/powerpc/boot/dts/mpc8379_mds.dts | 299 ++++++++++++++++++++++
> > +++++++++++
> > 3 files changed, 843 insertions(+), 0 deletions(-) create mode=20
> > 100644 arch/powerpc/boot/dts/mpc8377_mds.dts
> > create mode 100644 arch/powerpc/boot/dts/mpc8378_mds.dts
> > create mode 100644 arch/powerpc/boot/dts/mpc8379_mds.dts
{snip}
> > + };
> > + };
> > +
> > + memory {
> > + device_type =3D "memory";
> > + reg =3D <00000000 20000000>; // 512MB at 0
> > + };
> > +
> > + soc837x@e0000000 {
>=20
> make this just 'soc@e0000000'
>=20
The current u-boot support uses soc837x. U-boot should be changed first
for soc@e0000000 to work.
- Leo
^ permalink raw reply
* Re: PPC440EPx GPIO control help
From: Jeff Mock @ 2007-10-18 3:22 UTC (permalink / raw)
To: Dell Query; +Cc: linuxppc-embedded
In-Reply-To: <65478.31425.qm@web45611.mail.sp1.yahoo.com>
Oh no, it's not necessary to use /proc, pdev-lcd was my first device
driver. I wanted to try out all of the different features and it was
fun to add a /proc interface. It could just as easily have a read
interface or an ioctl() or whatever.
I think LDD3 is fantastic, stick with it and go slowly. Start out by
writing little test drivers on your desktop machine where it's easy to
debug. LDD3 really got me over the hump of writing device drivers.
jeff
Dell Query wrote:
> Hi Jeff,
>
> I read the device drivers part of the LDD3, it's really difficult as
> I
expected. Thanks for the sample codes. I'll develop my own driver basing
from your samples. Regarding reading the status of the LED, is it really
necessary to use proc?
> Regards,
> dell
>
> Jeff Mock <jeff@mock.com> wrote:
> David Hawkins wrote:
>>> I have a PPC440EPx Sequoia Evaluation board that runs on Linux 2.6.21.
>>> What I would want to do is to control (write and read values to) its
>>> GPIO. Perhaps similar to Turbo C's outputb(0x378,0x01) to write and
>>> inportb(0x378) to read. I read the PPC440EPx manual but I find it
>>> difficult to understand.
>>>
>>> Could anyone show me any tutorial or some sample codes?
>> I copied the code below from some test code I wrote for a TS7300
>> board (uses an ARM EP9302 processor). However, since its user-space
>> code it should work fine.
>>
>
> I might be a little out of date, but I think you must write your own
> driver to wiggle the GPIO pins on a 440 processor. I just finished a
> project using a 440GX with a 2.6.15 kernel (we froze the code about 8
> months ago).
>
> The 440 powerPC core is a 32-bit processor with 36-bit physical
> addresses. The physical address for the GPIO pins is someplace above
> 4GB. An mmap() of /dev/mem only lets you map the lower 4GB of the
> address space, as a result you can't write a user space program on the
> 440 to wiggle the GPIO pins. (This was true with 2.6.15, I can't speak
> for later kernels).
>
> This tossed me into writing device drivers, which turned out to be not
> nearly as scary as I imagined. The Linux Device Drivers book is fabulous:
>
> http://lwn.net/Kernel/LDD3/
>
> Here is a driver for the 440GX that controls an LED on one of the GPIO
> pins you can use as an example. The device /dev/pdev-led has a
> read/write interface so you can do something like this:
>
> # echo "1" > /dev/pdev-led # turn on LED
> # echo "0" > /dev/pdev-led # turn off LED
>
> It also has a /proc interface so you can cat /proc/pdev-led to read the
> status of the LED. There are several other drivers there that probably
> won't be interesting, but pdev-led.c is probably a good starting point:
>
> http://www.mock.com/wsvn/listing.php?repname=mock.pdev&path=/trunk/sw/driver/
>
> jeff
>
>
>
>
> __________________________________________________
> Do You Yahoo!?
> Tired of spam? Yahoo! Mail has the best spam protection around
> http://mail.yahoo.com
^ permalink raw reply
* what's inside INT_FRAME_SIZE?
From: Wang, Baojun @ 2007-10-18 2:54 UTC (permalink / raw)
To: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 738 bytes --]
hi,
I need setup a stack frame manually under powerpc, sounds like I need
prepare at least for size INT_FRAME_SIZE (192 bytes through asm-offset.h),
I know the bottom 176 bytes are for struct pt_regs, how about the upper 16
(STACK_FRAME_OVERHEAD) bytes? what's inside this 16 bytes? Could you please
give me some hints? Thanks very much!
Regards,
Wang
--
Wang, Baojun Lanzhou University
Distributed & Embedded System Lab http://dslab.lzu.edu.cn
School of Information Science and Engeneering wangbj@lzu.edu.cn
Tianshui South Road 222. Lanzhou 730000 .P.R.China
Tel:+86-931-8912025 Fax:+86-931-8912022
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH] synchronize_irq needs a barrier
From: Benjamin Herrenschmidt @ 2007-10-18 2:57 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linuxppc-dev list, akpm, Linux Kernel list
In-Reply-To: <1192675254.12879.29.camel@pasglop>
>
> In general, I tend to think that for this function to make any sense
> (that is, to synchronize anything at all), it needs a barrier or you are
> just making a decision based on a totally random value of desc->status
> since it can have been re-ordered, speculatively loaded, pre-fetched,
> whatever'ed... :-).
Take a real life example:
drivers/message/fusion/mptbase.c
/* Disable interrupts! */
CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
ioc->active = 0;
synchronize_irq(pdev->irq);
And we aren't in a spinlock here.
That's just a random example grepped.... I think I see a few more. Then,
some drivers like tg3 actually do an smp_mb() before calling
synchronize_irq(). But then, some don't.
I think trying to have all drivers be correct here is asking for
trouble, we'd rather have synchronize_irq() be uber-safe. It's not like
it was used in hot path anyway.
Ben.
^ permalink raw reply
* RE: [PATCH v3 3/9] add Freescale SerDes PHY support
From: Li Yang-r58472 @ 2007-10-18 2:46 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev, paulus
In-Reply-To: <7B7F41BB-05FB-4BFD-B4C6-ADDE1E2D76E3@kernel.crashing.org>
> -----Original Message-----
> From: Kumar Gala [mailto:galak@kernel.crashing.org]=20
> Sent: Wednesday, October 17, 2007 10:13 PM
> To: Li Yang-r58472
> Cc: paulus@samba.org; linuxppc-dev@ozlabs.org
> Subject: Re: [PATCH v3 3/9] add Freescale SerDes PHY support
>=20
{snip}
This patch has been superseded by v4. And the problems have already
been addressed. Thanks.
- Leo
^ permalink raw reply
* Re: [PATCH] synchronize_irq needs a barrier
From: Benjamin Herrenschmidt @ 2007-10-18 2:40 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linuxppc-dev list, akpm, Linux Kernel list
In-Reply-To: <alpine.LFD.0.999.0710171906150.26902@woody.linux-foundation.org>
On Wed, 2007-10-17 at 19:12 -0700, Linus Torvalds wrote:
>
> So, what exactly does it protect against? At a minimum, this needs a
> comment in the changelog, and probably preferably in the source code too.
I replied to Andrew, but I agree, it's worth a comment, I'll add one.
> The thing is, synchronize_irq() can only protect against interrupts that
> are *already*running* on another CPU, and the caller must have made sure
> that no new interrupts are coming in (or at least that whatever new
> interrupts that come in will not pick up a certain piece of data).
>
> So I can imagine that the smb_mb() is there so that the caller - who has
> cleared some list or done something like that - will have any preceding
> writes that it did be serialized with actually checking the old state of
> "desc->status".
Yes.
> Fair enough - I can see that a smp_mb() is useful. But I think it needs
> documenting as such, and preferably with an example of how this actually
> happened in the first place (do you have one?)
One could argue that it's the caller that should do the mb() but that
would really be asking for trouble. Since most usage scenario require
it, and it's not a hot path, I prefer having it here.
Note that some kind of read barrier or compiler barrier should be needed
regardless, or we are just not sync'ing with anything at all (we may
have loaded the value ages ago and thus operate on a totally stale
value). I prefer a full barrier to also ensure all previous stores are
pushed out.
> The synchronize_irq() users that are really fundamental (ie the irq
> datastructures themselves) all should use the irq descriptor spinlock, and
> should *not* be needing any of this, since they would have serialized with
> whoever actually set the IRQ_INPROGRESS bit in the first place.
That isn't always the case. You can have very efficient lock-less fast
path and use synchronize_irq as a kind of RCU-like way to have the slow
path do the right thing.
> So in *that* sense, I think the memory barrier is useless, and I can't
> make up my mind whether it's good or bad. Which is why I'd really like to
> have an example scenario spelled out where it makes a difference..
Well, typically, I can clear a pointer and want to make sure my IRQ
handler isn't using it anymore before freeing the memory. Or set a "HW
is off" flag. Having spinlocks all over isn't always the best approach
on things that are really hot path, it's fair enough to use lockless
approaches like that by moving the burden to the slow path that does
synchronize_irq.
In general, I tend to think that for this function to make any sense
(that is, to synchronize anything at all), it needs a barrier or you are
just making a decision based on a totally random value of desc->status
since it can have been re-ordered, speculatively loaded, pre-fetched,
whatever'ed... :-).
Want a respin with a comment ?
Ben.
^ permalink raw reply
* [PATCH] bootwrapper: Allow wrapper script to execute verbosely
From: Grant Likely @ 2007-10-18 2:22 UTC (permalink / raw)
To: paulus, linuxppc-dev, David Gibson
From: Grant Likely <grant.likely@secretlab.ca>
Allow wrapper script to print verbose progress when the V is set in the
environment.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
arch/powerpc/boot/wrapper | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index 39b27e5..347639c 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -21,6 +21,11 @@
# (default ./arch/powerpc/boot)
# -W dir specify working directory for temporary files (default .)
+# Allow for verbose output
+if [ "$V" = 1 ]; then
+ set -x
+fi
+
# defaults
kernel=
ofile=zImage
^ permalink raw reply related
* Re: aty128fb PCI card on ppc 405ep taihu board
From: 王重 @ 2007-10-18 2:19 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <mailman.3.1192500005.32221.linuxppc-embedded@ozlabs.org>
[-- Attachment #1: Type: text/plain, Size: 1143 bytes --]
Thanks Bill and thanks Wolfgang! VGA BIOS is the problem. I use scitechsoft
videoboot to initialize the card. Videoboot is based on scitechsoft x86emu
which could run x86 code on other platforms. Now I successfully initialized
the card and get the framebuffer information. But the monitor still gets NO
SIGNAL through the card.
Serial console shows framebuffer is enabled:
videoboot: Booting PCI video card bus 0, function 0, device 6
aty128fb: Found Intel x86 BIOS ROM Image
aty128fb: Rage128 BIOS located
aty128fb: Rage128 RK PCI [chip rev 0x2] 32M 64-bit SDR SGRAM (2:1)
fb0: ATY Rage128 frame buffer device on Rage128 RK PCI
Some information I get from framebuffer:
id = ATY Rage128
depth = 16
smemlen = 33554432
line_length = 0
FB_TYPE_ = 0
type_aux = 0
FB_VISUAL_ = 3
xpanstep = 8
ypanstep = 1
ywrapstep = 0
mmio_start = bbffc0000d
mmio_len = 8192
accel = 32
xres = 640
yres = 480
xres_virtul = 640
yres_virtul = 480
xoffset = 0
yoffset = 0
bits_per_pixel = 16
[-- Attachment #2: Type: text/html, Size: 7895 bytes --]
^ permalink raw reply
* Re: [PATCH] synchronize_irq needs a barrier
From: Linus Torvalds @ 2007-10-18 2:12 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list, akpm, Linux Kernel list
In-Reply-To: <1192670742.12879.5.camel@pasglop>
On Thu, 18 Oct 2007, Benjamin Herrenschmidt wrote:
>
> + smp_mb();
> while (desc->status & IRQ_INPROGRESS)
> cpu_relax();
So, what exactly does it protect against? At a minimum, this needs a
comment in the changelog, and probably preferably in the source code too.
The thing is, synchronize_irq() can only protect against interrupts that
are *already*running* on another CPU, and the caller must have made sure
that no new interrupts are coming in (or at least that whatever new
interrupts that come in will not pick up a certain piece of data).
So I can imagine that the smb_mb() is there so that the caller - who has
cleared some list or done something like that - will have any preceding
writes that it did be serialized with actually checking the old state of
"desc->status".
Fair enough - I can see that a smp_mb() is useful. But I think it needs
documenting as such, and preferably with an example of how this actually
happened in the first place (do you have one?)
The synchronize_irq() users that are really fundamental (ie the irq
datastructures themselves) all should use the irq descriptor spinlock, and
should *not* be needing any of this, since they would have serialized with
whoever actually set the IRQ_INPROGRESS bit in the first place.
So in *that* sense, I think the memory barrier is useless, and I can't
make up my mind whether it's good or bad. Which is why I'd really like to
have an example scenario spelled out where it makes a difference..
Ok?
Linus
^ permalink raw reply
* libfdt: Make fdt_string() return a const pointer
From: David Gibson @ 2007-10-18 2:10 UTC (permalink / raw)
To: Jon Loeliger; +Cc: linuxppc-dev
Currently, fdt_string() returns a (non-const) char *, despite taking a
const void *fdt. This is inconsistent with all the other read-only
functions which all return const pointers into the blob.
This patch fixes that.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Index: dtc/libfdt/fdt_ro.c
===================================================================
--- dtc.orig/libfdt/fdt_ro.c 2007-10-17 17:35:49.000000000 +1000
+++ dtc/libfdt/fdt_ro.c 2007-10-17 17:35:50.000000000 +1000
@@ -82,7 +82,7 @@ static int nodename_eq(const void *fdt,
return 0;
}
-char *fdt_string(const void *fdt, int stroffset)
+const char *fdt_string(const void *fdt, int stroffset)
{
return (char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
}
Index: dtc/libfdt/libfdt.h
===================================================================
--- dtc.orig/libfdt/libfdt.h 2007-10-17 17:35:35.000000000 +1000
+++ dtc/libfdt/libfdt.h 2007-10-17 17:35:36.000000000 +1000
@@ -110,7 +110,7 @@ static inline void *fdt_offset_ptr_w(voi
int fdt_move(const void *fdt, void *buf, int bufsize);
/* Read-only functions */
-char *fdt_string(const void *fdt, int stroffset);
+const char *fdt_string(const void *fdt, int stroffset);
int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
int fdt_num_mem_rsv(const void *fdt);
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* Re: PPC440EPx GPIO control help
From: Dell Query @ 2007-10-18 2:00 UTC (permalink / raw)
To: Jeff Mock; +Cc: linuxppc-embedded
In-Reply-To: <4715A9D9.6090308@mock.com>
[-- Attachment #1: Type: text/plain, Size: 2408 bytes --]
Hi Jeff,
I read the device drivers part of the LDD3, it's really difficult as I expected. Thanks for the sample codes. I'll develop my own driver basing from your samples. Regarding reading the status of the LED, is it really necessary to use proc?
Regards,
dell
Jeff Mock <jeff@mock.com> wrote:
David Hawkins wrote:
>> I have a PPC440EPx Sequoia Evaluation board that runs on Linux 2.6.21.
>> What I would want to do is to control (write and read values to) its
>> GPIO. Perhaps similar to Turbo C's outputb(0x378,0x01) to write and
>> inportb(0x378) to read. I read the PPC440EPx manual but I find it
>> difficult to understand.
>>
>> Could anyone show me any tutorial or some sample codes?
>
> I copied the code below from some test code I wrote for a TS7300
> board (uses an ARM EP9302 processor). However, since its user-space
> code it should work fine.
>
I might be a little out of date, but I think you must write your own
driver to wiggle the GPIO pins on a 440 processor. I just finished a
project using a 440GX with a 2.6.15 kernel (we froze the code about 8
months ago).
The 440 powerPC core is a 32-bit processor with 36-bit physical
addresses. The physical address for the GPIO pins is someplace above
4GB. An mmap() of /dev/mem only lets you map the lower 4GB of the
address space, as a result you can't write a user space program on the
440 to wiggle the GPIO pins. (This was true with 2.6.15, I can't speak
for later kernels).
This tossed me into writing device drivers, which turned out to be not
nearly as scary as I imagined. The Linux Device Drivers book is fabulous:
http://lwn.net/Kernel/LDD3/
Here is a driver for the 440GX that controls an LED on one of the GPIO
pins you can use as an example. The device /dev/pdev-led has a
read/write interface so you can do something like this:
# echo "1" > /dev/pdev-led # turn on LED
# echo "0" > /dev/pdev-led # turn off LED
It also has a /proc interface so you can cat /proc/pdev-led to read the
status of the LED. There are several other drivers there that probably
won't be interesting, but pdev-led.c is probably a good starting point:
http://www.mock.com/wsvn/listing.php?repname=mock.pdev&path=/trunk/sw/driver/
jeff
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
[-- Attachment #2: Type: text/html, Size: 2806 bytes --]
^ permalink raw reply
* Re: [PATCH] synchronize_irq needs a barrier
From: Benjamin Herrenschmidt @ 2007-10-18 1:55 UTC (permalink / raw)
To: Andrew Morton; +Cc: linuxppc-dev, torvalds, linux-kernel
In-Reply-To: <20071017184512.a1c647b2.akpm@linux-foundation.org>
> > Index: linux-work/kernel/irq/manage.c
> > ===================================================================
> > --- linux-work.orig/kernel/irq/manage.c 2007-10-18 11:22:16.000000000 +1000
> > +++ linux-work/kernel/irq/manage.c 2007-10-18 11:22:20.000000000 +1000
> > @@ -33,6 +33,7 @@ void synchronize_irq(unsigned int irq)
> > if (irq >= NR_IRQS)
> > return;
> >
> > + smp_mb();
> > while (desc->status & IRQ_INPROGRESS)
> > cpu_relax();
> > }
>
> Anyone reading this code is going to ask "wtf is that for". It needs a
> comment telling them.
>
>
> mb() is the new lock_kernel(). Sigh.
Ugh ?
That sounds fairly obvious to me :-) we are reading a value, that is
totally unordered, nothing to do about lock kernel or whatever, if we
want the above statement to make any sense in any kind of usage
scenario, it needs to be ordered vs. what happens before.
For example, take a construct like:
device->my_hw_is_off = 1;
synchronize_irq();
turn_off_hardware();
That basically makes sure the irq either sees device->my_hw_is_off
being set to 1, or if an irq handler is already in progress and hasn't
seen it, we wait for it to complete.
(You can replace "hw_is_off" with anything that we want to set and make
sure the IRQ handler sees it before proceeding. It could be clearing a
pointer to something and make sure the irq sees it before freeing the
data, etc...).
I think pretty much any use of synchronize_irq() I can imagine needs
such kind of ordering... or it simply doesn't synchronize anything :-)
Cheers,
Ben.
^ permalink raw reply
* Re: 2.6.23-mm1 - build failure with advansys
From: Matthew Wilcox @ 2007-10-18 1:48 UTC (permalink / raw)
To: Paul Mackerras
Cc: Matthew Wilcox, linuxppc-dev, Andrew Morton, linux-kernel,
Kamalesh Babulal
In-Reply-To: <18198.41946.697397.255427@cargo.ozlabs.ibm.com>
On Thu, Oct 18, 2007 at 10:07:54AM +1000, Paul Mackerras wrote:
> The correct fix is to make advansys depend on CONFIG_VIRT_TO_BUS, or
> alternatively fix advansys.c properly by making it use the interfaces
> described in Documentation/DMA-mapping.txt (or the equivalent scsi
> helpers).
If you look at the git logs, you'll notice there's some progress towards
this. It's already the case for the narrow boards. I have a patch to
rip it all out for the wide boards, but there's clearly a bug because it
crashes my parisc machine. Works fine on x86 though. I can't work on
it this week because I'm travelling and the parisc machine with remote
power died on me last week.
I think I already suggested a temporary CONFIG_VIRT_TO_BUS dependency to
akpm last week.
--
Intel are signing my paycheques ... these opinions are still mine
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours. We can't possibly take such
a retrograde step."
^ permalink raw reply
* Re: [PATCH] synchronize_irq needs a barrier
From: Andrew Morton @ 2007-10-18 1:45 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev, torvalds, linux-kernel
In-Reply-To: <1192670742.12879.5.camel@pasglop>
On Thu, 18 Oct 2007 11:25:42 +1000
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> synchronize_irq needs at the very least a compiler barrier and a
> read barrier on SMP,
Why?
> but there are enough cases around where a
> write barrier is also needed and it's not a hot path so I prefer
> using a full smp_mb() here.
>
> It will degrade to a compiler barrier on !SMP.
>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
>
> Index: linux-work/kernel/irq/manage.c
> ===================================================================
> --- linux-work.orig/kernel/irq/manage.c 2007-10-18 11:22:16.000000000 +1000
> +++ linux-work/kernel/irq/manage.c 2007-10-18 11:22:20.000000000 +1000
> @@ -33,6 +33,7 @@ void synchronize_irq(unsigned int irq)
> if (irq >= NR_IRQS)
> return;
>
> + smp_mb();
> while (desc->status & IRQ_INPROGRESS)
> cpu_relax();
> }
Anyone reading this code is going to ask "wtf is that for". It needs a
comment telling them.
mb() is the new lock_kernel(). Sigh.
^ permalink raw reply
* Re: [PATCH 2/2] Use of_get_pci_dev_node() in axon_msi.c
From: Michael Ellerman @ 2007-10-18 1:30 UTC (permalink / raw)
To: benh; +Cc: sparclinux, sfr, paulus, David Miller, linuxppc-dev
In-Reply-To: <1192620990.11899.168.camel@pasglop>
[-- Attachment #1: Type: text/plain, Size: 1497 bytes --]
On Wed, 2007-10-17 at 21:36 +1000, Benjamin Herrenschmidt wrote:
> > I find it ironic that you add of_get_pci_dev_node() as a function
> > which gets the node and grabs a reference to it, and then the very
> > first usage you make of it doesn't drop the reference at all.
> >
> > That reference grabbing aspect of the new interface is obviously very
> > useful! :-)
> >
> > Kidding aside (I realize that in this case probably the driver never
> > unregisters and therefore the reference never needs to be released)
> > it's really much nicer to add facilities when you have patches in hand
> > that actually use them.
>
> I think in this case, it's mostly a matter of consistency... pretty much
> everything that returns a device_node grabs a reference... except
> pci_device_to_OF_node :-)
Yeah, it's a matter of the API being error-prone in that most routines
take a reference for you, but this one doesn't.
> I think Michael is trying to address that, and axon-msi happens to be
> something he wrote so a good candidate for an initial conversion :-)
Yep, I wanted at least one user in tree with the patch. I plan to
convert other pci_device_to_OF_node() users to use the refcounted
version over time.
cheers
--
Michael Ellerman
OzLabs, IBM Australia Development Lab
wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)
We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ 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