* Re: [PATCH 1/2] USB: Rework OHCI PPC OF for new bindings
From: tnt @ 2007-11-01 11:19 UTC (permalink / raw)
To: Matt Sealey; +Cc: linuxppc-dev, linux-usb-devel
In-Reply-To: <471FC191.6020704@genesi-usa.com>
> Valentine Barshak wrote:
>> Rework ohci-ppc-of driver to use big-endian property instead of
>> ohci-be/ohci-le compatible strings. Also remove unnecessary
>> user-selectable USB_OHCI_HCD_PPC_OF_LE/BE stuff, because
>> USB_OHCI_BIG_ENDIAN_DESC/MMIO should always be enabled for ppc
>> and USB_OHCI_LITTLE_ENDIAN is selected for USB_OHCI_HCD_PCI by default.
I don't find those options useless. If you think the defauts are not the
best change them but I find these options relevant. You don't always want
the support for BE on PPC ... if the only controller you have is pci ...
or if you're on a soc that use little endian ...
> Can we just make sure real quickly that the changing of compatibles
> doesn't break existing, not-easily-flashable firmwares?
I tend to agree with Matt here.
Do we really need to stop supporting the old values right now ?
IMHO, Changing to the usb-ohci with a property sounds fine to me if you
really want to but don't drop support for the old values. They are not
"bad". Change the dts to reflect the fact that the new "way" is preferred
and a comment somewhere in the code and that should be fine.
Sylvain
^ permalink raw reply
* [PATCH] 2.6.24-rc1-git9 - Missing include file in kallsyms.h
From: Kamalesh Babulal @ 2007-11-01 8:35 UTC (permalink / raw)
To: linux-kernel; +Cc: linuxppc-dev, akpm, rusty, torvalds
The Build with randconfig fails with following error with the
2.6.24-rc4-git9
include/linux/kallsyms.h:56: error: ‘NULL’ undeclared (first use in this
function)
include/linux/kallsyms.h:56: error: (Each undeclared identifier is
reported only once
include/linux/kallsyms.h:56: error: for each function it appears in.)
make[2]: *** [arch/powerpc/platforms/cell/spu_callbacks.o] Error 1
make[1]: *** [arch/powerpc/platforms/cell] Error 2
make: *** [arch/powerpc/platforms] Error 2
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
--
diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
index f73de6f..82de2fb 100644
--- a/include/linux/kallsyms.h
+++ b/include/linux/kallsyms.h
@@ -6,6 +6,7 @@
#define _LINUX_KALLSYMS_H
#include <linux/errno.h>
+#include <linux/stddef.h>
#define KSYM_NAME_LEN 128
#define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s]") + (KSYM_NAME_LEN - 1) + \
--
Thanks & Regards,
Kamalesh Babulal,
Linux Technology Center,
IBM, ISTL.
^ permalink raw reply related
* Re: [PATCH] ucc_geth: add support for netpoll
From: Anton Vorontsov @ 2007-11-01 10:05 UTC (permalink / raw)
To: Li Yang-r58472; +Cc: netdev, linux-kernel, linuxppc-dev
In-Reply-To: <989B956029373F45A0B8AF0297081890019B642A@zch01exm26.fsl.freescale.net>
On Thu, Nov 01, 2007 at 10:33:24AM +0800, Li Yang-r58472 wrote:
> > -----Original Message-----
> > From: Anton Vorontsov [mailto:cbou@mail.ru]
> > Sent: Thursday, November 01, 2007 5:59 AM
> > To: Li Yang-r58472
> > Cc: netdev@vger.kernel.org; linux-kernel@vger.kernel.org;
> > linuxppc-dev@ozlabs.org
> > Subject: Re: [PATCH] ucc_geth: add support for netpoll
> >
> > On Mon, Oct 29, 2007 at 03:17:44PM +0300, Anton Vorontsov wrote:
> > [...]
> > > > Oops. The original patch happened to hit the Junk mail box. :(
> > >
> > > That one as well? http://lkml.org/lkml/2007/10/11/128
> > >
> > > > I think
> > > > the patch is good to merge after the cosmetic change. I
> > can do it
> > > > in next pull request to Jeff.
> > >
> > > Ok, great. Thanks.
> >
> > I'm wondering if you missed that email again. Maybe your mail
> > client/server doing weird things with emails from @ru.mvista.com?
>
> No. I have explicitly add you to the whitelist. :)
Hehe, thanks. ;-)
> Please be patient,
> isn't this patch a new feature which can only be integrated in the merge
> window?
Sure it is. I didn't mean to "hurry up" you, of course not.
Just wondered if you've solved issues with getting my emails. Such
wonders are quite normal if there was a precedent lately. ;-)
Sorry for troubling you,
--
Anton Vorontsov
email: cbou@mail.ru
backup email: ya-cbou@yandex.ru
irc://irc.freenode.net/bd2
^ permalink raw reply
* Re: [0/2] Embed a copy of dtc in the kernel source
From: Kumar Gala @ 2007-11-01 6:54 UTC (permalink / raw)
To: David Gibson; +Cc: linuxppc-dev
In-Reply-To: <20071031044953.GG7772@localhost.localdomain>
On Oct 30, 2007, at 11:49 PM, David Gibson wrote:
> On Tue, Oct 30, 2007 at 11:37:15PM -0500, Kumar Gala wrote:
>>
>> On Oct 30, 2007, at 10:24 PM, David Gibson wrote:
>>
>>> These two patches are a respin of my previous patch to merge a
>>> copy of
>>> dtc into the kernel tree, so that kernel builds no longer depend
>>> on an
>>> externally installed copy of dtc.
>>>
>>> This respin embeds a newer revision of dtc, and incorporates Sam
>>> Ravnborg's preferred approach to Makefile integration. Also,
>>> since so
>>> many people whinged about it last time, I've split the patch into
>>> two
>>> parts, the first is the too-large-for-the-list patch just verbatim
>>> adding files and the second has the changes to existing kernel files
>>> to build and use the embedded code.
>>
>> What about doing part of this via git-submodule?
>
> Uh.. where do I find out what that does? My version of git (Ubuntu
> gutsy) doesn't seem to know anything about it...
Take a look at:
http://www.kernel.org/pub/software/scm/git/docs/git-submodule.html
- k
^ permalink raw reply
* dtc: Move tree checking code to checks.c
From: David Gibson @ 2007-11-01 5:49 UTC (permalink / raw)
To: Jon Loeliger; +Cc: linuxppc-dev
This patch moves the dtc code for checking the device tree its
processing into a new checks.c. The tree accessor functions from
livetree.c which the checks use are exported and added to dtc.h.
Another small step towards a flexible checking architecture.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Index: dtc/checks.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ dtc/checks.c 2007-11-01 16:45:01.000000000 +1100
@@ -0,0 +1,460 @@
+/*
+ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2007.
+ *
+ *
+ * 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 "dtc.h"
+
+/*
+ * 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;
+}
+
+/*
+ * Semantic check functions
+ */
+
+static int must_be_one_cell(struct property *prop, struct node *node)
+{
+ if (prop->val.len != sizeof(cell_t)) {
+ ERRMSG("\"%s\" property in %s has the wrong length (should be 1 cell)\n",
+ prop->name, node->fullpath);
+ return 0;
+ }
+
+ return 1;
+}
+
+static int must_be_cells(struct property *prop, struct node *node)
+{
+ if ((prop->val.len % sizeof(cell_t)) != 0) {
+ ERRMSG("\"%s\" property in %s is not a multiple of cell size\n",
+ prop->name, node->fullpath);
+ return 0;
+ }
+
+ return 1;
+}
+
+static int must_be_string(struct property *prop, struct node *node)
+{
+ if (! data_is_one_string(prop->val)) {
+ ERRMSG("\"%s\" property in %s is not a string\n",
+ prop->name, node->fullpath);
+ return 0;
+ }
+
+ return 1;
+}
+
+static int name_prop_check(struct property *prop, struct node *node)
+{
+ if ((prop->val.len != node->basenamelen+1)
+ || !strneq(prop->val.val, node->name, node->basenamelen)) {
+ ERRMSG("name property \"%s\" does not match node basename in %s\n",
+ prop->val.val,
+ node->fullpath);
+ return 0;
+ }
+
+ return 1;
+}
+
+static struct {
+ char *propname;
+ int (*check_fn)(struct property *prop, struct node *node);
+} prop_checker_table[] = {
+ {"name", must_be_string},
+ {"name", name_prop_check},
+ {"linux,phandle", must_be_one_cell},
+ {"#address-cells", must_be_one_cell},
+ {"#size-cells", must_be_one_cell},
+ {"reg", must_be_cells},
+ {"model", must_be_string},
+ {"device_type", must_be_string},
+};
+
+static int check_properties(struct node *node)
+{
+ struct property *prop;
+ struct node *child;
+ int i;
+ int ok = 1;
+
+ 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;
+ }
+
+ for_each_child(node, child)
+ if (! check_properties(child))
+ ok = 0;
+
+ return ok;
+}
+
+#define CHECK_HAVE(node, propname) \
+ do { \
+ if (! (prop = get_property((node), (propname)))) \
+ DO_ERR("Missing \"%s\" property in %s\n", (propname), \
+ (node)->fullpath); \
+ } while (0);
+
+#define CHECK_HAVE_WARN(node, propname) \
+ do { \
+ if (! (prop = get_property((node), (propname)))) \
+ WARNMSG("%s has no \"%s\" property\n", \
+ (node)->fullpath, (propname)); \
+ } while (0)
+
+#define CHECK_HAVE_STRING(node, propname) \
+ do { \
+ CHECK_HAVE((node), (propname)); \
+ if (prop && !data_is_one_string(prop->val)) \
+ DO_ERR("\"%s\" property in %s is not a string\n", \
+ (propname), (node)->fullpath); \
+ } while (0)
+
+#define CHECK_HAVE_STREQ(node, propname, value) \
+ do { \
+ CHECK_HAVE_STRING((node), (propname)); \
+ if (prop && !streq(prop->val.val, (value))) \
+ DO_ERR("%s has wrong %s, %s (should be %s\n", \
+ (node)->fullpath, (propname), \
+ prop->val.val, (value)); \
+ } while (0)
+
+#define CHECK_HAVE_ONECELL(node, propname) \
+ do { \
+ CHECK_HAVE((node), (propname)); \
+ if (prop && (prop->val.len != sizeof(cell_t))) \
+ DO_ERR("\"%s\" property in %s has wrong size %d (should be 1 cell)\n", (propname), (node)->fullpath, prop->val.len); \
+ } while (0)
+
+#define CHECK_HAVE_WARN_ONECELL(node, propname) \
+ do { \
+ CHECK_HAVE_WARN((node), (propname)); \
+ if (prop && (prop->val.len != sizeof(cell_t))) \
+ DO_ERR("\"%s\" property in %s has wrong size %d (should be 1 cell)\n", (propname), (node)->fullpath, prop->val.len); \
+ } while (0)
+
+#define CHECK_HAVE_WARN_PHANDLE(xnode, propname, root) \
+ do { \
+ struct node *ref; \
+ CHECK_HAVE_WARN_ONECELL((xnode), (propname)); \
+ if (prop) {\
+ cell_t phandle = propval_cell(prop); \
+ if ((phandle == 0) || (phandle == -1)) { \
+ DO_ERR("\"%s\" property in %s contains an invalid phandle %x\n", (propname), (xnode)->fullpath, phandle); \
+ } else { \
+ ref = get_node_by_phandle((root), propval_cell(prop)); \
+ if (! ref) \
+ DO_ERR("\"%s\" property in %s refers to non-existant phandle %x\n", (propname), (xnode)->fullpath, propval_cell(prop)); \
+ } \
+ } \
+ } while (0)
+
+#define CHECK_HAVE_WARN_STRING(node, propname) \
+ do { \
+ CHECK_HAVE_WARN((node), (propname)); \
+ if (prop && !data_is_one_string(prop->val)) \
+ DO_ERR("\"%s\" property in %s is not a string\n", \
+ (propname), (node)->fullpath); \
+ } while (0)
+
+static int check_root(struct node *root)
+{
+ struct property *prop;
+ int ok = 1;
+
+ CHECK_HAVE_STRING(root, "model");
+
+ CHECK_HAVE(root, "#address-cells");
+ CHECK_HAVE(root, "#size-cells");
+
+ CHECK_HAVE_WARN(root, "compatible");
+
+ return ok;
+}
+
+static int check_cpus(struct node *root, int outversion, int boot_cpuid_phys)
+{
+ struct node *cpus, *cpu;
+ struct property *prop;
+ struct node *bootcpu = NULL;
+ int ok = 1;
+
+ cpus = get_subnode(root, "cpus");
+ if (! cpus) {
+ ERRMSG("Missing /cpus node\n");
+ return 0;
+ }
+
+ CHECK_HAVE_WARN(cpus, "#address-cells");
+ CHECK_HAVE_WARN(cpus, "#size-cells");
+
+ for_each_child(cpus, cpu) {
+ CHECK_HAVE_STREQ(cpu, "device_type", "cpu");
+
+ if (cpu->addr_cells != 1)
+ DO_ERR("%s has bad #address-cells value %d (should be 1)\n",
+ cpu->fullpath, cpu->addr_cells);
+ if (cpu->size_cells != 0)
+ DO_ERR("%s has bad #size-cells value %d (should be 0)\n",
+ cpu->fullpath, cpu->size_cells);
+
+ CHECK_HAVE_ONECELL(cpu, "reg");
+ if (prop) {
+ cell_t unitnum;
+ char *eptr;
+
+ unitnum = strtol(get_unitname(cpu), &eptr, 16);
+ if (*eptr) {
+ WARNMSG("%s has bad format unit name %s (should be CPU number\n",
+ cpu->fullpath, get_unitname(cpu));
+ } else if (unitnum != propval_cell(prop)) {
+ WARNMSG("%s unit name \"%s\" does not match \"reg\" property <%x>\n",
+ cpu->fullpath, get_unitname(cpu),
+ propval_cell(prop));
+ }
+ }
+
+/* CHECK_HAVE_ONECELL(cpu, "d-cache-line-size"); */
+/* CHECK_HAVE_ONECELL(cpu, "i-cache-line-size"); */
+ CHECK_HAVE_ONECELL(cpu, "d-cache-size");
+ CHECK_HAVE_ONECELL(cpu, "i-cache-size");
+
+ CHECK_HAVE_WARN_ONECELL(cpu, "clock-frequency");
+ CHECK_HAVE_WARN_ONECELL(cpu, "timebase-frequency");
+
+ prop = get_property(cpu, "linux,boot-cpu");
+ if (prop) {
+ if (prop->val.len)
+ WARNMSG("\"linux,boot-cpu\" property in %s is non-empty\n",
+ cpu->fullpath);
+ if (bootcpu)
+ DO_ERR("Multiple boot cpus (%s and %s)\n",
+ bootcpu->fullpath, cpu->fullpath);
+ else
+ bootcpu = cpu;
+ }
+ }
+
+ if (outversion < 2) {
+ if (! bootcpu)
+ WARNMSG("No cpu has \"linux,boot-cpu\" property\n");
+ } else {
+ if (bootcpu)
+ WARNMSG("\"linux,boot-cpu\" property is deprecated in blob version 2 or higher\n");
+ if (boot_cpuid_phys == 0xfeedbeef)
+ WARNMSG("physical boot CPU not set. Use -b option to set\n");
+ }
+
+ return ok;
+}
+
+static int check_memory(struct node *root)
+{
+ struct node *mem;
+ struct property *prop;
+ int nnodes = 0;
+ int ok = 1;
+
+ for_each_child(root, mem) {
+ if (! strneq(mem->name, "memory", mem->basenamelen))
+ continue;
+
+ nnodes++;
+
+ CHECK_HAVE_STREQ(mem, "device_type", "memory");
+ CHECK_HAVE(mem, "reg");
+ }
+
+ if (nnodes == 0) {
+ ERRMSG("No memory nodes\n");
+ return 0;
+ }
+
+ return ok;
+}
+
+static int check_chosen(struct node *root)
+{
+ struct node *chosen;
+ struct property *prop;
+ int ok = 1;
+
+ chosen = get_subnode(root, "chosen");
+ if (!chosen)
+ return ok;
+
+ /* give warning for obsolete interrupt-controller property */
+ do {
+ if ((prop = get_property(chosen, "interrupt-controller")) != NULL) {
+ WARNMSG("%s has obsolete \"%s\" property\n",
+ chosen->fullpath, "interrupt-controller");
+ }
+ } while (0);
+
+ return ok;
+}
+
+static int check_addr_size_reg(struct node *node,
+ int p_addr_cells, int p_size_cells)
+{
+ int addr_cells = p_addr_cells;
+ int size_cells = p_size_cells;
+ struct property *prop;
+ struct node *child;
+ int ok = 1;
+
+ node->addr_cells = addr_cells;
+ node->size_cells = size_cells;
+
+ prop = get_property(node, "reg");
+ if (prop) {
+ int len = prop->val.len / 4;
+
+ if ((len % (addr_cells+size_cells)) != 0)
+ DO_ERR("\"reg\" property in %s has invalid length (%d) for given #address-cells (%d) and #size-cells (%d)\n",
+ node->fullpath, prop->val.len,
+ addr_cells, size_cells);
+ }
+
+ prop = get_property(node, "#address-cells");
+ if (prop)
+ addr_cells = propval_cell(prop);
+
+ prop = get_property(node, "#size-cells");
+ if (prop)
+ size_cells = propval_cell(prop);
+
+ for_each_child(node, child) {
+ ok = ok && check_addr_size_reg(child, addr_cells, size_cells);
+ }
+
+ return ok;
+}
+
+int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys)
+{
+ int ok = 1;
+
+ ok = ok && check_properties(dt);
+ ok = ok && check_addr_size_reg(dt, -1, -1);
+ ok = ok && check_root(dt);
+ ok = ok && check_cpus(dt, outversion, boot_cpuid_phys);
+ ok = ok && check_memory(dt);
+ ok = ok && check_chosen(dt);
+ if (! ok)
+ return 0;
+
+ return 1;
+}
Index: dtc/livetree.c
===================================================================
--- dtc.orig/livetree.c 2007-11-01 14:53:17.000000000 +1100
+++ dtc/livetree.c 2007-11-01 14:56:55.000000000 +1100
@@ -180,7 +180,7 @@
* Tree accessor functions
*/
-static char *get_unitname(struct node *node)
+char *get_unitname(struct node *node)
{
if (node->name[node->basenamelen] == '\0')
return "";
@@ -188,7 +188,7 @@
return node->name + node->basenamelen + 1;
}
-static struct property *get_property(struct node *node, char *propname)
+struct property *get_property(struct node *node, char *propname)
{
struct property *prop;
@@ -199,13 +199,13 @@
return NULL;
}
-static cell_t propval_cell(struct property *prop)
+cell_t propval_cell(struct property *prop)
{
assert(prop->val.len == sizeof(cell_t));
return be32_to_cpu(*((cell_t *)prop->val.val));
}
-static struct node *get_subnode(struct node *node, char *nodename)
+struct node *get_subnode(struct node *node, char *nodename)
{
struct node *child;
@@ -257,7 +257,7 @@
return NULL;
}
-static struct node *get_node_by_phandle(struct node *tree, cell_t phandle)
+struct node *get_node_by_phandle(struct node *tree, cell_t phandle)
{
struct node *child, *node;
@@ -297,100 +297,6 @@
}
/*
- * 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
*/
@@ -442,348 +348,3 @@
{
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)) {
- ERRMSG("\"%s\" property in %s has the wrong length (should be 1 cell)\n",
- prop->name, node->fullpath);
- return 0;
- }
-
- return 1;
-}
-
-static int must_be_cells(struct property *prop, struct node *node)
-{
- if ((prop->val.len % sizeof(cell_t)) != 0) {
- ERRMSG("\"%s\" property in %s is not a multiple of cell size\n",
- prop->name, node->fullpath);
- return 0;
- }
-
- return 1;
-}
-
-static int must_be_string(struct property *prop, struct node *node)
-{
- if (! data_is_one_string(prop->val)) {
- ERRMSG("\"%s\" property in %s is not a string\n",
- prop->name, node->fullpath);
- return 0;
- }
-
- return 1;
-}
-
-static int name_prop_check(struct property *prop, struct node *node)
-{
- if ((prop->val.len != node->basenamelen+1)
- || !strneq(prop->val.val, node->name, node->basenamelen)) {
- ERRMSG("name property \"%s\" does not match node basename in %s\n",
- prop->val.val,
- node->fullpath);
- return 0;
- }
-
- return 1;
-}
-
-static struct {
- char *propname;
- int (*check_fn)(struct property *prop, struct node *node);
-} prop_checker_table[] = {
- {"name", must_be_string},
- {"name", name_prop_check},
- {"linux,phandle", must_be_one_cell},
- {"#address-cells", must_be_one_cell},
- {"#size-cells", must_be_one_cell},
- {"reg", must_be_cells},
- {"model", must_be_string},
- {"device_type", must_be_string},
-};
-
-static int check_properties(struct node *node)
-{
- struct property *prop;
- struct node *child;
- int i;
- int ok = 1;
-
- 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;
- }
-
- for_each_child(node, child)
- if (! check_properties(child))
- ok = 0;
-
- return ok;
-}
-
-#define CHECK_HAVE(node, propname) \
- do { \
- if (! (prop = get_property((node), (propname)))) \
- DO_ERR("Missing \"%s\" property in %s\n", (propname), \
- (node)->fullpath); \
- } while (0);
-
-#define CHECK_HAVE_WARN(node, propname) \
- do { \
- if (! (prop = get_property((node), (propname)))) \
- WARNMSG("%s has no \"%s\" property\n", \
- (node)->fullpath, (propname)); \
- } while (0)
-
-#define CHECK_HAVE_STRING(node, propname) \
- do { \
- CHECK_HAVE((node), (propname)); \
- if (prop && !data_is_one_string(prop->val)) \
- DO_ERR("\"%s\" property in %s is not a string\n", \
- (propname), (node)->fullpath); \
- } while (0)
-
-#define CHECK_HAVE_STREQ(node, propname, value) \
- do { \
- CHECK_HAVE_STRING((node), (propname)); \
- if (prop && !streq(prop->val.val, (value))) \
- DO_ERR("%s has wrong %s, %s (should be %s\n", \
- (node)->fullpath, (propname), \
- prop->val.val, (value)); \
- } while (0)
-
-#define CHECK_HAVE_ONECELL(node, propname) \
- do { \
- CHECK_HAVE((node), (propname)); \
- if (prop && (prop->val.len != sizeof(cell_t))) \
- DO_ERR("\"%s\" property in %s has wrong size %d (should be 1 cell)\n", (propname), (node)->fullpath, prop->val.len); \
- } while (0)
-
-#define CHECK_HAVE_WARN_ONECELL(node, propname) \
- do { \
- CHECK_HAVE_WARN((node), (propname)); \
- if (prop && (prop->val.len != sizeof(cell_t))) \
- DO_ERR("\"%s\" property in %s has wrong size %d (should be 1 cell)\n", (propname), (node)->fullpath, prop->val.len); \
- } while (0)
-
-#define CHECK_HAVE_WARN_PHANDLE(xnode, propname, root) \
- do { \
- struct node *ref; \
- CHECK_HAVE_WARN_ONECELL((xnode), (propname)); \
- if (prop) {\
- cell_t phandle = propval_cell(prop); \
- if ((phandle == 0) || (phandle == -1)) { \
- DO_ERR("\"%s\" property in %s contains an invalid phandle %x\n", (propname), (xnode)->fullpath, phandle); \
- } else { \
- ref = get_node_by_phandle((root), propval_cell(prop)); \
- if (! ref) \
- DO_ERR("\"%s\" property in %s refers to non-existant phandle %x\n", (propname), (xnode)->fullpath, propval_cell(prop)); \
- } \
- } \
- } while (0)
-
-#define CHECK_HAVE_WARN_STRING(node, propname) \
- do { \
- CHECK_HAVE_WARN((node), (propname)); \
- if (prop && !data_is_one_string(prop->val)) \
- DO_ERR("\"%s\" property in %s is not a string\n", \
- (propname), (node)->fullpath); \
- } while (0)
-
-static int check_root(struct node *root)
-{
- struct property *prop;
- int ok = 1;
-
- CHECK_HAVE_STRING(root, "model");
-
- CHECK_HAVE(root, "#address-cells");
- CHECK_HAVE(root, "#size-cells");
-
- CHECK_HAVE_WARN(root, "compatible");
-
- return ok;
-}
-
-static int check_cpus(struct node *root, int outversion, int boot_cpuid_phys)
-{
- struct node *cpus, *cpu;
- struct property *prop;
- struct node *bootcpu = NULL;
- int ok = 1;
-
- cpus = get_subnode(root, "cpus");
- if (! cpus) {
- ERRMSG("Missing /cpus node\n");
- return 0;
- }
-
- CHECK_HAVE_WARN(cpus, "#address-cells");
- CHECK_HAVE_WARN(cpus, "#size-cells");
-
- for_each_child(cpus, cpu) {
- CHECK_HAVE_STREQ(cpu, "device_type", "cpu");
-
- if (cpu->addr_cells != 1)
- DO_ERR("%s has bad #address-cells value %d (should be 1)\n",
- cpu->fullpath, cpu->addr_cells);
- if (cpu->size_cells != 0)
- DO_ERR("%s has bad #size-cells value %d (should be 0)\n",
- cpu->fullpath, cpu->size_cells);
-
- CHECK_HAVE_ONECELL(cpu, "reg");
- if (prop) {
- cell_t unitnum;
- char *eptr;
-
- unitnum = strtol(get_unitname(cpu), &eptr, 16);
- if (*eptr) {
- WARNMSG("%s has bad format unit name %s (should be CPU number\n",
- cpu->fullpath, get_unitname(cpu));
- } else if (unitnum != propval_cell(prop)) {
- WARNMSG("%s unit name \"%s\" does not match \"reg\" property <%x>\n",
- cpu->fullpath, get_unitname(cpu),
- propval_cell(prop));
- }
- }
-
-/* CHECK_HAVE_ONECELL(cpu, "d-cache-line-size"); */
-/* CHECK_HAVE_ONECELL(cpu, "i-cache-line-size"); */
- CHECK_HAVE_ONECELL(cpu, "d-cache-size");
- CHECK_HAVE_ONECELL(cpu, "i-cache-size");
-
- CHECK_HAVE_WARN_ONECELL(cpu, "clock-frequency");
- CHECK_HAVE_WARN_ONECELL(cpu, "timebase-frequency");
-
- prop = get_property(cpu, "linux,boot-cpu");
- if (prop) {
- if (prop->val.len)
- WARNMSG("\"linux,boot-cpu\" property in %s is non-empty\n",
- cpu->fullpath);
- if (bootcpu)
- DO_ERR("Multiple boot cpus (%s and %s)\n",
- bootcpu->fullpath, cpu->fullpath);
- else
- bootcpu = cpu;
- }
- }
-
- if (outversion < 2) {
- if (! bootcpu)
- WARNMSG("No cpu has \"linux,boot-cpu\" property\n");
- } else {
- if (bootcpu)
- WARNMSG("\"linux,boot-cpu\" property is deprecated in blob version 2 or higher\n");
- if (boot_cpuid_phys == 0xfeedbeef)
- WARNMSG("physical boot CPU not set. Use -b option to set\n");
- }
-
- return ok;
-}
-
-static int check_memory(struct node *root)
-{
- struct node *mem;
- struct property *prop;
- int nnodes = 0;
- int ok = 1;
-
- for_each_child(root, mem) {
- if (! strneq(mem->name, "memory", mem->basenamelen))
- continue;
-
- nnodes++;
-
- CHECK_HAVE_STREQ(mem, "device_type", "memory");
- CHECK_HAVE(mem, "reg");
- }
-
- if (nnodes == 0) {
- ERRMSG("No memory nodes\n");
- return 0;
- }
-
- return ok;
-}
-
-static int check_chosen(struct node *root)
-{
- struct node *chosen;
- struct property *prop;
- int ok = 1;
-
- chosen = get_subnode(root, "chosen");
- if (!chosen)
- return ok;
-
- /* give warning for obsolete interrupt-controller property */
- do {
- if ((prop = get_property(chosen, "interrupt-controller")) != NULL) {
- WARNMSG("%s has obsolete \"%s\" property\n",
- chosen->fullpath, "interrupt-controller");
- }
- } while (0);
-
- return ok;
-}
-
-static int check_addr_size_reg(struct node *node,
- int p_addr_cells, int p_size_cells)
-{
- int addr_cells = p_addr_cells;
- int size_cells = p_size_cells;
- struct property *prop;
- struct node *child;
- int ok = 1;
-
- node->addr_cells = addr_cells;
- node->size_cells = size_cells;
-
- prop = get_property(node, "reg");
- if (prop) {
- int len = prop->val.len / 4;
-
- if ((len % (addr_cells+size_cells)) != 0)
- DO_ERR("\"reg\" property in %s has invalid length (%d) for given #address-cells (%d) and #size-cells (%d)\n",
- node->fullpath, prop->val.len,
- addr_cells, size_cells);
- }
-
- prop = get_property(node, "#address-cells");
- if (prop)
- addr_cells = propval_cell(prop);
-
- prop = get_property(node, "#size-cells");
- if (prop)
- size_cells = propval_cell(prop);
-
- for_each_child(node, child) {
- ok = ok && check_addr_size_reg(child, addr_cells, size_cells);
- }
-
- return ok;
-}
-
-int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys)
-{
- int ok = 1;
-
- ok = ok && check_properties(dt);
- ok = ok && check_addr_size_reg(dt, -1, -1);
- ok = ok && check_root(dt);
- ok = ok && check_cpus(dt, outversion, boot_cpuid_phys);
- ok = ok && check_memory(dt);
- ok = ok && check_chosen(dt);
- if (! ok)
- return 0;
-
- return 1;
-}
Index: dtc/Makefile.dtc
===================================================================
--- dtc.orig/Makefile.dtc 2007-11-01 14:53:42.000000000 +1100
+++ dtc/Makefile.dtc 2007-11-01 14:53:57.000000000 +1100
@@ -3,7 +3,8 @@
# This is not a complete Makefile of itself. Instead, it is designed to
# be easily embeddable into other systems of Makefiles.
#
-DTC_SRCS = dtc.c flattree.c fstree.c data.c livetree.c treesource.c srcpos.c
+DTC_SRCS = dtc.c flattree.c fstree.c data.c livetree.c treesource.c srcpos.c \
+ checks.c
DTC_EXTRA = dtc.h srcpos.h
DTC_LEXFILES = dtc-lexer.l
DTC_BISONFILES = dtc-parser.y
Index: dtc/dtc.h
===================================================================
--- dtc.orig/dtc.h 2007-11-01 14:54:26.000000000 +1100
+++ dtc/dtc.h 2007-11-01 14:57:06.000000000 +1100
@@ -189,11 +189,13 @@
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);
+char *get_unitname(struct node *node);
+struct property *get_property(struct node *node, char *propname);
+cell_t propval_cell(struct property *prop);
+struct node *get_subnode(struct node *node, char *nodename);
+struct node *get_node_by_phandle(struct node *tree, cell_t phandle);
-int check_device_tree(struct node *dt, int outversion, int boot_cpuid_phys);
+void fixup_references(struct node *dt);
/* Boot info (tree plus memreserve information */
@@ -220,6 +222,11 @@
struct boot_info *build_boot_info(struct reserve_info *reservelist,
struct node *tree);
+/* Checks */
+
+int check_structure(struct node *dt);
+int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys);
+
/* Flattened trees */
void dt_to_blob(FILE *f, struct boot_info *bi, int version,
--
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: question on modifying pte entries
From: Benjamin Herrenschmidt @ 2007-11-01 4:37 UTC (permalink / raw)
To: Chris Friesen; +Cc: linuxppc-dev
In-Reply-To: <4728DB43.1060205@nortel.com>
On Wed, 2007-10-31 at 13:45 -0600, Chris Friesen wrote:
> Hi all,
>
> We've got some kernel code that monitors which pages have been dirtied
> by an application.
>
> The pages are locked in memory, and the system has no swap. Initially
> we mark the pages clean using ptep_clear_flush_dirty(), then when
> requested by the app we scanning through the pages and check the dirty
> bit using pte_dirty(). If it's dirty we store the address and then mark
> it clean using the same function as above. The above is all done while
> holding both mm->mmap_sem and mm->page_table_lock.
>
> This worked fine in 2.6.10 but now in 2.6.14 it's giving us problems.
> Periodically we'll get a page that we know has been dirtied, but it
> doesn't get detected as such. It appears that once this occurs, that
> page will never again be detected as dirty.
>
> Does anyone have any ideas what may be happening? Were there any
> changes in the page table area other than moving to 4-level mappings?
> Anyone aware of any missing tlb flushes that were fixed later?
.14 ? ouch that's old... I can't tell you for sure what went in when,
also you aren't telling us whether you are using 32 or 64 bits kernels
and what processor family it is, so it's hard to help you there.
What comes to mind though:
- At one point, a PTE page lock was introduced. You need to take that
instead of the PTL (actually, you may need to take both, I'm not sure).
I don't know off hand if 2.6.14 has it already though.
- Flushes are batched on ppc64. There might be something wrong with the
batching... clear_flush_dirty should flush but maybe it's not doing it
or something like that... There used to be a subtle race with the
batching as well that you may hit, not sure, that's why I reworked it
all recently (in .22 or .23 iirc).
- Maybe the VM is messing around and disliking the changes to the PTE
you are doing behind its back ?
Ben.
^ permalink raw reply
* RE: [PATCH] ucc_geth: add support for netpoll
From: Li Yang-r58472 @ 2007-11-01 2:33 UTC (permalink / raw)
To: cbou; +Cc: netdev, linux-kernel, linuxppc-dev
In-Reply-To: <20071031215903.GA1287@zarina>
> -----Original Message-----
> From: Anton Vorontsov [mailto:cbou@mail.ru]=20
> Sent: Thursday, November 01, 2007 5:59 AM
> To: Li Yang-r58472
> Cc: netdev@vger.kernel.org; linux-kernel@vger.kernel.org;=20
> linuxppc-dev@ozlabs.org
> Subject: Re: [PATCH] ucc_geth: add support for netpoll
>=20
> On Mon, Oct 29, 2007 at 03:17:44PM +0300, Anton Vorontsov wrote:
> [...]
> > > Oops. The original patch happened to hit the Junk mail box. :(
> >=20
> > That one as well? http://lkml.org/lkml/2007/10/11/128
> >=20
> > > I think
> > > the patch is good to merge after the cosmetic change. I=20
> can do it=20
> > > in next pull request to Jeff.
> >=20
> > Ok, great. Thanks.
>=20
> I'm wondering if you missed that email again. Maybe your mail=20
> client/server doing weird things with emails from @ru.mvista.com?
No. I have explicitly add you to the whitelist. :) Please be patient,
isn't this patch a new feature which can only be integrated in the merge
window? Thanks.
- Leo
^ permalink raw reply
* Re: [PATCH 1/3] Add remove_memory() for ppc64
From: KAMEZAWA Hiroyuki @ 2007-11-01 0:46 UTC (permalink / raw)
To: Dave Hansen
Cc: linuxppc-dev, anton, linux-mm, Paul Mackerras, GOTO,
Badari Pulavarty, Andrew Morton
In-Reply-To: <1193867703.6271.42.camel@localhost>
On Wed, 31 Oct 2007 14:55:03 -0700
Dave Hansen <haveblue@us.ibm.com> wrote:
> On Wed, 2007-10-31 at 14:11 -0800, Badari Pulavarty wrote:
> >
> > Well, We don't need arch-specific remove_memory() for ia64 and ppc64.
> > x86_64, I don't know. We will know, only when some one does the
> > verification. I don't need arch_remove_memory() hook also at this
> > time.
>
> I wasn't being very clear. I say, add the arch hook only if you need
> it. But, for now, just take the ia64 code and make it generic.
>
remove_memory() has been arch-specific since there was no piece of unplug
code. And I didn't merge it to be generic when I implemented ia64 ver.
Hmm...I have no objection to merge them. But let's see how memory hotremove
for ppc64 works for a while. We can merge them later.
I'm glad to have new testers :)
Thanks,
-Kame
^ permalink raw reply
* libfdt: Handle v16 and re-ordered trees for r/w
From: David Gibson @ 2007-11-01 0:37 UTC (permalink / raw)
To: Jon Loeliger; +Cc: linuxppc-dev
Currently all the read/write functions in libfdt require that the
given tree be v17, and further, that the tree has the memory
reservation block, structure block and strings block stored in that
physical order.
This patch eases these constraints, by making fdt_open_int() reorder
the blocks, and/or convert the tree to v17, so that it will then be
ready for the other read-write functions.
It also extends fdt_pack() to actually remove any gaps between blocks
that might be present.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Index: dtc/libfdt/fdt_rw.c
===================================================================
--- dtc.orig/libfdt/fdt_rw.c 2007-10-31 18:45:58.000000000 +1100
+++ dtc/libfdt/fdt_rw.c 2007-11-01 11:18:24.000000000 +1100
@@ -55,6 +55,18 @@
#include "libfdt_internal.h"
+static int _blocks_misordered(const void *fdt,
+ int mem_rsv_size, int struct_size)
+{
+ return (fdt_off_mem_rsvmap(fdt) < ALIGN(sizeof(struct fdt_header), 8))
+ || (fdt_off_dt_struct(fdt) <
+ (fdt_off_mem_rsvmap(fdt) + mem_rsv_size))
+ || (fdt_off_dt_strings(fdt) <
+ (fdt_off_dt_struct(fdt) + struct_size))
+ || (fdt_totalsize(fdt) <
+ (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
+}
+
static int rw_check_header(void *fdt)
{
int err;
@@ -63,16 +75,8 @@
return err;
if (fdt_version(fdt) < 17)
return -FDT_ERR_BADVERSION;
- if (fdt_off_mem_rsvmap(fdt) < ALIGN(sizeof(struct fdt_header), 8))
- return -FDT_ERR_BADLAYOUT;
- if (fdt_off_dt_struct(fdt) <
- (fdt_off_mem_rsvmap(fdt) + sizeof(struct fdt_reserve_entry)))
- return -FDT_ERR_BADLAYOUT;
- if (fdt_off_dt_strings(fdt) <
- (fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt)))
- return -FDT_ERR_BADLAYOUT;
- if (fdt_totalsize(fdt) <
- (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)))
+ if (_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry),
+ fdt_size_dt_struct(fdt)))
return -FDT_ERR_BADLAYOUT;
if (fdt_version(fdt) > 17)
fdt_set_version(fdt, 17);
@@ -342,36 +346,102 @@
endoffset - nodeoffset, 0);
}
-int fdt_open_into(void *fdt, void *buf, int bufsize)
+static void _packblocks(const void *fdt, void *buf,
+ int mem_rsv_size, int struct_size)
+{
+ int mem_rsv_off, struct_off, strings_off;
+
+ mem_rsv_off = ALIGN(sizeof(struct fdt_header), 8);
+ struct_off = mem_rsv_off + mem_rsv_size;
+ strings_off = struct_off + struct_size;
+
+ memmove(buf + mem_rsv_off, fdt + fdt_off_mem_rsvmap(fdt), mem_rsv_size);
+ fdt_set_off_mem_rsvmap(buf, mem_rsv_off);
+
+ memcpy(buf + struct_off, fdt + fdt_off_dt_struct(fdt), struct_size);
+ fdt_set_off_dt_struct(buf, struct_off);
+ fdt_set_size_dt_struct(buf, struct_size);
+
+ memcpy(buf + strings_off, fdt + fdt_off_dt_strings(fdt),
+ fdt_size_dt_strings(fdt));
+ fdt_set_off_dt_strings(buf, strings_off);
+ fdt_set_size_dt_strings(buf, fdt_size_dt_strings(fdt));
+}
+
+int fdt_open_into(const void *fdt, void *buf, int bufsize)
{
int err;
+ int mem_rsv_size, struct_size;
+ int newsize;
+ void *tmp;
- err = fdt_move(fdt, buf, bufsize);
+ err = fdt_check_header(fdt);
if (err)
return err;
- fdt = buf;
+ mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
+ * sizeof(struct fdt_reserve_entry);
- fdt_set_totalsize(fdt, bufsize);
+ if (fdt_version(fdt) >= 17) {
+ struct_size = fdt_size_dt_struct(fdt);
+ } else {
+ struct_size = 0;
+ while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
+ ;
+ }
- /* FIXME: re-order if necessary */
+ if (!_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
+ /* no further work necessary */
+ err = fdt_move(fdt, buf, bufsize);
+ if (err)
+ return err;
+ fdt_set_version(buf, 17);
+ fdt_set_size_dt_struct(buf, struct_size);
+ fdt_set_totalsize(buf, bufsize);
+ return 0;
+ }
- err = rw_check_header(fdt);
- if (err)
- return err;
+ /* Need to reorder */
+ newsize = ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
+ + struct_size + fdt_size_dt_strings(fdt);
+
+ if (bufsize < newsize)
+ return -FDT_ERR_NOSPACE;
+
+ if (((buf + newsize) <= fdt)
+ || (buf >= (fdt + fdt_totalsize(fdt)))) {
+ tmp = buf;
+ } else {
+ tmp = (void *)fdt + fdt_totalsize(fdt);
+ if ((tmp + newsize) > (buf + bufsize))
+ return -FDT_ERR_NOSPACE;
+ }
+
+ _packblocks(fdt, tmp, mem_rsv_size, struct_size);
+ memmove(buf, tmp, newsize);
+
+ fdt_set_magic(buf, FDT_MAGIC);
+ fdt_set_totalsize(buf, bufsize);
+ fdt_set_version(buf, 17);
+ fdt_set_last_comp_version(buf, 16);
+ fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt));
return 0;
}
int fdt_pack(void *fdt)
{
+ int mem_rsv_size;
int err;
err = rw_check_header(fdt);
if (err)
return err;
- /* FIXME: pack components */
+ mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
+ * sizeof(struct fdt_reserve_entry);
+ _packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
fdt_set_totalsize(fdt, _blob_data_size(fdt));
+
return 0;
}
Index: dtc/libfdt/libfdt.h
===================================================================
--- dtc.orig/libfdt/libfdt.h 2007-10-31 18:45:59.000000000 +1100
+++ dtc/libfdt/libfdt.h 2007-11-01 10:38:53.000000000 +1100
@@ -412,7 +412,7 @@
/* Read-write functions */
/**********************************************************************/
-int fdt_open_into(void *fdt, void *buf, int bufsize);
+int fdt_open_into(const void *fdt, void *buf, int bufsize);
int fdt_pack(void *fdt);
int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
Index: dtc/tests/run_tests.sh
===================================================================
--- dtc.orig/tests/run_tests.sh 2007-11-01 10:38:52.000000000 +1100
+++ dtc/tests/run_tests.sh 2007-11-01 10:38:53.000000000 +1100
@@ -62,6 +62,8 @@
run_test del_node $TREE
}
+ALL_LAYOUTS="mts mst tms tsm smt stm"
+
libfdt_tests () {
tree1_tests test_tree1.dtb
@@ -82,7 +84,7 @@
# v16 and alternate layout tests
for tree in test_tree1.dtb; do
for version in 17 16; do
- for layout in mts mst tms tsm smt stm; do
+ for layout in $ALL_LAYOUTS; do
run_test mangle-layout $tree $version $layout
tree1_tests v$version.$layout.$tree
run_test dtbs_equal_ordered $tree v$version.$layout.$tree
@@ -91,18 +93,21 @@
done
# Read-write tests
- for tree in test_tree1.dtb sw_tree1.test.dtb; do
- rm -f opened.$tree repacked.$tree
- run_test open_pack $tree
- tree1_tests opened.$tree
- tree1_tests repacked.$tree
- done
-
- for tree in test_tree1.dtb sw_tree1.test.dtb; do
- tree1_tests_rw $tree
- tree1_tests_rw moved.$tree
- tree1_tests_rw shunted.$tree
- tree1_tests_rw deshunted.$tree
+ for basetree in test_tree1.dtb; do
+ for version in 17 16; do
+ for layout in $ALL_LAYOUTS; do
+ tree=v$version.$layout.$basetree
+ rm -f opened.$tree repacked.$tree
+ run_test open_pack $tree
+ tree1_tests $tree
+ tree1_tests opened.$tree
+ tree1_tests repacked.$tree
+
+ tree1_tests_rw $tree
+ tree1_tests_rw opened.$tree
+ tree1_tests_rw repacked.$tree
+ done
+ done
done
run_test rw_tree1
tree1_tests rw_tree1.test.dtb
Index: dtc/tests/del_property.c
===================================================================
--- dtc.orig/tests/del_property.c 2007-10-31 18:45:59.000000000 +1100
+++ dtc/tests/del_property.c 2007-11-01 10:38:53.000000000 +1100
@@ -41,6 +41,8 @@
test_init(argc, argv);
fdt = load_blob_arg(argc, argv);
+ fdt = open_blob_rw(fdt);
+
oldsize = fdt_totalsize(fdt);
intp = check_getprop_typed(fdt, 0, "prop-int", TEST_VALUE_1);
Index: dtc/tests/testutils.c
===================================================================
--- dtc.orig/tests/testutils.c 2007-10-31 18:45:59.000000000 +1100
+++ dtc/tests/testutils.c 2007-11-01 10:38:53.000000000 +1100
@@ -220,3 +220,21 @@
offset += ret;
}
}
+
+void *open_blob_rw(void *blob)
+{
+ int err;
+ void *buf = blob;
+
+ err = fdt_open_into(blob, buf, fdt_totalsize(blob));
+ if (err == -FDT_ERR_NOSPACE) {
+ /* Ran out of space converting to v17 */
+ int newsize = fdt_totalsize(blob) + 8;
+
+ buf = xmalloc(newsize);
+ err = fdt_open_into(blob, buf, newsize);
+ }
+ if (err)
+ FAIL("fdt_open_into(): %s", fdt_strerror(err));
+ return buf;
+}
Index: dtc/tests/del_node.c
===================================================================
--- dtc.orig/tests/del_node.c 2007-10-31 18:45:59.000000000 +1100
+++ dtc/tests/del_node.c 2007-11-01 10:38:53.000000000 +1100
@@ -40,6 +40,8 @@
test_init(argc, argv);
fdt = load_blob_arg(argc, argv);
+ fdt = open_blob_rw(fdt);
+
oldsize = fdt_totalsize(fdt);
subnode1_offset = fdt_path_offset(fdt, "/subnode@1");
Index: dtc/tests/tests.h
===================================================================
--- dtc.orig/tests/tests.h 2007-10-31 18:45:59.000000000 +1100
+++ dtc/tests/tests.h 2007-11-01 10:38:53.000000000 +1100
@@ -132,5 +132,6 @@
void *load_blob(const char *filename);
void *load_blob_arg(int argc, char *argv[]);
void save_blob(const char *filename, void *blob);
+void *open_blob_rw(void *blob);
#endif /* _TESTS_H */
--
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
* [2.6 patch] the scheduled I2C RTC driver removal
From: Adrian Bunk @ 2007-10-31 23:03 UTC (permalink / raw)
To: Jean Delvare; +Cc: linuxppc-dev, linux-kernel, i2c
This patch contains the scheduled removal of legacy I2C RTC drivers with
replacement drivers.
Signed-off-by: Adrian Bunk <bunk@kernel.org>
---
Documentation/feature-removal-schedule.txt | 7
arch/powerpc/platforms/83xx/mpc832x_mds.c | 24 -
arch/powerpc/platforms/83xx/mpc834x_mds.c | 24 -
arch/powerpc/platforms/83xx/mpc836x_mds.c | 24 -
arch/ppc/platforms/83xx/mpc834x_sys.c | 20 -
arch/ppc/platforms/85xx/tqm85xx.c | 21 -
arch/ppc/platforms/katana.c | 21 -
drivers/i2c/chips/Kconfig | 38 -
drivers/i2c/chips/Makefile | 3
drivers/i2c/chips/ds1337.c | 410 --------------------
drivers/i2c/chips/ds1374.c | 267 -------------
drivers/i2c/chips/m41t00.c | 413 ---------------------
include/linux/m41t00.h | 50 --
13 files changed, 1322 deletions(-)
bf858b44b3071082be3aaf71e2d46ddb26415247
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 6bb9be5..391f2d1 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -275,13 +275,6 @@ Who: Tejun Heo <htejun@gmail.com>
---------------------------
-What: Legacy RTC drivers (under drivers/i2c/chips)
-When: November 2007
-Why: Obsolete. We have a RTC subsystem with better drivers.
-Who: Jean Delvare <khali@linux-fr.org>
-
----------------------------
-
What: iptables SAME target
When: 1.1. 2008
Files: net/ipv4/netfilter/ipt_SAME.c, include/linux/netfilter_ipv4/ipt_SAME.h
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
index 972fa85..66382df 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -145,30 +145,6 @@ static void __init mpc832x_sys_init_IRQ(void)
#endif /* CONFIG_QUICC_ENGINE */
}
-#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
-extern ulong ds1374_get_rtc_time(void);
-extern int ds1374_set_rtc_time(ulong);
-
-static int __init mpc832x_rtc_hookup(void)
-{
- struct timespec tv;
-
- if (!machine_is(mpc832x_mds))
- return 0;
-
- ppc_md.get_rtc_time = ds1374_get_rtc_time;
- ppc_md.set_rtc_time = ds1374_set_rtc_time;
-
- tv.tv_nsec = 0;
- tv.tv_sec = (ppc_md.get_rtc_time) ();
- do_settimeofday(&tv);
-
- return 0;
-}
-
-late_initcall(mpc832x_rtc_hookup);
-#endif
-
/*
* Called very early, MMU is off, device-tree isn't unflattened
*/
diff --git a/arch/powerpc/platforms/83xx/mpc834x_mds.c b/arch/powerpc/platforms/83xx/mpc834x_mds.c
index 00aed7c..a81bb3c 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c
@@ -106,30 +106,6 @@ static void __init mpc834x_mds_init_IRQ(void)
ipic_set_default_priority();
}
-#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
-extern ulong ds1374_get_rtc_time(void);
-extern int ds1374_set_rtc_time(ulong);
-
-static int __init mpc834x_rtc_hookup(void)
-{
- struct timespec tv;
-
- if (!machine_is(mpc834x_mds))
- return 0;
-
- ppc_md.get_rtc_time = ds1374_get_rtc_time;
- ppc_md.set_rtc_time = ds1374_set_rtc_time;
-
- tv.tv_nsec = 0;
- tv.tv_sec = (ppc_md.get_rtc_time) ();
- do_settimeofday(&tv);
-
- return 0;
-}
-
-late_initcall(mpc834x_rtc_hookup);
-#endif
-
/*
* Called very early, MMU is off, device-tree isn't unflattened
*/
diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c
index 0f3855c..8d87b9c 100644
--- a/arch/powerpc/platforms/83xx/mpc836x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c
@@ -152,30 +152,6 @@ static void __init mpc836x_mds_init_IRQ(void)
#endif /* CONFIG_QUICC_ENGINE */
}
-#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
-extern ulong ds1374_get_rtc_time(void);
-extern int ds1374_set_rtc_time(ulong);
-
-static int __init mpc8360_rtc_hookup(void)
-{
- struct timespec tv;
-
- if (!machine_is(mpc836x_mds))
- return 0;
-
- ppc_md.get_rtc_time = ds1374_get_rtc_time;
- ppc_md.set_rtc_time = ds1374_set_rtc_time;
-
- tv.tv_nsec = 0;
- tv.tv_sec = (ppc_md.get_rtc_time) ();
- do_settimeofday(&tv);
-
- return 0;
-}
-
-late_initcall(mpc8360_rtc_hookup);
-#endif
-
/*
* Called very early, MMU is off, device-tree isn't unflattened
*/
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c
index b84f8df..cb0a749 100644
--- a/arch/ppc/platforms/83xx/mpc834x_sys.c
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.c
@@ -224,26 +224,6 @@ mpc834x_sys_init_IRQ(void)
ipic_set_default_priority();
}
-#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
-extern ulong ds1374_get_rtc_time(void);
-extern int ds1374_set_rtc_time(ulong);
-
-static int __init
-mpc834x_rtc_hookup(void)
-{
- struct timespec tv;
-
- ppc_md.get_rtc_time = ds1374_get_rtc_time;
- ppc_md.set_rtc_time = ds1374_set_rtc_time;
-
- tv.tv_nsec = 0;
- tv.tv_sec = (ppc_md.get_rtc_time)();
- do_settimeofday(&tv);
-
- return 0;
-}
-late_initcall(mpc834x_rtc_hookup);
-#endif
static __inline__ void
mpc834x_sys_set_bat(void)
{
diff --git a/arch/ppc/platforms/85xx/tqm85xx.c b/arch/ppc/platforms/85xx/tqm85xx.c
index 4ee2bd1..27ce389 100644
--- a/arch/ppc/platforms/85xx/tqm85xx.c
+++ b/arch/ppc/platforms/85xx/tqm85xx.c
@@ -258,27 +258,6 @@ int tqm85xx_show_cpuinfo(struct seq_file *m)
return 0;
}
-#if defined(CONFIG_I2C) && defined(CONFIG_SENSORS_DS1337)
-extern ulong ds1337_get_rtc_time(void);
-extern int ds1337_set_rtc_time(unsigned long nowtime);
-
-static int __init
-tqm85xx_rtc_hookup(void)
-{
- struct timespec tv;
-
- ppc_md.set_rtc_time = ds1337_set_rtc_time;
- ppc_md.get_rtc_time = ds1337_get_rtc_time;
-
- tv.tv_nsec = 0;
- tv.tv_sec = (ppc_md.get_rtc_time)();
- do_settimeofday(&tv);
-
- return 0;
-}
-late_initcall(tqm85xx_rtc_hookup);
-#endif
-
#ifdef CONFIG_PCI
/*
* interrupt routing
diff --git a/arch/ppc/platforms/katana.c b/arch/ppc/platforms/katana.c
index 52f63e6..fe6e88c 100644
--- a/arch/ppc/platforms/katana.c
+++ b/arch/ppc/platforms/katana.c
@@ -838,27 +838,6 @@ katana_find_end_of_memory(void)
return bdp->bi_memsize;
}
-#if defined(CONFIG_I2C_MV64XXX) && defined(CONFIG_SENSORS_M41T00)
-extern ulong m41t00_get_rtc_time(void);
-extern int m41t00_set_rtc_time(ulong);
-
-static int __init
-katana_rtc_hookup(void)
-{
- struct timespec tv;
-
- ppc_md.get_rtc_time = m41t00_get_rtc_time;
- ppc_md.set_rtc_time = m41t00_set_rtc_time;
-
- tv.tv_nsec = 0;
- tv.tv_sec = (ppc_md.get_rtc_time)();
- do_settimeofday(&tv);
-
- return 0;
-}
-late_initcall(katana_rtc_hookup);
-#endif
-
#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE)
static void __init
katana_map_io(void)
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
index 2e1c24f..5b8eb02 100644
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -4,32 +4,6 @@
menu "Miscellaneous I2C Chip support"
-config SENSORS_DS1337
- tristate "Dallas DS1337 and DS1339 Real Time Clock (DEPRECATED)"
- depends on EXPERIMENTAL
- help
- If you say yes here you get support for Dallas Semiconductor
- DS1337 and DS1339 real-time clock chips.
-
- This driver can also be built as a module. If so, the module
- will be called ds1337.
-
- This driver is deprecated and will be dropped soon. Use
- rtc-ds1307 instead.
-
-config SENSORS_DS1374
- tristate "Dallas DS1374 Real Time Clock (DEPRECATED)"
- depends on EXPERIMENTAL
- help
- If you say yes here you get support for Dallas Semiconductor
- DS1374 real-time clock chips.
-
- This driver can also be built as a module. If so, the module
- will be called ds1374.
-
- This driver is deprecated and will be dropped soon. Use
- rtc-ds1374 instead.
-
config DS1682
tristate "Dallas DS1682 Total Elapsed Time Recorder with Alarm"
depends on EXPERIMENTAL
@@ -116,18 +90,6 @@ config TPS65010
This driver can also be built as a module. If so, the module
will be called tps65010.
-config SENSORS_M41T00
- tristate "ST M41T00 RTC chip (DEPRECATED)"
- depends on PPC32
- help
- If you say yes here you get support for the ST M41T00 RTC chip.
-
- This driver can also be built as a module. If so, the module
- will be called m41t00.
-
- This driver is deprecated and will be dropped soon. Use
- rtc-ds1307 or rtc-m41t80 instead.
-
config SENSORS_MAX6875
tristate "Maxim MAX6875 Power supply supervisor"
depends on EXPERIMENTAL
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
index ca924e1..1d5d1a5 100644
--- a/drivers/i2c/chips/Makefile
+++ b/drivers/i2c/chips/Makefile
@@ -2,12 +2,9 @@
# Makefile for miscellaneous I2C chip drivers.
#
-obj-$(CONFIG_SENSORS_DS1337) += ds1337.o
-obj-$(CONFIG_SENSORS_DS1374) += ds1374.o
obj-$(CONFIG_DS1682) += ds1682.o
obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o
obj-$(CONFIG_SENSORS_MAX6875) += max6875.o
-obj-$(CONFIG_SENSORS_M41T00) += m41t00.o
obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o
obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o
obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
diff --git a/drivers/i2c/chips/ds1337.c b/drivers/i2c/chips/ds1337.c
deleted file mode 100644
index ec17d6b..0000000
--- a/drivers/i2c/chips/ds1337.c
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * linux/drivers/i2c/chips/ds1337.c
- *
- * Copyright (C) 2005 James Chapman <jchapman@katalix.com>
- *
- * based on linux/drivers/acorn/char/pcf8583.c
- * Copyright (C) 2000 Russell King
- *
- * 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.
- *
- * Driver for Dallas Semiconductor DS1337 and DS1339 real time clock chip
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/string.h>
-#include <linux/rtc.h> /* get the user-level API */
-#include <linux/bcd.h>
-#include <linux/list.h>
-
-/* Device registers */
-#define DS1337_REG_HOUR 2
-#define DS1337_REG_DAY 3
-#define DS1337_REG_DATE 4
-#define DS1337_REG_MONTH 5
-#define DS1337_REG_CONTROL 14
-#define DS1337_REG_STATUS 15
-
-/* FIXME - how do we export these interface constants? */
-#define DS1337_GET_DATE 0
-#define DS1337_SET_DATE 1
-
-/*
- * Functions declaration
- */
-static unsigned short normal_i2c[] = { 0x68, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD_1(ds1337);
-
-static int ds1337_attach_adapter(struct i2c_adapter *adapter);
-static int ds1337_detect(struct i2c_adapter *adapter, int address, int kind);
-static void ds1337_init_client(struct i2c_client *client);
-static int ds1337_detach_client(struct i2c_client *client);
-static int ds1337_command(struct i2c_client *client, unsigned int cmd,
- void *arg);
-
-/*
- * Driver data (common to all clients)
- */
-static struct i2c_driver ds1337_driver = {
- .driver = {
- .name = "ds1337",
- },
- .attach_adapter = ds1337_attach_adapter,
- .detach_client = ds1337_detach_client,
- .command = ds1337_command,
-};
-
-/*
- * Client data (each client gets its own)
- */
-struct ds1337_data {
- struct i2c_client client;
- struct list_head list;
-};
-
-/*
- * Internal variables
- */
-static LIST_HEAD(ds1337_clients);
-
-static inline int ds1337_read(struct i2c_client *client, u8 reg, u8 *value)
-{
- s32 tmp = i2c_smbus_read_byte_data(client, reg);
-
- if (tmp < 0)
- return -EIO;
-
- *value = tmp;
-
- return 0;
-}
-
-/*
- * Chip access functions
- */
-static int ds1337_get_datetime(struct i2c_client *client, struct rtc_time *dt)
-{
- int result;
- u8 buf[7];
- u8 val;
- struct i2c_msg msg[2];
- u8 offs = 0;
-
- if (!dt) {
- dev_dbg(&client->dev, "%s: EINVAL: dt=NULL\n", __FUNCTION__);
- return -EINVAL;
- }
-
- msg[0].addr = client->addr;
- msg[0].flags = 0;
- msg[0].len = 1;
- msg[0].buf = &offs;
-
- msg[1].addr = client->addr;
- msg[1].flags = I2C_M_RD;
- msg[1].len = sizeof(buf);
- msg[1].buf = &buf[0];
-
- result = i2c_transfer(client->adapter, msg, 2);
-
- dev_dbg(&client->dev, "%s: [%d] %02x %02x %02x %02x %02x %02x %02x\n",
- __FUNCTION__, result, buf[0], buf[1], buf[2], buf[3],
- buf[4], buf[5], buf[6]);
-
- if (result == 2) {
- dt->tm_sec = BCD2BIN(buf[0]);
- dt->tm_min = BCD2BIN(buf[1]);
- val = buf[2] & 0x3f;
- dt->tm_hour = BCD2BIN(val);
- dt->tm_wday = BCD2BIN(buf[3]) - 1;
- dt->tm_mday = BCD2BIN(buf[4]);
- val = buf[5] & 0x7f;
- dt->tm_mon = BCD2BIN(val) - 1;
- dt->tm_year = BCD2BIN(buf[6]);
- if (buf[5] & 0x80)
- dt->tm_year += 100;
-
- dev_dbg(&client->dev, "%s: secs=%d, mins=%d, "
- "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
- __FUNCTION__, dt->tm_sec, dt->tm_min,
- dt->tm_hour, dt->tm_mday,
- dt->tm_mon, dt->tm_year, dt->tm_wday);
-
- return 0;
- }
-
- dev_err(&client->dev, "error reading data! %d\n", result);
- return -EIO;
-}
-
-static int ds1337_set_datetime(struct i2c_client *client, struct rtc_time *dt)
-{
- int result;
- u8 buf[8];
- u8 val;
- struct i2c_msg msg[1];
-
- if (!dt) {
- dev_dbg(&client->dev, "%s: EINVAL: dt=NULL\n", __FUNCTION__);
- return -EINVAL;
- }
-
- dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
- "mday=%d, mon=%d, year=%d, wday=%d\n", __FUNCTION__,
- dt->tm_sec, dt->tm_min, dt->tm_hour,
- dt->tm_mday, dt->tm_mon, dt->tm_year, dt->tm_wday);
-
- buf[0] = 0; /* reg offset */
- buf[1] = BIN2BCD(dt->tm_sec);
- buf[2] = BIN2BCD(dt->tm_min);
- buf[3] = BIN2BCD(dt->tm_hour);
- buf[4] = BIN2BCD(dt->tm_wday + 1);
- buf[5] = BIN2BCD(dt->tm_mday);
- buf[6] = BIN2BCD(dt->tm_mon + 1);
- val = dt->tm_year;
- if (val >= 100) {
- val -= 100;
- buf[6] |= (1 << 7);
- }
- buf[7] = BIN2BCD(val);
-
- msg[0].addr = client->addr;
- msg[0].flags = 0;
- msg[0].len = sizeof(buf);
- msg[0].buf = &buf[0];
-
- result = i2c_transfer(client->adapter, msg, 1);
- if (result == 1)
- return 0;
-
- dev_err(&client->dev, "error writing data! %d\n", result);
- return -EIO;
-}
-
-static int ds1337_command(struct i2c_client *client, unsigned int cmd,
- void *arg)
-{
- dev_dbg(&client->dev, "%s: cmd=%d\n", __FUNCTION__, cmd);
-
- switch (cmd) {
- case DS1337_GET_DATE:
- return ds1337_get_datetime(client, arg);
-
- case DS1337_SET_DATE:
- return ds1337_set_datetime(client, arg);
-
- default:
- return -EINVAL;
- }
-}
-
-/*
- * Public API for access to specific device. Useful for low-level
- * RTC access from kernel code.
- */
-int ds1337_do_command(int bus, int cmd, void *arg)
-{
- struct list_head *walk;
- struct list_head *tmp;
- struct ds1337_data *data;
-
- list_for_each_safe(walk, tmp, &ds1337_clients) {
- data = list_entry(walk, struct ds1337_data, list);
- if (data->client.adapter->nr == bus)
- return ds1337_command(&data->client, cmd, arg);
- }
-
- return -ENODEV;
-}
-
-static int ds1337_attach_adapter(struct i2c_adapter *adapter)
-{
- return i2c_probe(adapter, &addr_data, ds1337_detect);
-}
-
-/*
- * The following function does more than just detection. If detection
- * succeeds, it also registers the new chip.
- */
-static int ds1337_detect(struct i2c_adapter *adapter, int address, int kind)
-{
- struct i2c_client *new_client;
- struct ds1337_data *data;
- int err = 0;
- const char *name = "";
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
- I2C_FUNC_I2C))
- goto exit;
-
- if (!(data = kzalloc(sizeof(struct ds1337_data), GFP_KERNEL))) {
- err = -ENOMEM;
- goto exit;
- }
- INIT_LIST_HEAD(&data->list);
-
- /* The common I2C client data is placed right before the
- * DS1337-specific data.
- */
- new_client = &data->client;
- i2c_set_clientdata(new_client, data);
- new_client->addr = address;
- new_client->adapter = adapter;
- new_client->driver = &ds1337_driver;
- new_client->flags = 0;
-
- /*
- * Now we do the remaining detection. A negative kind means that
- * the driver was loaded with no force parameter (default), so we
- * must both detect and identify the chip. A zero kind means that
- * the driver was loaded with the force parameter, the detection
- * step shall be skipped. A positive kind means that the driver
- * was loaded with the force parameter and a given kind of chip is
- * requested, so both the detection and the identification steps
- * are skipped.
- *
- * For detection, we read registers that are most likely to cause
- * detection failure, i.e. those that have more bits with fixed
- * or reserved values.
- */
-
- /* Default to an DS1337 if forced */
- if (kind == 0)
- kind = ds1337;
-
- if (kind < 0) { /* detection and identification */
- u8 data;
-
- /* Check that status register bits 6-2 are zero */
- if ((ds1337_read(new_client, DS1337_REG_STATUS, &data) < 0) ||
- (data & 0x7c))
- goto exit_free;
-
- /* Check for a valid day register value */
- if ((ds1337_read(new_client, DS1337_REG_DAY, &data) < 0) ||
- (data == 0) || (data & 0xf8))
- goto exit_free;
-
- /* Check for a valid date register value */
- if ((ds1337_read(new_client, DS1337_REG_DATE, &data) < 0) ||
- (data == 0) || (data & 0xc0) || ((data & 0x0f) > 9) ||
- (data >= 0x32))
- goto exit_free;
-
- /* Check for a valid month register value */
- if ((ds1337_read(new_client, DS1337_REG_MONTH, &data) < 0) ||
- (data == 0) || (data & 0x60) || ((data & 0x0f) > 9) ||
- ((data >= 0x13) && (data <= 0x19)))
- goto exit_free;
-
- /* Check that control register bits 6-5 are zero */
- if ((ds1337_read(new_client, DS1337_REG_CONTROL, &data) < 0) ||
- (data & 0x60))
- goto exit_free;
-
- kind = ds1337;
- }
-
- if (kind == ds1337)
- name = "ds1337";
-
- /* We can fill in the remaining client fields */
- strlcpy(new_client->name, name, I2C_NAME_SIZE);
-
- /* Tell the I2C layer a new client has arrived */
- if ((err = i2c_attach_client(new_client)))
- goto exit_free;
-
- /* Initialize the DS1337 chip */
- ds1337_init_client(new_client);
-
- /* Add client to local list */
- list_add(&data->list, &ds1337_clients);
-
- return 0;
-
-exit_free:
- kfree(data);
-exit:
- return err;
-}
-
-static void ds1337_init_client(struct i2c_client *client)
-{
- u8 status, control;
-
- /* On some boards, the RTC isn't configured by boot firmware.
- * Handle that case by starting/configuring the RTC now.
- */
- status = i2c_smbus_read_byte_data(client, DS1337_REG_STATUS);
- control = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
-
- if ((status & 0x80) || (control & 0x80)) {
- /* RTC not running */
- u8 buf[1+16]; /* First byte is interpreted as address */
- struct i2c_msg msg[1];
-
- dev_dbg(&client->dev, "%s: RTC not running!\n", __FUNCTION__);
-
- /* Initialize all, including STATUS and CONTROL to zero */
- memset(buf, 0, sizeof(buf));
-
- /* Write valid values in the date/time registers */
- buf[1+DS1337_REG_DAY] = 1;
- buf[1+DS1337_REG_DATE] = 1;
- buf[1+DS1337_REG_MONTH] = 1;
-
- msg[0].addr = client->addr;
- msg[0].flags = 0;
- msg[0].len = sizeof(buf);
- msg[0].buf = &buf[0];
-
- i2c_transfer(client->adapter, msg, 1);
- } else {
- /* Running: ensure that device is set in 24-hour mode */
- s32 val;
-
- val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR);
- if ((val >= 0) && (val & (1 << 6)))
- i2c_smbus_write_byte_data(client, DS1337_REG_HOUR,
- val & 0x3f);
- }
-}
-
-static int ds1337_detach_client(struct i2c_client *client)
-{
- int err;
- struct ds1337_data *data = i2c_get_clientdata(client);
-
- if ((err = i2c_detach_client(client)))
- return err;
-
- list_del(&data->list);
- kfree(data);
- return 0;
-}
-
-static int __init ds1337_init(void)
-{
- return i2c_add_driver(&ds1337_driver);
-}
-
-static void __exit ds1337_exit(void)
-{
- i2c_del_driver(&ds1337_driver);
-}
-
-MODULE_AUTHOR("James Chapman <jchapman@katalix.com>");
-MODULE_DESCRIPTION("DS1337 RTC driver");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL_GPL(ds1337_do_command);
-
-module_init(ds1337_init);
-module_exit(ds1337_exit);
diff --git a/drivers/i2c/chips/ds1374.c b/drivers/i2c/chips/ds1374.c
deleted file mode 100644
index 8a2ff0c..0000000
--- a/drivers/i2c/chips/ds1374.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * drivers/i2c/chips/ds1374.c
- *
- * I2C client/driver for the Maxim/Dallas DS1374 Real-Time Clock
- *
- * Author: Randy Vinson <rvinson@mvista.com>
- *
- * Based on the m41t00.c by Mark Greer <mgreer@mvista.com>
- *
- * 2005 (c) MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-/*
- * This i2c client/driver wedges between the drivers/char/genrtc.c RTC
- * interface and the SMBus interface of the i2c subsystem.
- * It would be more efficient to use i2c msgs/i2c_transfer directly but, as
- * recommened in .../Documentation/i2c/writing-clients section
- * "Sending and receiving", using SMBus level communication is preferred.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/rtc.h>
-#include <linux/bcd.h>
-#include <linux/mutex.h>
-#include <linux/workqueue.h>
-
-#define DS1374_REG_TOD0 0x00
-#define DS1374_REG_TOD1 0x01
-#define DS1374_REG_TOD2 0x02
-#define DS1374_REG_TOD3 0x03
-#define DS1374_REG_WDALM0 0x04
-#define DS1374_REG_WDALM1 0x05
-#define DS1374_REG_WDALM2 0x06
-#define DS1374_REG_CR 0x07
-#define DS1374_REG_SR 0x08
-#define DS1374_REG_SR_OSF 0x80
-#define DS1374_REG_TCR 0x09
-
-#define DS1374_DRV_NAME "ds1374"
-
-static DEFINE_MUTEX(ds1374_mutex);
-
-static struct i2c_driver ds1374_driver;
-static struct i2c_client *save_client;
-
-static unsigned short ignore[] = { I2C_CLIENT_END };
-static unsigned short normal_addr[] = { 0x68, I2C_CLIENT_END };
-
-static struct i2c_client_address_data addr_data = {
- .normal_i2c = normal_addr,
- .probe = ignore,
- .ignore = ignore,
-};
-
-static ulong ds1374_read_rtc(void)
-{
- ulong time = 0;
- int reg = DS1374_REG_WDALM0;
-
- while (reg--) {
- s32 tmp;
- if ((tmp = i2c_smbus_read_byte_data(save_client, reg)) < 0) {
- dev_warn(&save_client->dev,
- "can't read from rtc chip\n");
- return 0;
- }
- time = (time << 8) | (tmp & 0xff);
- }
- return time;
-}
-
-static void ds1374_write_rtc(ulong time)
-{
- int reg;
-
- for (reg = DS1374_REG_TOD0; reg < DS1374_REG_WDALM0; reg++) {
- if (i2c_smbus_write_byte_data(save_client, reg, time & 0xff)
- < 0) {
- dev_warn(&save_client->dev,
- "can't write to rtc chip\n");
- break;
- }
- time = time >> 8;
- }
-}
-
-static void ds1374_check_rtc_status(void)
-{
- s32 tmp;
-
- tmp = i2c_smbus_read_byte_data(save_client, DS1374_REG_SR);
- if (tmp < 0) {
- dev_warn(&save_client->dev,
- "can't read status from rtc chip\n");
- return;
- }
- if (tmp & DS1374_REG_SR_OSF) {
- dev_warn(&save_client->dev,
- "oscillator discontinuity flagged, time unreliable\n");
- tmp &= ~DS1374_REG_SR_OSF;
- tmp = i2c_smbus_write_byte_data(save_client, DS1374_REG_SR,
- tmp & 0xff);
- if (tmp < 0)
- dev_warn(&save_client->dev,
- "can't clear discontinuity notification\n");
- }
-}
-
-ulong ds1374_get_rtc_time(void)
-{
- ulong t1, t2;
- int limit = 10; /* arbitrary retry limit */
-
- mutex_lock(&ds1374_mutex);
-
- /*
- * Since the reads are being performed one byte at a time using
- * the SMBus vs a 4-byte i2c transfer, there is a chance that a
- * carry will occur during the read. To detect this, 2 reads are
- * performed and compared.
- */
- do {
- t1 = ds1374_read_rtc();
- t2 = ds1374_read_rtc();
- } while (t1 != t2 && limit--);
-
- mutex_unlock(&ds1374_mutex);
-
- if (t1 != t2) {
- dev_warn(&save_client->dev,
- "can't get consistent time from rtc chip\n");
- t1 = 0;
- }
-
- return t1;
-}
-
-static ulong new_time;
-
-static void ds1374_set_work(struct work_struct *work)
-{
- ulong t1, t2;
- int limit = 10; /* arbitrary retry limit */
-
- t1 = new_time;
-
- mutex_lock(&ds1374_mutex);
-
- /*
- * Since the writes are being performed one byte at a time using
- * the SMBus vs a 4-byte i2c transfer, there is a chance that a
- * carry will occur during the write. To detect this, the write
- * value is read back and compared.
- */
- do {
- ds1374_write_rtc(t1);
- t2 = ds1374_read_rtc();
- } while (t1 != t2 && limit--);
-
- mutex_unlock(&ds1374_mutex);
-
- if (t1 != t2)
- dev_warn(&save_client->dev,
- "can't confirm time set from rtc chip\n");
-}
-
-static struct workqueue_struct *ds1374_workqueue;
-
-static DECLARE_WORK(ds1374_work, ds1374_set_work);
-
-int ds1374_set_rtc_time(ulong nowtime)
-{
- new_time = nowtime;
-
- if (in_interrupt())
- queue_work(ds1374_workqueue, &ds1374_work);
- else
- ds1374_set_work(NULL);
-
- return 0;
-}
-
-/*
- *****************************************************************************
- *
- * Driver Interface
- *
- *****************************************************************************
- */
-static int ds1374_probe(struct i2c_adapter *adap, int addr, int kind)
-{
- struct i2c_client *client;
- int rc;
-
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
-
- strncpy(client->name, DS1374_DRV_NAME, I2C_NAME_SIZE);
- client->addr = addr;
- client->adapter = adap;
- client->driver = &ds1374_driver;
-
- ds1374_workqueue = create_singlethread_workqueue("ds1374");
- if (!ds1374_workqueue) {
- kfree(client);
- return -ENOMEM; /* most expected reason */
- }
-
- if ((rc = i2c_attach_client(client)) != 0) {
- kfree(client);
- return rc;
- }
-
- save_client = client;
-
- ds1374_check_rtc_status();
-
- return 0;
-}
-
-static int ds1374_attach(struct i2c_adapter *adap)
-{
- return i2c_probe(adap, &addr_data, ds1374_probe);
-}
-
-static int ds1374_detach(struct i2c_client *client)
-{
- int rc;
-
- if ((rc = i2c_detach_client(client)) == 0) {
- kfree(i2c_get_clientdata(client));
- destroy_workqueue(ds1374_workqueue);
- }
- return rc;
-}
-
-static struct i2c_driver ds1374_driver = {
- .driver = {
- .name = DS1374_DRV_NAME,
- },
- .id = I2C_DRIVERID_DS1374,
- .attach_adapter = ds1374_attach,
- .detach_client = ds1374_detach,
-};
-
-static int __init ds1374_init(void)
-{
- return i2c_add_driver(&ds1374_driver);
-}
-
-static void __exit ds1374_exit(void)
-{
- i2c_del_driver(&ds1374_driver);
-}
-
-module_init(ds1374_init);
-module_exit(ds1374_exit);
-
-MODULE_AUTHOR("Randy Vinson <rvinson@mvista.com>");
-MODULE_DESCRIPTION("Maxim/Dallas DS1374 RTC I2C Client Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c
deleted file mode 100644
index 3fcb646..0000000
--- a/drivers/i2c/chips/m41t00.c
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * I2C client/driver for the ST M41T00 family of i2c rtc chips.
- *
- * Author: Mark A. Greer <mgreer@mvista.com>
- *
- * 2005, 2006 (c) MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-/*
- * This i2c client/driver wedges between the drivers/char/genrtc.c RTC
- * interface and the SMBus interface of the i2c subsystem.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/rtc.h>
-#include <linux/bcd.h>
-#include <linux/workqueue.h>
-#include <linux/platform_device.h>
-#include <linux/m41t00.h>
-#include <asm/time.h>
-#include <asm/rtc.h>
-
-static struct i2c_driver m41t00_driver;
-static struct i2c_client *save_client;
-
-static unsigned short ignore[] = { I2C_CLIENT_END };
-static unsigned short normal_addr[] = { I2C_CLIENT_END, I2C_CLIENT_END };
-
-static struct i2c_client_address_data addr_data = {
- .normal_i2c = normal_addr,
- .probe = ignore,
- .ignore = ignore,
-};
-
-struct m41t00_chip_info {
- u8 type;
- char *name;
- u8 read_limit;
- u8 sec; /* Offsets for chip regs */
- u8 min;
- u8 hour;
- u8 day;
- u8 mon;
- u8 year;
- u8 alarm_mon;
- u8 alarm_hour;
- u8 sqw;
- u8 sqw_freq;
-};
-
-static struct m41t00_chip_info m41t00_chip_info_tbl[] = {
- {
- .type = M41T00_TYPE_M41T00,
- .name = "m41t00",
- .read_limit = 5,
- .sec = 0,
- .min = 1,
- .hour = 2,
- .day = 4,
- .mon = 5,
- .year = 6,
- },
- {
- .type = M41T00_TYPE_M41T81,
- .name = "m41t81",
- .read_limit = 1,
- .sec = 1,
- .min = 2,
- .hour = 3,
- .day = 5,
- .mon = 6,
- .year = 7,
- .alarm_mon = 0xa,
- .alarm_hour = 0xc,
- .sqw = 0x13,
- },
- {
- .type = M41T00_TYPE_M41T85,
- .name = "m41t85",
- .read_limit = 1,
- .sec = 1,
- .min = 2,
- .hour = 3,
- .day = 5,
- .mon = 6,
- .year = 7,
- .alarm_mon = 0xa,
- .alarm_hour = 0xc,
- .sqw = 0x13,
- },
-};
-static struct m41t00_chip_info *m41t00_chip;
-
-ulong
-m41t00_get_rtc_time(void)
-{
- s32 sec, min, hour, day, mon, year;
- s32 sec1, min1, hour1, day1, mon1, year1;
- u8 reads = 0;
- u8 buf[8], msgbuf[1] = { 0 }; /* offset into rtc's regs */
- struct i2c_msg msgs[] = {
- {
- .addr = save_client->addr,
- .flags = 0,
- .len = 1,
- .buf = msgbuf,
- },
- {
- .addr = save_client->addr,
- .flags = I2C_M_RD,
- .len = 8,
- .buf = buf,
- },
- };
-
- sec = min = hour = day = mon = year = 0;
-
- do {
- if (i2c_transfer(save_client->adapter, msgs, 2) < 0)
- goto read_err;
-
- sec1 = sec;
- min1 = min;
- hour1 = hour;
- day1 = day;
- mon1 = mon;
- year1 = year;
-
- sec = buf[m41t00_chip->sec] & 0x7f;
- min = buf[m41t00_chip->min] & 0x7f;
- hour = buf[m41t00_chip->hour] & 0x3f;
- day = buf[m41t00_chip->day] & 0x3f;
- mon = buf[m41t00_chip->mon] & 0x1f;
- year = buf[m41t00_chip->year];
- } while ((++reads < m41t00_chip->read_limit) && ((sec != sec1)
- || (min != min1) || (hour != hour1) || (day != day1)
- || (mon != mon1) || (year != year1)));
-
- if ((m41t00_chip->read_limit > 1) && ((sec != sec1) || (min != min1)
- || (hour != hour1) || (day != day1) || (mon != mon1)
- || (year != year1)))
- goto read_err;
-
- sec = BCD2BIN(sec);
- min = BCD2BIN(min);
- hour = BCD2BIN(hour);
- day = BCD2BIN(day);
- mon = BCD2BIN(mon);
- year = BCD2BIN(year);
-
- year += 1900;
- if (year < 1970)
- year += 100;
-
- return mktime(year, mon, day, hour, min, sec);
-
-read_err:
- dev_err(&save_client->dev, "m41t00_get_rtc_time: Read error\n");
- return 0;
-}
-EXPORT_SYMBOL_GPL(m41t00_get_rtc_time);
-
-static void
-m41t00_set(void *arg)
-{
- struct rtc_time tm;
- int nowtime = *(int *)arg;
- s32 sec, min, hour, day, mon, year;
- u8 wbuf[9], *buf = &wbuf[1], msgbuf[1] = { 0 };
- struct i2c_msg msgs[] = {
- {
- .addr = save_client->addr,
- .flags = 0,
- .len = 1,
- .buf = msgbuf,
- },
- {
- .addr = save_client->addr,
- .flags = I2C_M_RD,
- .len = 8,
- .buf = buf,
- },
- };
-
- to_tm(nowtime, &tm);
- tm.tm_year = (tm.tm_year - 1900) % 100;
-
- sec = BIN2BCD(tm.tm_sec);
- min = BIN2BCD(tm.tm_min);
- hour = BIN2BCD(tm.tm_hour);
- day = BIN2BCD(tm.tm_mday);
- mon = BIN2BCD(tm.tm_mon);
- year = BIN2BCD(tm.tm_year);
-
- /* Read reg values into buf[0..7]/wbuf[1..8] */
- if (i2c_transfer(save_client->adapter, msgs, 2) < 0) {
- dev_err(&save_client->dev, "m41t00_set: Read error\n");
- return;
- }
-
- wbuf[0] = 0; /* offset into rtc's regs */
- buf[m41t00_chip->sec] = (buf[m41t00_chip->sec] & ~0x7f) | (sec & 0x7f);
- buf[m41t00_chip->min] = (buf[m41t00_chip->min] & ~0x7f) | (min & 0x7f);
- buf[m41t00_chip->hour] = (buf[m41t00_chip->hour] & ~0x3f) | (hour& 0x3f);
- buf[m41t00_chip->day] = (buf[m41t00_chip->day] & ~0x3f) | (day & 0x3f);
- buf[m41t00_chip->mon] = (buf[m41t00_chip->mon] & ~0x1f) | (mon & 0x1f);
- buf[m41t00_chip->year] = year;
-
- if (i2c_master_send(save_client, wbuf, 9) < 0)
- dev_err(&save_client->dev, "m41t00_set: Write error\n");
-}
-
-static ulong new_time;
-/* well, isn't this API just _lovely_? */
-static void
-m41t00_barf(struct work_struct *unusable)
-{
- m41t00_set(&new_time);
-}
-
-static struct workqueue_struct *m41t00_wq;
-static DECLARE_WORK(m41t00_work, m41t00_barf);
-
-int
-m41t00_set_rtc_time(ulong nowtime)
-{
- new_time = nowtime;
-
- if (in_interrupt())
- queue_work(m41t00_wq, &m41t00_work);
- else
- m41t00_set(&new_time);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(m41t00_set_rtc_time);
-
-/*
- *****************************************************************************
- *
- * platform_data Driver Interface
- *
- *****************************************************************************
- */
-static int __init
-m41t00_platform_probe(struct platform_device *pdev)
-{
- struct m41t00_platform_data *pdata;
- int i;
-
- if (pdev && (pdata = pdev->dev.platform_data)) {
- normal_addr[0] = pdata->i2c_addr;
-
- for (i=0; i<ARRAY_SIZE(m41t00_chip_info_tbl); i++)
- if (m41t00_chip_info_tbl[i].type == pdata->type) {
- m41t00_chip = &m41t00_chip_info_tbl[i];
- m41t00_chip->sqw_freq = pdata->sqw_freq;
- return 0;
- }
- }
- return -ENODEV;
-}
-
-static int __exit
-m41t00_platform_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
-static struct platform_driver m41t00_platform_driver = {
- .probe = m41t00_platform_probe,
- .remove = m41t00_platform_remove,
- .driver = {
- .owner = THIS_MODULE,
- .name = M41T00_DRV_NAME,
- },
-};
-
-/*
- *****************************************************************************
- *
- * Driver Interface
- *
- *****************************************************************************
- */
-static int
-m41t00_probe(struct i2c_adapter *adap, int addr, int kind)
-{
- struct i2c_client *client;
- int rc;
-
- if (!i2c_check_functionality(adap, I2C_FUNC_I2C
- | I2C_FUNC_SMBUS_BYTE_DATA))
- return 0;
-
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
-
- strlcpy(client->name, m41t00_chip->name, I2C_NAME_SIZE);
- client->addr = addr;
- client->adapter = adap;
- client->driver = &m41t00_driver;
-
- if ((rc = i2c_attach_client(client)))
- goto attach_err;
-
- if (m41t00_chip->type != M41T00_TYPE_M41T00) {
- /* If asked, disable SQW, set SQW frequency & re-enable */
- if (m41t00_chip->sqw_freq)
- if (((rc = i2c_smbus_read_byte_data(client,
- m41t00_chip->alarm_mon)) < 0)
- || ((rc = i2c_smbus_write_byte_data(client,
- m41t00_chip->alarm_mon, rc & ~0x40)) <0)
- || ((rc = i2c_smbus_write_byte_data(client,
- m41t00_chip->sqw,
- m41t00_chip->sqw_freq)) < 0)
- || ((rc = i2c_smbus_write_byte_data(client,
- m41t00_chip->alarm_mon, rc | 0x40)) <0))
- goto sqw_err;
-
- /* Make sure HT (Halt Update) bit is cleared */
- if ((rc = i2c_smbus_read_byte_data(client,
- m41t00_chip->alarm_hour)) < 0)
- goto ht_err;
-
- if (rc & 0x40)
- if ((rc = i2c_smbus_write_byte_data(client,
- m41t00_chip->alarm_hour, rc & ~0x40))<0)
- goto ht_err;
- }
-
- /* Make sure ST (stop) bit is cleared */
- if ((rc = i2c_smbus_read_byte_data(client, m41t00_chip->sec)) < 0)
- goto st_err;
-
- if (rc & 0x80)
- if ((rc = i2c_smbus_write_byte_data(client, m41t00_chip->sec,
- rc & ~0x80)) < 0)
- goto st_err;
-
- m41t00_wq = create_singlethread_workqueue(m41t00_chip->name);
- save_client = client;
- return 0;
-
-st_err:
- dev_err(&client->dev, "m41t00_probe: Can't clear ST bit\n");
- goto attach_err;
-ht_err:
- dev_err(&client->dev, "m41t00_probe: Can't clear HT bit\n");
- goto attach_err;
-sqw_err:
- dev_err(&client->dev, "m41t00_probe: Can't set SQW Frequency\n");
-attach_err:
- kfree(client);
- return rc;
-}
-
-static int
-m41t00_attach(struct i2c_adapter *adap)
-{
- return i2c_probe(adap, &addr_data, m41t00_probe);
-}
-
-static int
-m41t00_detach(struct i2c_client *client)
-{
- int rc;
-
- if ((rc = i2c_detach_client(client)) == 0) {
- kfree(client);
- destroy_workqueue(m41t00_wq);
- }
- return rc;
-}
-
-static struct i2c_driver m41t00_driver = {
- .driver = {
- .name = M41T00_DRV_NAME,
- },
- .id = I2C_DRIVERID_STM41T00,
- .attach_adapter = m41t00_attach,
- .detach_client = m41t00_detach,
-};
-
-static int __init
-m41t00_init(void)
-{
- int rc;
-
- if (!(rc = platform_driver_register(&m41t00_platform_driver)))
- rc = i2c_add_driver(&m41t00_driver);
- return rc;
-}
-
-static void __exit
-m41t00_exit(void)
-{
- i2c_del_driver(&m41t00_driver);
- platform_driver_unregister(&m41t00_platform_driver);
-}
-
-module_init(m41t00_init);
-module_exit(m41t00_exit);
-
-MODULE_AUTHOR("Mark A. Greer <mgreer@mvista.com>");
-MODULE_DESCRIPTION("ST Microelectronics M41T00 RTC I2C Client Driver");
-MODULE_LICENSE("GPL");
diff --git a/include/linux/m41t00.h b/include/linux/m41t00.h
deleted file mode 100644
index b423360..0000000
--- a/include/linux/m41t00.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Definitions for the ST M41T00 family of i2c rtc chips.
- *
- * Author: Mark A. Greer <mgreer@mvista.com>
- *
- * 2005, 2006 (c) MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-
-#ifndef _M41T00_H
-#define _M41T00_H
-
-#define M41T00_DRV_NAME "m41t00"
-#define M41T00_I2C_ADDR 0x68
-
-#define M41T00_TYPE_M41T00 0
-#define M41T00_TYPE_M41T81 81
-#define M41T00_TYPE_M41T85 85
-
-struct m41t00_platform_data {
- u8 type;
- u8 i2c_addr;
- u8 sqw_freq;
-};
-
-/* SQW output disabled, this is default value by power on */
-#define M41T00_SQW_DISABLE (0)
-
-#define M41T00_SQW_32KHZ (1<<4) /* 32.768 KHz */
-#define M41T00_SQW_8KHZ (2<<4) /* 8.192 KHz */
-#define M41T00_SQW_4KHZ (3<<4) /* 4.096 KHz */
-#define M41T00_SQW_2KHZ (4<<4) /* 2.048 KHz */
-#define M41T00_SQW_1KHZ (5<<4) /* 1.024 KHz */
-#define M41T00_SQW_512HZ (6<<4) /* 512 Hz */
-#define M41T00_SQW_256HZ (7<<4) /* 256 Hz */
-#define M41T00_SQW_128HZ (8<<4) /* 128 Hz */
-#define M41T00_SQW_64HZ (9<<4) /* 64 Hz */
-#define M41T00_SQW_32HZ (10<<4) /* 32 Hz */
-#define M41T00_SQW_16HZ (11<<4) /* 16 Hz */
-#define M41T00_SQW_8HZ (12<<4) /* 8 Hz */
-#define M41T00_SQW_4HZ (13<<4) /* 4 Hz */
-#define M41T00_SQW_2HZ (14<<4) /* 2 Hz */
-#define M41T00_SQW_1HZ (15<<4) /* 1 Hz */
-
-extern ulong m41t00_get_rtc_time(void);
-extern int m41t00_set_rtc_time(ulong nowtime);
-
-#endif /* _M41T00_H */
^ permalink raw reply related
* Re: libfdt as its own repo and submodule of dtc?
From: David Gibson @ 2007-10-31 22:56 UTC (permalink / raw)
To: Kumar Gala; +Cc: linux-ppc list, Jon Loeliger, Jerry Van Baren
In-Reply-To: <F940E9CC-1F15-4EC5-94DC-A600FD702380@kernel.crashing.org>
On Thu, Nov 01, 2007 at 01:55:30AM -0500, Kumar Gala wrote:
>
> On Oct 30, 2007, at 6:40 PM, David Gibson wrote:
>
> > On Tue, Oct 30, 2007 at 01:14:06PM -0400, Jerry Van Baren wrote:
> >> Jon Loeliger wrote:
> >>> So, like, the other day Kumar Gala mumbled:
> >>>> Jon,
> >>>>
> >>>> It seems like have libfdt as a unique git repo that is a
> >>>> submodule of
> >>>> the things that need it (dtc, u-boot, etc.) might make some
> >>>> sense and it
> >>>> easier for the projects that need to pull it in.
> >>>>
> >>>> Is this something you can take a look at? (or have other ideas on).
> >>> I would be fine with making libfdt a git repository separate
> >>> from the DTC repository if that makes it easier to integrate
> >>> it with other projects.
> >
> > I don't think it's a good idea to make dtc and libfdt entirely
> > seperate repositories (again). Being able to use both together in
> > their combined testsuite is very useful (libfdt is used to check trees
> > generated by dtc, dtc is used to generate example trees for libfdt
> > testing).
> >
> > I'm not sure how submodules/subrepositories work so I don't know if
> > that makes sense.
>
> I believe submodules will accomplish this (at least from what I can
> tell).
I'm not too keen on using a git feature that's more recent than the
git in most distros.
--
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: RFC: replace device_type with new "class" property?
From: David Gibson @ 2007-10-31 22:55 UTC (permalink / raw)
To: Yoder Stuart-B08248; +Cc: Olof Johansson, linuxppc-dev
In-Reply-To: <9696D7A991D0824DBA8DFAC74A9C5FA3035F2AC3@az33exm25.fsl.freescale.net>
On Wed, Oct 31, 2007 at 08:31:02AM -0700, Yoder Stuart-B08248 wrote:
>
> > > I think what we should do is keep device_type, including
> > > permitting new uses of it in a limited way-- only permitting
> > > the use of device_type when there is an official binding
> > > (like in the power.org ePAPR) defined.
> >
> > That's what I was thinking when we first started defining flat tree
> > bindings. But the more time I've spent thinking about it, and the
> > more time I've spent reviewing people's proposed bindings, the less
> > useful I think it is.
> >
> > The *only* reason I'm suggesting leaving device_type values for
> > IEEE1275 defined classes is so that flat trees written as flat trees
> > look more similar to OF derived trees.
> >
> > > > Explicitly specifying what device class bindings / conventions the
> > > > node complies with is cute, but not actually all that useful in
> > > > practice. If it looks like a "duck" class device node, and it
> > > > quacks^Whas the properties of a "duck" class device node,
> > it's "duck"
> > > > class compliant.
> > > >
> > > > Or to look at it another way, "class bindings" aren't
> > really bindings,
> > > > but rather a set of conventions that device bindings for specific
> > > > devices in that class ought to follow.
> > >
> > > I tend to think of a 'binding' as a 'set of conventions'.
> >
> > Well, whatever. My point is that conventions are most flexible if you
> > don't have to explicitly announce that you're following them - you
> > just go ahead and follow as many conventions as make sense for your
> > device.
>
> Let me repeat what I think you are advocating-- we should
> treat the collection of properties for 'established' device
> classes like like "network", "serial", etc as a set of useful
> conventions. That is, there are no set of _required_ properties
> per se, but the device tree creator picks from the established
> properties plus supplementing with "company,xyz" properties
> in whatever way they think makes sense for them.
Not the device tree creater, the device binding creator (though for
"one-off" type devices those may be the same person).
> This works...but certainly is weaker with respect to
> standardization. My previous argument had the assumption
> that something like "mac-address" in a network node was
> _required_, and thus needed a class id of some sort to tie
> the standardized node to.
Not for a network device type that represented a point-to-point link..
(Well, technically most nodes should lack 'mac-address', but I think
'local-mac-address' is what you meant)
> If we relax things so there are no required properties for
> device nodes, then I agree that a device class property
> has limited or no value.
There are required properties, but the requrements are done at the
device binding (i.e. compatible property) level. Those bindings might
in turn reference class requirements ("A foobaz-ethernet node must
have all the standard properties for a network node described in
Sx.y.z, and in addition must have foobaz,frobnication-quotient").
> However, maybe we do want to keep device_type in
> a very limited way to define requirements for what you
> call 'fundamental' types of nodes. It may be that certain
> properties in a "cpu" node (like cache-size?) should be
> _required_ so that an OS that consumes the device tree
> can really count on certain properties being there. Or,
> I guess we could use "compatible" for that...?
No, I'm saying keep device_type for cpu and memory - we could do
otherwise but it would be a gratuitous divergence from OF trees. And
yes they should have their required properties, too.
--
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
* [patch 05/28] Add cmpxchg64 and cmpxchg64_local to powerpc
From: Mathieu Desnoyers @ 2007-10-31 22:37 UTC (permalink / raw)
To: akpm, linux-kernel; +Cc: Paul Mackerras, Mathieu Desnoyers, linuxppc-dev
In-Reply-To: <20071031223710.099558229@polymtl.ca>
Make sure that at least cmpxchg64_local is available on all architectures to use
for unsigned long long values.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Acked-by: Paul Mackerras <paulus@samba.org>
CC: linuxppc-dev@ozlabs.org
---
include/asm-powerpc/system.h | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
Index: linux-2.6-lttng/include/asm-powerpc/system.h
===================================================================
--- linux-2.6-lttng.orig/include/asm-powerpc/system.h 2007-10-31 17:32:44.000000000 -0400
+++ linux-2.6-lttng/include/asm-powerpc/system.h 2007-10-31 17:56:25.000000000 -0400
@@ -461,7 +461,7 @@ __cmpxchg_local(volatile void *ptr, unsi
return old;
}
-#define cmpxchg(ptr,o,n) \
+#define cmpxchg(ptr, o, n) \
({ \
__typeof__(*(ptr)) _o_ = (o); \
__typeof__(*(ptr)) _n_ = (n); \
@@ -470,7 +470,7 @@ __cmpxchg_local(volatile void *ptr, unsi
})
-#define cmpxchg_local(ptr,o,n) \
+#define cmpxchg_local(ptr, o, n) \
({ \
__typeof__(*(ptr)) _o_ = (o); \
__typeof__(*(ptr)) _n_ = (n); \
@@ -490,6 +490,20 @@ __cmpxchg_local(volatile void *ptr, unsi
*/
#define NET_IP_ALIGN 0
#define NET_SKB_PAD L1_CACHE_BYTES
+
+#define cmpxchg64(ptr, o, n) \
+ ({ \
+ BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
+ cmpxchg((ptr), (o), (n)); \
+ })
+#define cmpxchg64_local(ptr, o, n) \
+ ({ \
+ BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
+ cmpxchg_local((ptr), (o), (n)); \
+ })
+#else
+#include <asm-generic/cmpxchg-local.h>
+#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
#endif
#define arch_align_stack(x) (x)
--
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
^ permalink raw reply
* Re: [PATCH] ucc_geth: add support for netpoll
From: Anton Vorontsov @ 2007-10-31 21:59 UTC (permalink / raw)
To: Li Yang-r58472; +Cc: netdev, linux-kernel, linuxppc-dev
In-Reply-To: <20071029121744.GA20372@localhost.localdomain>
On Mon, Oct 29, 2007 at 03:17:44PM +0300, Anton Vorontsov wrote:
[...]
> > Oops. The original patch happened to hit the Junk mail box. :(
>
> That one as well? http://lkml.org/lkml/2007/10/11/128
>
> > I think
> > the patch is good to merge after the cosmetic change. I can do it in
> > next pull request to Jeff.
>
> Ok, great. Thanks.
I'm wondering if you missed that email again. Maybe your mail
client/server doing weird things with emails from @ru.mvista.com?
Thanks.
> Here it is:
>
> - - - -
> From: Anton Vorontsov <avorontsov@ru.mvista.com>
> Subject: [PATCH] ucc_geth: add support for netpoll
>
> This patch adds netpoll support for the QE UCC Gigabit Ethernet
> driver. Tested using netconsole and KGDBoE.
>
> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
> ---
> drivers/net/ucc_geth.c | 20 ++++++++++++++++++++
> 1 files changed, 20 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
> index bec413b..94e78d8 100644
> --- a/drivers/net/ucc_geth.c
> +++ b/drivers/net/ucc_geth.c
> @@ -3678,6 +3678,23 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
> return IRQ_HANDLED;
> }
>
> +#ifdef CONFIG_NET_POLL_CONTROLLER
> +/*
> + * Polling 'interrupt' - used by things like netconsole to send skbs
> + * without having to re-enable interrupts. It's not called while
> + * the interrupt routine is executing.
> + */
> +static void ucc_netpoll(struct net_device *dev)
> +{
> + struct ucc_geth_private *ugeth = netdev_priv(dev);
> + int irq = ugeth->ug_info->uf_info.irq;
> +
> + disable_irq(irq);
> + ucc_geth_irq_handler(irq, dev);
> + enable_irq(irq);
> +}
> +#endif /* CONFIG_NET_POLL_CONTROLLER */
> +
> /* Called when something needs to use the ethernet device */
> /* Returns 0 for success. */
> static int ucc_geth_open(struct net_device *dev)
> @@ -3963,6 +3980,9 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
> #ifdef CONFIG_UGETH_NAPI
> netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, UCC_GETH_DEV_WEIGHT);
> #endif /* CONFIG_UGETH_NAPI */
> +#ifdef CONFIG_NET_POLL_CONTROLLER
> + dev->poll_controller = ucc_netpoll;
> +#endif
> dev->stop = ucc_geth_close;
> // dev->change_mtu = ucc_geth_change_mtu;
> dev->mtu = 1500;
> --
> 1.5.2.2
--
Anton Vorontsov
email: cbou@mail.ru
backup email: ya-cbou@yandex.ru
irc://irc.freenode.net/bd2
^ permalink raw reply
* Re: [PATCH 1/3] Add remove_memory() for ppc64
From: Dave Hansen @ 2007-10-31 21:55 UTC (permalink / raw)
To: Badari Pulavarty
Cc: linux-mm, anton, linuxppc-dev, Paul Mackerras, Andrew Morton,
KAMEZAWA Hiroyuki
In-Reply-To: <1193868715.17412.55.camel@dyn9047017100.beaverton.ibm.com>
On Wed, 2007-10-31 at 14:11 -0800, Badari Pulavarty wrote:
>
> Well, We don't need arch-specific remove_memory() for ia64 and ppc64.
> x86_64, I don't know. We will know, only when some one does the
> verification. I don't need arch_remove_memory() hook also at this
> time.
I wasn't being very clear. I say, add the arch hook only if you need
it. But, for now, just take the ia64 code and make it generic.
-- Dave
^ permalink raw reply
* Re: [PATCH 1/3] Add remove_memory() for ppc64
From: Dale Farnsworth @ 2007-10-31 21:47 UTC (permalink / raw)
To: pbadari; +Cc: linuxppc-dev
In-Reply-To: <1193867133.17412.49.camel@dyn9047017100.beaverton.ibm.com>
Badari Pulavarty wrote:
> On Thu, 2007-11-01 at 01:26 -0500, Kumar Gala wrote:
> > On Oct 31, 2007, at 11:49 AM, Badari Pulavarty wrote:
> >
> > > Supply arch specific remove_memory() for PPC64. There is nothing
> > > ppc specific code here and its exactly same as ia64 version.
> > > For now, lets keep it arch specific - so each arch can add
> > > its own special things if needed.
> > >
> > > Signed-off-by: Badari Pulavarty <pbadari@us.ibm.com>
> > > ---
> >
> > What's ppc64 specific about these patches?
>
> Like I mentioned, nothing. When KAME did the hotplug memory
> remove, he kept this remove_memory() arch-specific - so
> each arch can provide its own, if it needs to something
> special. So far, there is no need for arch-specific
> remove_memory(). If other archs (x86-64 and others)
> agree we can merge this into arch neutral code.
>
> I have to provide this for ppc64 to plug into general
> frame work.
You've added it to arch/powerpc for both PPC32 and PPC64, so your
commit description is misleading.
-Dale
^ permalink raw reply
* Re: [PATCH 1/3] Add remove_memory() for ppc64
From: Badari Pulavarty @ 2007-10-31 22:13 UTC (permalink / raw)
To: Dave Hansen
Cc: linux-mm, anton, linuxppc-dev, Paul Mackerras, Andrew Morton,
KAMEZAWA Hiroyuki
In-Reply-To: <1193863502.6271.38.camel@localhost>
On Wed, 2007-10-31 at 13:45 -0700, Dave Hansen wrote:
> On Wed, 2007-10-31 at 08:49 -0800, Badari Pulavarty wrote:
> > +#ifdef CONFIG_MEMORY_HOTREMOVE
> > +int remove_memory(u64 start, u64 size)
> > +{
> > + unsigned long start_pfn, end_pfn;
> > + unsigned long timeout = 120 * HZ;
> > + int ret;
> > + start_pfn = start >> PAGE_SHIFT;
> > + end_pfn = start_pfn + (size >> PAGE_SHIFT);
> > + ret = offline_pages(start_pfn, end_pfn, timeout);
> > + return ret;
> > +}
> > +EXPORT_SYMBOL_GPL(remove_memory);
> > +#endif /* CONFIG_MEMORY_HOTREMOVE */
>
> Did someone go and copy the ia64 verion? Tsk. Tsk. Bad Badari. :)
>
> Can we just make this a weak symbol in the generic mm/memory_hotplug.c?
> Or, make this the generic memory_remove() function int there and have an
> arch_remove_memory() hook called from there if the architectures need to
> tweak it?
BTW, we do have generic remove_memory() which returns -EINVAL, if
CONFIG_HOTPLUG_MEMORY_REMOVE is not set to cover all the arch
that doesn't support it.
Thanks,
Badari
^ permalink raw reply
* Re: [PATCH 1/3] Add remove_memory() for ppc64
From: Badari Pulavarty @ 2007-10-31 22:11 UTC (permalink / raw)
To: Dave Hansen
Cc: linux-mm, anton, linuxppc-dev, Paul Mackerras, Andrew Morton,
KAMEZAWA Hiroyuki
In-Reply-To: <1193863502.6271.38.camel@localhost>
On Wed, 2007-10-31 at 13:45 -0700, Dave Hansen wrote:
> On Wed, 2007-10-31 at 08:49 -0800, Badari Pulavarty wrote:
> > +#ifdef CONFIG_MEMORY_HOTREMOVE
> > +int remove_memory(u64 start, u64 size)
> > +{
> > + unsigned long start_pfn, end_pfn;
> > + unsigned long timeout = 120 * HZ;
> > + int ret;
> > + start_pfn = start >> PAGE_SHIFT;
> > + end_pfn = start_pfn + (size >> PAGE_SHIFT);
> > + ret = offline_pages(start_pfn, end_pfn, timeout);
> > + return ret;
> > +}
> > +EXPORT_SYMBOL_GPL(remove_memory);
> > +#endif /* CONFIG_MEMORY_HOTREMOVE */
>
> Did someone go and copy the ia64 verion? Tsk. Tsk. Bad Badari. :)
>
> Can we just make this a weak symbol in the generic mm/memory_hotplug.c?
> Or, make this the generic memory_remove() function int there and have an
> arch_remove_memory() hook called from there if the architectures need to
> tweak it?
Well, We don't need arch-specific remove_memory() for ia64 and ppc64.
x86_64, I don't know. We will know, only when some one does the
verification. I don't need arch_remove_memory() hook also at this time.
KAME and I agreed that, we will kill all this if no arch needs it (after
verifying it with x86/x86-64). No point adding all the infrastructure,
if no one needs it at the end.
Thanks,
Badari
^ permalink raw reply
* Re: [PATCH 1/3] Add remove_memory() for ppc64
From: Dave Hansen @ 2007-10-31 20:45 UTC (permalink / raw)
To: Badari Pulavarty
Cc: linux-mm, anton, linuxppc-dev, Paul Mackerras, Andrew Morton,
KAMEZAWA Hiroyuki
In-Reply-To: <1193849375.17412.34.camel@dyn9047017100.beaverton.ibm.com>
On Wed, 2007-10-31 at 08:49 -0800, Badari Pulavarty wrote:
> +#ifdef CONFIG_MEMORY_HOTREMOVE
> +int remove_memory(u64 start, u64 size)
> +{
> + unsigned long start_pfn, end_pfn;
> + unsigned long timeout = 120 * HZ;
> + int ret;
> + start_pfn = start >> PAGE_SHIFT;
> + end_pfn = start_pfn + (size >> PAGE_SHIFT);
> + ret = offline_pages(start_pfn, end_pfn, timeout);
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(remove_memory);
> +#endif /* CONFIG_MEMORY_HOTREMOVE */
Did someone go and copy the ia64 verion? Tsk. Tsk. Bad Badari. :)
Can we just make this a weak symbol in the generic mm/memory_hotplug.c?
Or, make this the generic memory_remove() function int there and have an
arch_remove_memory() hook called from there if the architectures need to
tweak it?
-- Dave
^ permalink raw reply
* Re: [PATCH 1/3] Add remove_memory() for ppc64
From: Badari Pulavarty @ 2007-10-31 21:45 UTC (permalink / raw)
To: Kumar Gala
Cc: linux-mm, anton, linuxppc-dev, Paul Mackerras, Andrew Morton,
KAMEZAWA Hiroyuki
In-Reply-To: <46434BBD-7656-41B1-BED0-3A3E212032B5@kernel.crashing.org>
On Thu, 2007-11-01 at 01:26 -0500, Kumar Gala wrote:
> On Oct 31, 2007, at 11:49 AM, Badari Pulavarty wrote:
>
> > Supply arch specific remove_memory() for PPC64. There is nothing
> > ppc specific code here and its exactly same as ia64 version.
> > For now, lets keep it arch specific - so each arch can add
> > its own special things if needed.
> >
> > Signed-off-by: Badari Pulavarty <pbadari@us.ibm.com>
> > ---
>
> What's ppc64 specific about these patches?
Like I mentioned, nothing. When KAME did the hotplug memory
remove, he kept this remove_memory() arch-specific - so
each arch can provide its own, if it needs to something
special. So far, there is no need for arch-specific
remove_memory(). If other archs (x86-64 and others)
agree we can merge this into arch neutral code.
I have to provide this for ppc64 to plug into general
frame work.
Thanks,
Badari
^ permalink raw reply
* Re: reboot of mpc8270 sometimes fails
From: Matvejchikov Ilya @ 2007-10-31 20:14 UTC (permalink / raw)
To: linuxppc-embedded, Theo Gjaltema
Hi!
I thik that m8260_restart in 2.4 kernel is broken. Try to get it from
the 2.6 kernel, or look at this.
/* The 8260 has an internal 1-second timer update register that
@@ -112,21 +123,16 @@ m8260_get_rtc_time(void)
static void
m8260_restart(char *cmd)
{
- extern void m8260_gorom(bd_t *bi, uint addr);
- uint startaddr;
-
- /* Most boot roms have a warmstart as the second instruction
- * of the reset vector. If that doesn't work for you, change this
- * or the reboot program to send a proper address.
- */
- startaddr = 0xff000104;
-
- if (cmd != NULL) {
- if (!strncmp(cmd, "startaddr=", 10))
- startaddr = simple_strtoul(&cmd[10], NULL, 0);
- }
-
- m8260_gorom((unsigned int)__pa(__res), startaddr);
+ __volatile__ unsigned char dummy;
+
+ local_irq_disable();
+ ((cpm2_map_t *) cpm2_immr)->im_clkrst.car_rmr |= 0x00000001;
+
+ /* Clear the ME,EE,IR & DR bits in MSR to cause checkstop */
+ mtmsr(mfmsr() & ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR));
+ dummy = ((cpm2_map_t *) cpm2_immr)->im_clkrst.res[0];
+ printk("Restart failed\n");
+ while (1) ;
}
^ permalink raw reply
* question on modifying pte entries
From: Chris Friesen @ 2007-10-31 19:45 UTC (permalink / raw)
To: linuxppc-dev
Hi all,
We've got some kernel code that monitors which pages have been dirtied
by an application.
The pages are locked in memory, and the system has no swap. Initially
we mark the pages clean using ptep_clear_flush_dirty(), then when
requested by the app we scanning through the pages and check the dirty
bit using pte_dirty(). If it's dirty we store the address and then mark
it clean using the same function as above. The above is all done while
holding both mm->mmap_sem and mm->page_table_lock.
This worked fine in 2.6.10 but now in 2.6.14 it's giving us problems.
Periodically we'll get a page that we know has been dirtied, but it
doesn't get detected as such. It appears that once this occurs, that
page will never again be detected as dirty.
Does anyone have any ideas what may be happening? Were there any
changes in the page table area other than moving to 4-level mappings?
Anyone aware of any missing tlb flushes that were fixed later?
Thanks,
Chris
^ permalink raw reply
* Re: Too many spurious interrupts on mpc82xx with linux-2.4.35.5
From: Matvejchikov Ilya @ 2007-10-31 19:49 UTC (permalink / raw)
To: Theo Gjaltema; +Cc: linuxppc-embedded
In-Reply-To: <4728C35B.7000709@chello.nl>
I'm glad to hear it! :)
2007/10/31, Theo Gjaltema <gjalt007@chello.nl>:
> Matvejchikov,
>
> I've tried this on 2.4.25 kernel from the denx eldk3.1.1 distribution
> and it works here fine as well.
> Thanks,
> Theo.
>
> Matvejchikov Ilya schreef:
> > Hi all!
> >
> > If you still have this problem, try this patch. It helps :)
> >
> > Signed-off-by : Matvejchikov Ilya <matvejchikov@gmail.com>
> > ---
> > diff -purN linux-2.4.34.5-vanilla/arch/ppc/kernel/cpm2_pic.c
> > linux-2.4.34.5/arch/ppc/kernel/cpm2_pic.c
> > --- linux-2.4.34.5-vanilla/arch/ppc/kernel/cpm2_pic.c 2007-06-06
> > 23:20:53.000000000 +0400
> > +++ linux-2.4.34.5/arch/ppc/kernel/cpm2_pic.c 2007-06-28
> > 12:17:42.000000000 +0400
> > @@ -79,6 +79,12 @@ static void cpm2_mask_and_ack(unsigned i
> > ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
> > simr[word] = ppc_cached_irq_mask[word];
> > sipnr[word] = 1 << (31 - bit);
> > +
> > + /*
> > + * Work around large numbers of spurious IRQs on PowerPC 82xx
> > + * systems.
> > + */
> > + mb();
> > }
> >
> > static void cpm2_end_irq(unsigned int irq_nr)
> > _______________________________________________
> > Linuxppc-embedded mailing list
> > Linuxppc-embedded@ozlabs.org
> > https://ozlabs.org/mailman/listinfo/linuxppc-embedded
> >
> >
>
>
^ permalink raw reply
* Re: [PATCH] ehea: add kexec support
From: Christoph Raisch @ 2007-10-31 19:48 UTC (permalink / raw)
To: michael
Cc: Thomas Q Klein, ossthema, Jeff Garzik, Jan-Bernd Themann, netdev,
linux-kernel, linux-ppc, Marcus Eder, Stefan Roscher
In-Reply-To: <1193784636.32504.4.camel@concordia>
Michael Ellerman <michael@ellerman.id.au> wrote on 30.10.2007 23:50:36:
>
> On Tue, 2007-10-30 at 09:39 +0100, Christoph Raisch wrote:
> >
> > Michael Ellerman <michael@ellerman.id.au> wrote on 28.10.2007 23:32:17:
> > Hope I didn't miss anything here...
>
> Perhaps. When we kdump the kernel does not call the reboot notifiers, so
> the code Jan-Bernd just added won't get called. So the eHEA resources
> won't be freed. When the kdump kernel tries to load the eHEA driver what
> will happen?
>
Good point.
If the device driver tries to allocate resources again (in the kdump
kernel),
which have been allocated before (in the crashed kernel) the hcalls will
fail because from the hypervisor view the resources are still in use.
Currently there's no method to find out the resource handles for these
HEA resources allocated by the crashed kernel within the hypervisor...
So we have to trigger a explicit deregister in the hypervisor before the
driver
is started again.
How do you recommend we should trigger this in the kdump process?
Is placing a hook into a ppc_md.machine_kexec be an option?
Gruss / Regards
Christoph R.
^ permalink raw reply
* Re: libfdt as its own repo and submodule of dtc?
From: Kumar Gala @ 2007-11-01 6:55 UTC (permalink / raw)
To: David Gibson; +Cc: linux-ppc list, Jon Loeliger, Jerry Van Baren
In-Reply-To: <20071030234011.GE2784@localhost.localdomain>
On Oct 30, 2007, at 6:40 PM, David Gibson wrote:
> On Tue, Oct 30, 2007 at 01:14:06PM -0400, Jerry Van Baren wrote:
>> Jon Loeliger wrote:
>>> So, like, the other day Kumar Gala mumbled:
>>>> Jon,
>>>>
>>>> It seems like have libfdt as a unique git repo that is a
>>>> submodule of
>>>> the things that need it (dtc, u-boot, etc.) might make some
>>>> sense and it
>>>> easier for the projects that need to pull it in.
>>>>
>>>> Is this something you can take a look at? (or have other ideas on).
>>> I would be fine with making libfdt a git repository separate
>>> from the DTC repository if that makes it easier to integrate
>>> it with other projects.
>
> I don't think it's a good idea to make dtc and libfdt entirely
> seperate repositories (again). Being able to use both together in
> their combined testsuite is very useful (libfdt is used to check trees
> generated by dtc, dtc is used to generate example trees for libfdt
> testing).
>
> I'm not sure how submodules/subrepositories work so I don't know if
> that makes sense.
I believe submodules will accomplish this (at least from what I can
tell).
- k
^ 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