* Re: [PATCH 04/28] Add early debug console for CPM serial ports.
From: David Gibson @ 2007-09-19 3:10 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20070917165733.GD6563@loki.buserror.net>
On Mon, Sep 17, 2007 at 11:57:33AM -0500, Scott Wood wrote:
> This code assumes that the ports have been previously set up, with
> buffers in DPRAM.
>
> Signed-off-by: Scott Wood <scottwood@freescale.com>
Looks sane as far as I can see.
Acked-by: David Gibson <david@gibson.dropbear.id.au>
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* Re: [PATCH 05/28] bootwrapper: Support all-in-one PCI nodes in cuboot-pq2.
From: David Gibson @ 2007-09-19 3:11 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20070917165734.GE6563@loki.buserror.net>
On Mon, Sep 17, 2007 at 11:57:34AM -0500, Scott Wood wrote:
> Consensus was reached to put PCI nodes at the root of the tree (and not
> under /soc), but the phandle to a control node was rejected in favor of
> simply not worrying about /pci/reg overlapping /soc/ranges.
>
> This updates cuboot-82xx to not look for the phandle.
I preferred the split-node method, but as you say, this consensus has
been reached for now.
Acked-by: David Gibson <david@gibson.dropbear.id.au>
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* Re: [PATCH 06/28] bootwrapper: Add PlanetCore firmware support.
From: David Gibson @ 2007-09-19 3:15 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20070917165735.GF6563@loki.buserror.net>
On Mon, Sep 17, 2007 at 11:57:35AM -0500, Scott Wood wrote:
> This is a library that board code can use to extract information from the
> PlanetCore configuration keys. PlanetCore is used on various boards from
> Embedded Planet.
>
> Signed-off-by: Scott Wood <scottwood@freescale.com>
[snip]
> +void planetcore_set_mac_addrs(const char *table)
> +{
> + char addr[4][6];
> + u64 int_addr;
> + u32 i;
> + int j;
> + void *node;
> +
> + if (!planetcore_get_hex(table, PLANETCORE_KEY_MAC_ADDR, &int_addr))
> + return;
> +
> + for (i = 0; i < 4; i++) {
> + u64 this_dev_addr = int_addr | mac_table[i];
> +
> + for (j = 5; j >= 0; j--) {
> + addr[i][j] = this_dev_addr & 0xff;
> + this_dev_addr >>= 8;
> + }
> +
> + node = find_node_by_prop_value(NULL, "linux,network-index",
> + (void *)&i, 4);
> + if (node) {
> + printf("ENET%u: local-mac-address <-"
> + " %02x:%02x:%02x:%02x:%02x:%02x\n\r", i,
> + addr[i][0], addr[i][1], addr[i][2],
> + addr[i][3], addr[i][4], addr[i][5]);
> +
> + setprop(node, "local-mac-address", addr[i], 6);
Hrm. When I said to extract the logic of fixup_mac_addrs(), I meant
to create a new one-address version of the function in devtree.c then
use it both here and in the fixup_mac_addrs() function. Rather than
duplicating it inline here.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* Re: [PATCH 07/28] bootwrapper: Add fsl_get_immr() and 8xx/pq2 clock functions.
From: David Gibson @ 2007-09-19 3:16 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20070917165736.GG6563@loki.buserror.net>
On Mon, Sep 17, 2007 at 11:57:36AM -0500, Scott Wood wrote:
> fsl_get_immr() uses /soc/ranges to determine the immr.
>
> mpc885_get_clock() transforms a crystal frequency into a system frequency
> according to the PLL register settings.
>
> pq2_get_clocks() does the same as the above for the PowerQUICC II,
> except that it produces several different clocks.
>
> The mpc8xx/pq2 set_clocks() functions modify common properties in
> the device tree based on the given clock data.
>
> The mpc885/pq2 fixup_clocks() functions call get_clocks(), and
> pass the results to set_clocks().
>
> Signed-off-by: Scott Wood <scottwood@freescale.com>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* Re: [PATCH 08/28] bootwrapper: Use fsl_get_immr() in cuboot-pq2.c.
From: David Gibson @ 2007-09-19 3:16 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20070917165737.GH6563@loki.buserror.net>
On Mon, Sep 17, 2007 at 11:57:37AM -0500, Scott Wood wrote:
Needs a commit comment
> Signed-off-by: Scott Wood <scottwood@freescale.com>
> ---
> arch/powerpc/boot/cuboot-pq2.c | 10 ++++------
> 1 files changed, 4 insertions(+), 6 deletions(-)
>
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* Re: [PATCH 1/3] powerpc clk.h interface for platforms
From: Paul Mackerras @ 2007-09-19 3:47 UTC (permalink / raw)
To: Domen Puncer; +Cc: David Brownell, linuxppc-dev, Sylvain Munaut
In-Reply-To: <20070806065857.GN4529@moe.telargo.com>
Domen Puncer writes:
> Paul, what do you say about this?
> Sylvain suggested it could also be integrated with define_machine
> interface.
As it stands, your patch adds the clk_* functions on all platforms.
What platforms would actually want to use them?
Paul.
^ permalink raw reply
* Cleanups for physmap_of.c
From: David Gibson @ 2007-09-19 4:16 UTC (permalink / raw)
To: Vitaly Wool, Paul Mackerras; +Cc: linuxppc-dev
This patch includes a whole batch of smallish cleanups for
drivers/mtd/physmap_of.c.
- A bunch of uneeded #includes are removed
- We switch to the modern linux/of.h etc. in place of
asm/prom.h
- Use some helper macros to avoid some ugly inline #ifdefs
- A few lines of unreachable code are removed
- A number of indentation / line-wrapping fixes
- More consistent use of kernel idioms such as if (!p) instead
of if (p == NULL)
- Clarify some printk()s and other informative strings.
- (the big one) Despite the name, this driver really has
nothing to do with drivers/mtd/physmap.c. The fact that the flash
chips must be physically direct mapped is a constrant, but doesn't
really say anything about the actual purpose of this driver, which is
to instantiate MTD devices based on information from the device tree.
Therefore the physmap name is replaced everywhere within the file with
"of_flash". The file itself and the Kconfig option is not renamed for
now (so that the diff is actually a diff). That can come later.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Index: working-2.6/drivers/mtd/maps/physmap_of.c
===================================================================
--- working-2.6.orig/drivers/mtd/maps/physmap_of.c 2007-09-14 14:24:06.000000000 +1000
+++ working-2.6/drivers/mtd/maps/physmap_of.c 2007-09-19 13:59:23.000000000 +1000
@@ -1,5 +1,5 @@
/*
- * Normal mappings of chips in physical memory for OF devices
+ * Flash mappings described by the OF (or flattened) device tree
*
* Copyright (C) 2006 MontaVista Software Inc.
* Author: Vitaly Wool <vwool@ru.mvista.com>
@@ -15,20 +15,15 @@
#include <linux/module.h>
#include <linux/types.h>
-#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
-#include <linux/mtd/physmap.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
-#include <asm/of_platform.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
-struct physmap_flash_info {
+struct of_flash {
struct mtd_info *mtd;
struct map_info map;
struct resource *res;
@@ -38,8 +33,10 @@ struct physmap_flash_info {
};
#ifdef CONFIG_MTD_PARTITIONS
+#define OF_FLASH_PARTS(info) ((info)->parts)
+
static int parse_obsolete_partitions(struct of_device *dev,
- struct physmap_flash_info *info,
+ struct of_flash *info,
struct device_node *dp)
{
int i, plen, nr_parts;
@@ -56,11 +53,9 @@ static int parse_obsolete_partitions(str
nr_parts = plen / sizeof(part[0]);
- info->parts = kzalloc(nr_parts * sizeof(struct mtd_partition), GFP_KERNEL);
- if (!info->parts) {
- printk(KERN_ERR "Can't allocate the flash partition data!\n");
+ info->parts = kzalloc(nr_parts * sizeof(*info->parts), GFP_KERNEL);
+ if (!info->parts)
return -ENOMEM;
- }
names = of_get_property(dp, "partition-names", &plen);
@@ -86,8 +81,8 @@ static int parse_obsolete_partitions(str
return nr_parts;
}
-static int __devinit process_partitions(struct physmap_flash_info *info,
- struct of_device *dev)
+static int __devinit parse_partitions(struct of_flash *info,
+ struct of_device *dev)
{
const char *partname;
static const char *part_probe_types[]
@@ -109,87 +104,68 @@ static int __devinit process_partitions(
for (pp = dp->child; pp; pp = pp->sibling)
nr_parts++;
- if (nr_parts) {
- info->parts = kzalloc(nr_parts * sizeof(struct mtd_partition),
- GFP_KERNEL);
- if (!info->parts) {
- printk(KERN_ERR "Can't allocate the flash partition data!\n");
- return -ENOMEM;
- }
+ if (nr_parts == 0)
+ return parse_obsolete_partitions(dev, info, dp);
- for (pp = dp->child, i = 0 ; pp; pp = pp->sibling, i++) {
- const u32 *reg;
- int len;
-
- reg = of_get_property(pp, "reg", &len);
- if (!reg || (len != 2*sizeof(u32))) {
- dev_err(&dev->dev, "Invalid 'reg' on %s\n",
- dp->full_name);
- kfree(info->parts);
- info->parts = NULL;
- return -EINVAL;
- }
- info->parts[i].offset = reg[0];
- info->parts[i].size = reg[1];
-
- partname = of_get_property(pp, "label", &len);
- if (!partname)
- partname = of_get_property(pp, "name", &len);
- info->parts[i].name = (char *)partname;
+ info->parts = kzalloc(nr_parts * sizeof(*info->parts),
+ GFP_KERNEL);
+ if (!info->parts)
+ return -ENOMEM;
- if (of_get_property(pp, "read-only", &len))
- info->parts[i].mask_flags = MTD_WRITEABLE;
+ for (pp = dp->child, i = 0; pp; pp = pp->sibling, i++) {
+ const u32 *reg;
+ int len;
+
+ reg = of_get_property(pp, "reg", &len);
+ if (!reg || (len != 2*sizeof(u32))) {
+ dev_err(&dev->dev, "Invalid 'reg' on %s\n",
+ dp->full_name);
+ kfree(info->parts);
+ info->parts = NULL;
+ return -EINVAL;
}
- } else {
- nr_parts = parse_obsolete_partitions(dev, info, dp);
- }
+ info->parts[i].offset = reg[0];
+ info->parts[i].size = reg[1];
- if (nr_parts < 0)
- return nr_parts;
+ partname = of_get_property(pp, "label", &len);
+ if (!partname)
+ partname = of_get_property(pp, "name", &len);
+ info->parts[i].name = (char *)partname;
- if (nr_parts > 0)
- add_mtd_partitions(info->mtd, info->parts, nr_parts);
- else
- add_mtd_device(info->mtd);
+ if (of_get_property(pp, "read-only", &len))
+ info->parts[i].mask_flags = MTD_WRITEABLE;
+ }
- return 0;
+ return nr_parts;
}
#else /* MTD_PARTITIONS */
-static int __devinit process_partitions(struct physmap_flash_info *info,
- struct device_node *dev)
-{
- add_mtd_device(info->mtd);
- return 0;
-}
+#define OF_FLASH_PARTS(info) (0)
+#define parse_partitions(info, dev) (0)
#endif /* MTD_PARTITIONS */
-static int of_physmap_remove(struct of_device *dev)
+static int of_flash_remove(struct of_device *dev)
{
- struct physmap_flash_info *info;
+ struct of_flash *info;
info = dev_get_drvdata(&dev->dev);
- if (info == NULL)
+ if (!info)
return 0;
dev_set_drvdata(&dev->dev, NULL);
- if (info->mtd != NULL) {
-#ifdef CONFIG_MTD_PARTITIONS
- if (info->parts) {
+ if (info->mtd) {
+ if (OF_FLASH_PARTS(info)) {
del_mtd_partitions(info->mtd);
- kfree(info->parts);
+ kfree(OF_FLASH_PARTS(info));
} else {
del_mtd_device(info->mtd);
}
-#else
- del_mtd_device(info->mtd);
-#endif
map_destroy(info->mtd);
}
- if (info->map.virt != NULL)
+ if (info->map.virt)
iounmap(info->map.virt);
- if (info->res != NULL) {
+ if (info->res) {
release_resource(info->res);
kfree(info->res);
}
@@ -227,52 +203,49 @@ static struct mtd_info * __devinit obsol
return do_map_probe("jedec_probe", map);
} else {
if (strcmp(of_probe, "ROM") != 0)
- dev_dbg(&dev->dev, "obsolete_probe: don't know probe type "
- "'%s', mapping as rom\n", of_probe);
+ dev_warn(&dev->dev, "obsolete_probe: don't know probe "
+ "type '%s', mapping as rom\n", of_probe);
return do_map_probe("mtd_rom", map);
}
}
-static int __devinit of_physmap_probe(struct of_device *dev, const struct of_device_id *match)
+static int __devinit of_flash_probe(struct of_device *dev,
+ const struct of_device_id *match)
{
struct device_node *dp = dev->node;
struct resource res;
- struct physmap_flash_info *info;
- const char *probe_type = (const char *)match->data;
+ struct of_flash *info;
+ const char *probe_type = match->data;
const u32 *width;
int err;
+ err = -ENXIO;
if (of_address_to_resource(dp, 0, &res)) {
- dev_err(&dev->dev, "Can't get the flash mapping!\n");
- err = -EINVAL;
+ dev_err(&dev->dev, "Can't get IO address from device tree\n");
goto err_out;
}
- dev_dbg(&dev->dev, "physmap flash device: %.8llx at %.8llx\n",
- (unsigned long long)res.end - res.start + 1,
- (unsigned long long)res.start);
-
- info = kzalloc(sizeof(struct physmap_flash_info), GFP_KERNEL);
- if (info == NULL) {
- err = -ENOMEM;
+ dev_dbg(&dev->dev, "of_flash device: %.8llx-%.8llx\n",
+ (unsigned long long)res.start, (unsigned long long)res.end);
+
+ err = -ENOMEM;
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
goto err_out;
- }
memset(info, 0, sizeof(*info));
dev_set_drvdata(&dev->dev, info);
+ err = -EBUSY;
info->res = request_mem_region(res.start, res.end - res.start + 1,
- dev->dev.bus_id);
- if (info->res == NULL) {
- dev_err(&dev->dev, "Could not reserve memory region\n");
- err = -ENOMEM;
+ dev->dev.bus_id);
+ if (!info->res)
goto err_out;
- }
+ err = -ENXIO;
width = of_get_property(dp, "bank-width", NULL);
- if (width == NULL) {
- dev_err(&dev->dev, "Can't get the flash bank width!\n");
- err = -EINVAL;
+ if (!width) {
+ dev_err(&dev->dev, "Can't get bank width from device tree\n");
goto err_out;
}
@@ -281,10 +254,10 @@ static int __devinit of_physmap_probe(st
info->map.size = res.end - res.start + 1;
info->map.bankwidth = *width;
+ err = -ENOMEM;
info->map.virt = ioremap(info->map.phys, info->map.size);
- if (info->map.virt == NULL) {
- dev_err(&dev->dev, "Failed to ioremap flash region\n");
- err = EIO;
+ if (!info->map.virt) {
+ dev_err(&dev->dev, "Failed to ioremap() flash region\n");
goto err_out;
}
@@ -295,25 +268,30 @@ static int __devinit of_physmap_probe(st
else
info->mtd = obsolete_probe(dev, &info->map);
- if (info->mtd == NULL) {
- dev_err(&dev->dev, "map_probe failed\n");
- err = -ENXIO;
+ err = -ENXIO;
+ if (!info->mtd) {
+ dev_err(&dev->dev, "do_map_probe() failed\n");
goto err_out;
}
info->mtd->owner = THIS_MODULE;
- return process_partitions(info, dev);
+ err = parse_partitions(info, dev);
+ if (err < 0)
+ goto err_out;
-err_out:
- of_physmap_remove(dev);
- return err;
+ if (err > 0)
+ add_mtd_partitions(info->mtd, OF_FLASH_PARTS(info), err);
+ else
+ add_mtd_device(info->mtd);
return 0;
-
+err_out:
+ of_flash_remove(dev);
+ return err;
}
-static struct of_device_id of_physmap_match[] = {
+static struct of_device_id of_flash_match[] = {
{
.compatible = "cfi-flash",
.data = (void *)"cfi_probe",
@@ -335,30 +313,28 @@ static struct of_device_id of_physmap_ma
},
{ },
};
+MODULE_DEVICE_TABLE(of, of_flash_match);
-MODULE_DEVICE_TABLE(of, of_physmap_match);
-
-
-static struct of_platform_driver of_physmap_flash_driver = {
- .name = "physmap-flash",
- .match_table = of_physmap_match,
- .probe = of_physmap_probe,
- .remove = of_physmap_remove,
+static struct of_platform_driver of_flash_driver = {
+ .name = "of-flash",
+ .match_table = of_flash_match,
+ .probe = of_flash_probe,
+ .remove = of_flash_remove,
};
-static int __init of_physmap_init(void)
+static int __init of_flash_init(void)
{
- return of_register_platform_driver(&of_physmap_flash_driver);
+ return of_register_platform_driver(&of_flash_driver);
}
-static void __exit of_physmap_exit(void)
+static void __exit of_flash_exit(void)
{
- of_unregister_platform_driver(&of_physmap_flash_driver);
+ of_unregister_platform_driver(&of_flash_driver);
}
-module_init(of_physmap_init);
-module_exit(of_physmap_exit);
+module_init(of_flash_init);
+module_exit(of_flash_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>");
-MODULE_DESCRIPTION("Configurable MTD map driver for OF");
+MODULE_DESCRIPTION("Device tree based MTD map driver");
--
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 1/2] powerpc: Don't expose clock vDSO functions when CPU has no timebase
From: Benjamin Herrenschmidt @ 2007-09-19 4:21 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
We forgot to remove the clock_gettime, clock_getres and get_tbfreq vDSO
calls on CPUs that have no timebase such as 601 or 403 (old CPUs that have
different mechanisms and for which the vDSO code will not work properly).
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/kernel/vdso.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
Index: linux-work/arch/powerpc/kernel/vdso.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/vdso.c 2007-09-18 16:54:37.000000000 +1000
+++ linux-work/arch/powerpc/kernel/vdso.c 2007-09-18 16:55:11.000000000 +1000
@@ -98,6 +98,18 @@ static struct vdso_patch_def vdso_patche
CPU_FTR_USE_TB, 0,
"__kernel_gettimeofday", NULL
},
+ {
+ CPU_FTR_USE_TB, 0,
+ "__kernel_clock_gettime", NULL
+ },
+ {
+ CPU_FTR_USE_TB, 0,
+ "__kernel_clock_getres", NULL
+ },
+ {
+ CPU_FTR_USE_TB, 0,
+ "__kernel_get_tbfreq", NULL
+ },
};
/*
^ permalink raw reply
* [PATCH 2/2] powerpc: Fix timekeeping on PowerPC 601
From: Benjamin Herrenschmidt @ 2007-09-19 4:21 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
Recent changes to the timekeeping code broke support for the PowerPC 601
processor which doesn't have the usual timebase facility but a slightly
different thing called (yuck) the RTC.
This fixes it, boot tested on an old 601 based PowerMac 7200
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/kernel/time.c | 8 +++++---
include/asm-powerpc/time.h | 5 +++++
2 files changed, 10 insertions(+), 3 deletions(-)
Index: linux-work/arch/powerpc/kernel/time.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/time.c 2007-09-19 10:53:28.000000000 +1000
+++ linux-work/arch/powerpc/kernel/time.c 2007-09-19 11:28:14.000000000 +1000
@@ -239,7 +239,7 @@ static void snapshot_tb_and_purr(void *d
struct cpu_purr_data *p = &__get_cpu_var(cpu_purr_data);
local_irq_save(flags);
- p->tb = mftb();
+ p->tb = get_tb_or_rtc();
p->purr = mfspr(SPRN_PURR);
wmb();
p->initialized = 1;
@@ -317,7 +317,7 @@ static void snapshot_purr(void)
*/
void snapshot_timebase(void)
{
- __get_cpu_var(last_jiffy) = get_tb();
+ __get_cpu_var(last_jiffy) = get_tb_or_rtc();
snapshot_purr();
}
@@ -684,6 +684,8 @@ void timer_interrupt(struct pt_regs * re
write_seqlock(&xtime_lock);
tb_next_jiffy = tb_last_jiffy + tb_ticks_per_jiffy;
+ if (__USE_RTC() && tb_next_jiffy >= 1000000000)
+ tb_next_jiffy -= 1000000000;
if (per_cpu(last_jiffy, cpu) >= tb_next_jiffy) {
tb_last_jiffy = tb_next_jiffy;
do_timer(1);
@@ -977,7 +979,7 @@ void __init time_init(void)
tb_to_ns_scale = scale;
tb_to_ns_shift = shift;
/* Save the current timebase to pretty up CONFIG_PRINTK_TIME */
- boot_tb = get_tb();
+ boot_tb = get_tb_or_rtc();
tm = get_boot_time();
Index: linux-work/include/asm-powerpc/time.h
===================================================================
--- linux-work.orig/include/asm-powerpc/time.h 2007-09-19 10:53:28.000000000 +1000
+++ linux-work/include/asm-powerpc/time.h 2007-09-19 10:53:37.000000000 +1000
@@ -149,6 +149,11 @@ static inline u64 get_tb(void)
}
#endif /* !CONFIG_PPC64 */
+static inline u64 get_tb_or_rtc(void)
+{
+ return __USE_RTC() ? get_rtc() : get_tb();
+}
+
static inline void set_tb(unsigned int upper, unsigned int lower)
{
mtspr(SPRN_TBWL, 0);
^ permalink raw reply
* Re: [PATCH 13/28] 8xx: Infrastructure code cleanup.
From: David Gibson @ 2007-09-19 4:25 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20070917165742.GM6563@loki.buserror.net>
On Mon, Sep 17, 2007 at 11:57:42AM -0500, Scott Wood wrote:
> 1. Keep a global mpc8xx_immr mapping, rather than constantly
> creating temporary mappings.
Nice, but again, it seems a bit pointless to leave in all the
immr_map() / immr_unmap() pairs now that they do basically nothing.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* Re: [PATCH] [POWERPC] Fix build errors when BLOCK=n
From: Paul Mackerras @ 2007-09-19 4:49 UTC (permalink / raw)
To: Emil Medve; +Cc: linuxppc-dev, kumar.gala, bzolnier, linux-ide
In-Reply-To: <11900663131073-git-send-email-Emilian.Medve@Freescale.com>
Emil Medve writes:
> The fix tries to use the smallest scope CONFIG_* symbols that will fix the build
> problem. In this case <linux/ide.h> needs to be included only if IDE=y or
> IDE=m were selected. Also, ppc_ide_md is needed only if BLK_DEV_IDE=y or
> BLK_DEV_IDE=m
It would be nicer to remove the ppc_ide_md stuff from ppc_ksyms.c
altogether and just put the EXPORT_SYMBOL in setup_32.c.
Paul.
^ permalink raw reply
* [PATCH] powerpc: Fix platinumfb framebuffer
From: Benjamin Herrenschmidt @ 2007-09-19 4:50 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev list, Linux Fbdev development list
powerpc: Fix platinumfb resource handling
Current kernels have a non-working platinumfb due to some resource
management issues. This fixes it.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
Note: platinumfb is a powermac only driver
Index: linux-work/drivers/video/platinumfb.c
===================================================================
--- linux-work.orig/drivers/video/platinumfb.c 2007-09-19 14:21:42.000000000 +1000
+++ linux-work/drivers/video/platinumfb.c 2007-09-19 14:47:11.000000000 +1000
@@ -17,6 +17,8 @@
* more details.
*/
+#undef DEBUG
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -535,33 +537,35 @@ static int __devinit platinumfb_probe(st
volatile __u8 *fbuffer;
int bank0, bank1, bank2, bank3, rc;
- printk(KERN_INFO "platinumfb: Found Apple Platinum video hardware\n");
+ dev_info(&odev->dev, "Found Apple Platinum video hardware\n");
info = framebuffer_alloc(sizeof(*pinfo), &odev->dev);
- if (info == NULL)
+ if (info == NULL) {
+ dev_err(&odev->dev, "Failed to allocate fbdev !\n");
return -ENOMEM;
+ }
pinfo = info->par;
if (of_address_to_resource(dp, 0, &pinfo->rsrc_reg) ||
of_address_to_resource(dp, 1, &pinfo->rsrc_fb)) {
- printk(KERN_ERR "platinumfb: Can't get resources\n");
- framebuffer_release(info);
- return -ENXIO;
- }
- if (!request_mem_region(pinfo->rsrc_reg.start,
- pinfo->rsrc_reg.start -
- pinfo->rsrc_reg.end + 1,
- "platinumfb registers")) {
+ dev_err(&odev->dev, "Can't get resources\n");
framebuffer_release(info);
return -ENXIO;
}
+ dev_dbg(&odev->dev, " registers : 0x%llx...0x%llx\n",
+ (unsigned long long)pinfo->rsrc_reg.start,
+ (unsigned long long)pinfo->rsrc_reg.end);
+ dev_dbg(&odev->dev, " framebuffer: 0x%llx...0x%llx\n",
+ (unsigned long long)pinfo->rsrc_fb.start,
+ (unsigned long long)pinfo->rsrc_fb.end);
+
+ /* Do not try to request register space, they overlap with the
+ * northbridge and that can fail. Only request framebuffer
+ */
if (!request_mem_region(pinfo->rsrc_fb.start,
- pinfo->rsrc_fb.start
- - pinfo->rsrc_fb.end + 1,
+ pinfo->rsrc_fb.end - pinfo->rsrc_fb.start + 1,
"platinumfb framebuffer")) {
- release_mem_region(pinfo->rsrc_reg.start,
- pinfo->rsrc_reg.end -
- pinfo->rsrc_reg.start + 1);
+ printk(KERN_ERR "platinumfb: Can't request framebuffer !\n");
framebuffer_release(info);
return -ENXIO;
}
@@ -600,7 +604,8 @@ static int __devinit platinumfb_probe(st
bank2 = fbuffer[0x200000] == 0x56;
bank3 = fbuffer[0x300000] == 0x78;
pinfo->total_vram = (bank0 + bank1 + bank2 + bank3) * 0x100000;
- printk(KERN_INFO "platinumfb: Total VRAM = %dMB (%d%d%d%d)\n", (int) (pinfo->total_vram / 1024 / 1024),
+ printk(KERN_INFO "platinumfb: Total VRAM = %dMB (%d%d%d%d)\n",
+ (unsigned int) (pinfo->total_vram / 1024 / 1024),
bank3, bank2, bank1, bank0);
/*
@@ -644,16 +649,15 @@ static int __devexit platinumfb_remove(s
unregister_framebuffer (info);
/* Unmap frame buffer and registers */
+ iounmap(pinfo->frame_buffer);
+ iounmap(pinfo->platinum_regs);
+ iounmap(pinfo->cmap_regs);
+
release_mem_region(pinfo->rsrc_fb.start,
pinfo->rsrc_fb.end -
pinfo->rsrc_fb.start + 1);
- release_mem_region(pinfo->rsrc_reg.start,
- pinfo->rsrc_reg.end -
- pinfo->rsrc_reg.start + 1);
- iounmap(pinfo->frame_buffer);
- iounmap(pinfo->platinum_regs);
+
release_mem_region(pinfo->cmap_regs_phys, 0x1000);
- iounmap(pinfo->cmap_regs);
framebuffer_release(info);
^ permalink raw reply
* Re: Jtag under Linux on MPC875
From: Sven Luther @ 2007-09-19 4:56 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-embedded
In-Reply-To: <20070918144905.GF441@ld0162-tx32.am.freescale.net>
On Tue, Sep 18, 2007 at 09:49:05AM -0500, Scott Wood wrote:
> On Tue, Sep 18, 2007 at 11:04:27AM +0200, fabien wrote:
> > I'm new in embedded system and i need some informations ...
> > Which tool could i use to connect my board througt the JTAG connector ?
> > My board is a custom board with a MPC875, and flash is S29GL032M. The probe
> > that can i use is
> > a PowerPC BDM windriver Probe 2.
> > I'm looking for a tool running on linux.
>
> The Abatron BDI2000 works well with Linux.
Indeed, but i was not able to put my MPC875 board in halt state once linux
started running. I hear Vitaly has had similar problems too.
Wolfgang said it worked though, so this may be due to a hardware quirk
or some misconfiguration or something. I am not really a bdi config file
expert myself.
Friendly,
Sven Luther
^ permalink raw reply
* Re: Linux based MPC855 SPI driver
From: Sven Luther @ 2007-09-19 4:57 UTC (permalink / raw)
To: Hesam Kohanteb; +Cc: linuxppc-embedded
In-Reply-To: <46F06313.8080007@Sun.COM>
On Tue, Sep 18, 2007 at 04:45:23PM -0700, Hesam Kohanteb wrote:
> Hi,
> I urgently need to implement a Linux based SPI driver for MPC855. Can
> please point me to one if exists or to a similar one MPC823.
I wrote something for the MPC875, need some cleanup, but i could send it
to you if you are interested. Please ask me personally.
Friendly,
Sven Luther
^ permalink raw reply
* [PATCH] powerpc mm init_32 gdb regions
From: Ed Swarthout @ 2007-09-19 5:09 UTC (permalink / raw)
To: galak, linuxppc-dev; +Cc: Ed Swarthout
Add memory regions to the kcore list for 32-bit machines.
Since the entries are only 32-bit, keep under 4G.
Signed-off-by: Ed Swarthout <Ed.Swarthout@freescale.com>
---
Adapted from init_64.c
arch/powerpc/mm/init_32.c | 34 ++++++++++++++++++++++++++++++++++
1 files changed, 34 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index d65995a..d804c65 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -255,3 +255,37 @@ void free_initrd_mem(unsigned long start, unsigned long end)
}
}
#endif
+
+static struct kcore_list kcore_vmem;
+
+static int __init setup_kcore(void)
+{
+ int i;
+
+ for (i=0; i < lmb.memory.cnt; i++) {
+ unsigned long base, size;
+ struct kcore_list *kcore_mem;
+
+ base = lmb.memory.region[i].base;
+ size = lmb.memory.region[i].size;
+
+ kcore_mem = kmalloc(sizeof(struct kcore_list), GFP_ATOMIC);
+ if (!kcore_mem)
+ panic("%s: kmalloc failed\n", __FUNCTION__);
+
+ /* must stay under 32 bits */
+ if ( 0xfffffffful - (unsigned long)__va(base) < size) {
+ size = 0xfffffffful - (unsigned long)(__va(base));
+ printk(KERN_DEBUG "setup_kcore: restrict size=%lx\n",
+ size);
+ }
+
+ kclist_add(kcore_mem, __va(base), size);
+ }
+
+ kclist_add(&kcore_vmem, (void *)VMALLOC_START,
+ VMALLOC_END-VMALLOC_START);
+
+ return 0;
+}
+module_init(setup_kcore);
--
1.5.3.rc6.63.gf7c18
^ permalink raw reply related
* Re: [PATCH 13/28] 8xx: Infrastructure code cleanup.
From: Scott Wood @ 2007-09-19 5:28 UTC (permalink / raw)
To: galak, linuxppc-dev
In-Reply-To: <20070919042533.GB30212@localhost.localdomain>
On Wed, Sep 19, 2007 at 02:25:33PM +1000, David Gibson wrote:
> On Mon, Sep 17, 2007 at 11:57:42AM -0500, Scott Wood wrote:
> > 1. Keep a global mpc8xx_immr mapping, rather than constantly
> > creating temporary mappings.
>
> Nice, but again, it seems a bit pointless to leave in all the
> immr_map() / immr_unmap() pairs now that they do basically nothing.
One step at a time. :-)
Once arch/ppc is gone, I'd like to do some heavier cleanup of the CPM
stuff, including merging with QE. For now, I want to touch code that's
shared between the architectures as little as possible.
-Scott
^ permalink raw reply
* Re: [PATCH 1/3] powerpc clk.h interface for platforms
From: Domen Puncer @ 2007-09-19 5:11 UTC (permalink / raw)
To: Paul Mackerras; +Cc: David Brownell, linuxppc-dev, Sylvain Munaut
In-Reply-To: <18160.39896.132391.625791@cargo.ozlabs.ibm.com>
On 19/09/07 13:47 +1000, Paul Mackerras wrote:
> Domen Puncer writes:
>
> > Paul, what do you say about this?
> > Sylvain suggested it could also be integrated with define_machine
> > interface.
>
> As it stands, your patch adds the clk_* functions on all platforms.
> What platforms would actually want to use them?
52xx
Reason for adding it to all was that EXPORT_SYMBOL's would clash if
one were to add clk support for another platform.
Domen
>
> Paul.
^ permalink raw reply
* [PATCH 4/5] Include hrtimer.h in tick.h.
From: Tony Breeds @ 2007-09-19 6:49 UTC (permalink / raw)
To: linuxppc-dev, Paul Mackerras; +Cc: Thomas Gleixner, Realtime Kernel
In-Reply-To: <1190184586.867449.381310088392.qpush@thor>
struct tick_shed uses struct hrtimer, explictly include the right header file.
preemtivly fixes the following warning
CC arch/powerpc/platforms/iseries/setup.o
In file included from arch/powerpc/platforms/iseries/setup.c:30:
include/linux/tick.h:45: error: field 'sched_timer' has incomplete type
Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>
---
include/linux/tick.h | 1 +
1 file changed, 1 insertion(+)
Index: working/include/linux/tick.h
===================================================================
--- working.orig/include/linux/tick.h
+++ working/include/linux/tick.h
@@ -7,6 +7,7 @@
#define _LINUX_TICK_H
#include <linux/clockchips.h>
+#include <linux/hrtimer.h>
#ifdef CONFIG_GENERIC_CLOCKEVENTS
^ permalink raw reply
* [PATCH 2/5] Implement generic time of day clocksource for powerpc machines.
From: Tony Breeds @ 2007-09-19 6:49 UTC (permalink / raw)
To: linuxppc-dev, Paul Mackerras; +Cc: Thomas Gleixner, Realtime Kernel
In-Reply-To: <1190184586.867449.381310088392.qpush@thor>
Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>
---
arch/powerpc/Kconfig | 6
arch/powerpc/kernel/time.c | 255 ++++++++++++-------------------------
2 files changed, 91 insertions(+), 170 deletions(-)
Index: working/arch/powerpc/Kconfig
===================================================================
--- working.orig/arch/powerpc/Kconfig
+++ working/arch/powerpc/Kconfig
@@ -24,6 +24,12 @@ config MMU
config GENERIC_CMOS_UPDATE
def_bool y
+config GENERIC_TIME
+ def_bool y
+
+config GENERIC_TIME_VSYSCALL
+ def_bool y
+
config GENERIC_HARDIRQS
bool
default y
Index: working/arch/powerpc/kernel/time.c
===================================================================
--- working.orig/arch/powerpc/kernel/time.c
+++ working/arch/powerpc/kernel/time.c
@@ -74,9 +74,28 @@
#endif
#include <asm/smp.h>
+/* powerpc clocksource/clockevent code */
+
+#include <linux/clocksource.h>
+
+static cycle_t timebase_read(void);
+
+static struct clocksource clocksource_timebase = {
+ .name = "timebase",
+ .rating = 400,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ .mask = CLOCKSOURCE_MASK(64),
+ .shift = 22,
+ .mult = 0, /* To be filled in */
+ .read = timebase_read,
+};
+
#ifdef CONFIG_PPC_ISERIES
static unsigned long __initdata iSeries_recal_titan;
static signed long __initdata iSeries_recal_tb;
+
+/* Forward declaration is only needed for iSereis compiles */
+void __init clocksource_init(void);
#endif
#define XSEC_PER_SEC (1024*1024)
@@ -344,65 +363,6 @@ void udelay(unsigned long usecs)
}
EXPORT_SYMBOL(udelay);
-/*
- * This version of gettimeofday has microsecond resolution.
- */
-static inline void __do_gettimeofday(struct timeval *tv)
-{
- unsigned long sec, usec;
- u64 tb_ticks, xsec;
- struct gettimeofday_vars *temp_varp;
- u64 temp_tb_to_xs, temp_stamp_xsec;
-
- /*
- * These calculations are faster (gets rid of divides)
- * if done in units of 1/2^20 rather than microseconds.
- * The conversion to microseconds at the end is done
- * without a divide (and in fact, without a multiply)
- */
- temp_varp = do_gtod.varp;
-
- /* Sampling the time base must be done after loading
- * do_gtod.varp in order to avoid racing with update_gtod.
- */
- data_barrier(temp_varp);
- tb_ticks = get_tb() - temp_varp->tb_orig_stamp;
- temp_tb_to_xs = temp_varp->tb_to_xs;
- temp_stamp_xsec = temp_varp->stamp_xsec;
- xsec = temp_stamp_xsec + mulhdu(tb_ticks, temp_tb_to_xs);
- sec = xsec / XSEC_PER_SEC;
- usec = (unsigned long)xsec & (XSEC_PER_SEC - 1);
- usec = SCALE_XSEC(usec, 1000000);
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-
-void do_gettimeofday(struct timeval *tv)
-{
- if (__USE_RTC()) {
- /* do this the old way */
- unsigned long flags, seq;
- unsigned int sec, nsec, usec;
-
- do {
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
- sec = xtime.tv_sec;
- nsec = xtime.tv_nsec + tb_ticks_since(tb_last_jiffy);
- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
- usec = nsec / 1000;
- while (usec >= 1000000) {
- usec -= 1000000;
- ++sec;
- }
- tv->tv_sec = sec;
- tv->tv_usec = usec;
- return;
- }
- __do_gettimeofday(tv);
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
/*
* There are two copies of tb_to_xs and stamp_xsec so that no
@@ -448,56 +408,6 @@ static inline void update_gtod(u64 new_t
++(vdso_data->tb_update_count);
}
-/*
- * When the timebase - tb_orig_stamp gets too big, we do a manipulation
- * between tb_orig_stamp and stamp_xsec. The goal here is to keep the
- * difference tb - tb_orig_stamp small enough to always fit inside a
- * 32 bits number. This is a requirement of our fast 32 bits userland
- * implementation in the vdso. If we "miss" a call to this function
- * (interrupt latency, CPU locked in a spinlock, ...) and we end up
- * with a too big difference, then the vdso will fallback to calling
- * the syscall
- */
-static __inline__ void timer_recalc_offset(u64 cur_tb)
-{
- unsigned long offset;
- u64 new_stamp_xsec;
- u64 tlen, t2x;
- u64 tb, xsec_old, xsec_new;
- struct gettimeofday_vars *varp;
-
- if (__USE_RTC())
- return;
- tlen = current_tick_length();
- offset = cur_tb - do_gtod.varp->tb_orig_stamp;
- if (tlen == last_tick_len && offset < 0x80000000u)
- return;
- if (tlen != last_tick_len) {
- t2x = mulhdu(tlen << TICKLEN_SHIFT, ticklen_to_xs);
- last_tick_len = tlen;
- } else
- t2x = do_gtod.varp->tb_to_xs;
- new_stamp_xsec = (u64) xtime.tv_nsec * XSEC_PER_SEC;
- do_div(new_stamp_xsec, 1000000000);
- new_stamp_xsec += (u64) xtime.tv_sec * XSEC_PER_SEC;
-
- ++vdso_data->tb_update_count;
- smp_mb();
-
- /*
- * Make sure time doesn't go backwards for userspace gettimeofday.
- */
- tb = get_tb();
- varp = do_gtod.varp;
- xsec_old = mulhdu(tb - varp->tb_orig_stamp, varp->tb_to_xs)
- + varp->stamp_xsec;
- xsec_new = mulhdu(tb - cur_tb, t2x) + new_stamp_xsec;
- if (xsec_new < xsec_old)
- new_stamp_xsec += xsec_old - xsec_new;
-
- update_gtod(cur_tb, new_stamp_xsec, t2x);
-}
-
#ifdef CONFIG_SMP
unsigned long profile_pc(struct pt_regs *regs)
{
@@ -569,6 +479,8 @@ static int __init iSeries_tb_recal(void)
iSeries_recal_titan = titan;
iSeries_recal_tb = tb;
+ /* Called here as now we know accurate values for the timebase */
+ clocksource_init();
return 0;
}
late_initcall(iSeries_tb_recal);
@@ -651,7 +563,6 @@ void timer_interrupt(struct pt_regs * re
if (per_cpu(last_jiffy, cpu) >= tb_next_jiffy) {
tb_last_jiffy = tb_next_jiffy;
do_timer(1);
- timer_recalc_offset(tb_last_jiffy);
}
write_sequnlock(&xtime_lock);
}
@@ -723,66 +634,6 @@ unsigned long long sched_clock(void)
return mulhdu(get_tb() - boot_tb, tb_to_ns_scale) << tb_to_ns_shift;
}
-int do_settimeofday(struct timespec *tv)
-{
- time_t wtm_sec, new_sec = tv->tv_sec;
- long wtm_nsec, new_nsec = tv->tv_nsec;
- unsigned long flags;
- u64 new_xsec;
- unsigned long tb_delta;
-
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_seqlock_irqsave(&xtime_lock, flags);
-
- /*
- * Updating the RTC is not the job of this code. If the time is
- * stepped under NTP, the RTC will be updated after STA_UNSYNC
- * is cleared. Tools like clock/hwclock either copy the RTC
- * to the system time, in which case there is no point in writing
- * to the RTC again, or write to the RTC but then they don't call
- * settimeofday to perform this operation.
- */
-
- /* Make userspace gettimeofday spin until we're done. */
- ++vdso_data->tb_update_count;
- smp_mb();
-
- /*
- * Subtract off the number of nanoseconds since the
- * beginning of the last tick.
- */
- tb_delta = tb_ticks_since(tb_last_jiffy);
- tb_delta = mulhdu(tb_delta, do_gtod.varp->tb_to_xs); /* in xsec */
- new_nsec -= SCALE_XSEC(tb_delta, 1000000000);
-
- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - new_sec);
- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - new_nsec);
-
- set_normalized_timespec(&xtime, new_sec, new_nsec);
- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
- ntp_clear();
-
- new_xsec = xtime.tv_nsec;
- if (new_xsec != 0) {
- new_xsec *= XSEC_PER_SEC;
- do_div(new_xsec, NSEC_PER_SEC);
- }
- new_xsec += (u64)xtime.tv_sec * XSEC_PER_SEC;
- update_gtod(tb_last_jiffy, new_xsec, do_gtod.varp->tb_to_xs);
-
- vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
- vdso_data->tz_dsttime = sys_tz.tz_dsttime;
-
- write_sequnlock_irqrestore(&xtime_lock, flags);
- clock_was_set();
- return 0;
-}
-
-EXPORT_SYMBOL(do_settimeofday);
-
static int __init get_freq(char *name, int cells, unsigned long *val)
{
struct device_node *cpu;
@@ -874,6 +725,64 @@ unsigned long read_persistent_clock(void
tm.tm_hour, tm.tm_min, tm.tm_sec);
}
+/* clocksource code */
+/* FIXME: provide an RTC clocksource /or/ use a better name */
+static cycle_t timebase_read(void)
+{
+ if (__USE_RTC())
+ return (cycle_t)get_rtc();
+ return (cycle_t)get_tb();
+}
+
+void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
+{
+ u64 t2x, stamp_xsec;
+
+ if (__USE_RTC() || clock != &clocksource_timebase)
+ return;
+
+ /* Make userspace gettimeofday spin until we're done. */
+ ++vdso_data->tb_update_count;
+ smp_mb();
+
+ /* XXX this assumes clock->shift == 22 */
+ /* 4611686018 ~= 2^(20+64-22) / 1e9 */
+ t2x = (u64) clock->mult * 4611686018ULL;
+ stamp_xsec = (u64) xtime.tv_nsec * XSEC_PER_SEC;
+ do_div(stamp_xsec, 1000000000);
+ stamp_xsec += (u64) xtime.tv_sec * XSEC_PER_SEC;
+ update_gtod(clock->cycle_last, stamp_xsec, t2x);
+}
+
+void update_vsyscall_tz(void)
+{
+ /* Make userspace gettimeofday spin until we're done. */
+ ++vdso_data->tb_update_count;
+ smp_mb();
+ vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
+ vdso_data->tz_dsttime = sys_tz.tz_dsttime;
+ smp_mb();
+ ++vdso_data->tb_update_count;
+}
+
+void __init clocksource_init(void)
+{
+ int mult = clocksource_hz2mult(tb_ticks_per_sec,
+ clocksource_timebase.shift);
+
+ clocksource_timebase.mult = mult;
+
+ if (clocksource_register(&clocksource_timebase)) {
+ printk(KERN_ERR "clocksource: %s is already registered\n",
+ clocksource_timebase.name);
+ return;
+ }
+
+ printk(KERN_INFO "clocksource: %s mult[%x] shift[%d] registered\n",
+ clocksource_timebase.name,
+ clocksource_timebase.mult, clocksource_timebase.shift);
+}
+
/* This function is only called on the boot processor */
void __init time_init(void)
{
@@ -983,6 +892,12 @@ void __init time_init(void)
write_sequnlock_irqrestore(&xtime_lock, flags);
+ /* Register the clocksource, if we're not running on iSeries */
+#ifdef CONFIG_ISERIES
+ if (!firmware_has_feature(FW_FEATURE_ISERIES))
+#endif
+ clocksource_init();
+
/* Not exact, but the timer interrupt takes care of this */
set_dec(tb_ticks_per_jiffy);
}
^ permalink raw reply
* [PATCH 5/5] Enable tickless idle and high res timers for powerpc
From: Tony Breeds @ 2007-09-19 6:49 UTC (permalink / raw)
To: linuxppc-dev, Paul Mackerras; +Cc: Thomas Gleixner, Realtime Kernel
In-Reply-To: <1190184586.867449.381310088392.qpush@thor>
Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>
---
arch/powerpc/Kconfig | 1 +
arch/powerpc/kernel/idle.c | 3 +++
arch/powerpc/platforms/iseries/setup.c | 5 +++++
3 files changed, 9 insertions(+)
Index: working/arch/powerpc/Kconfig
===================================================================
--- working.orig/arch/powerpc/Kconfig
+++ working/arch/powerpc/Kconfig
@@ -168,6 +168,7 @@ config HIGHMEM
bool "High memory support"
depends on PPC32
+source kernel/time/Kconfig
source kernel/Kconfig.hz
source kernel/Kconfig.preempt
source "fs/Kconfig.binfmt"
Index: working/arch/powerpc/kernel/idle.c
===================================================================
--- working.orig/arch/powerpc/kernel/idle.c
+++ working/arch/powerpc/kernel/idle.c
@@ -24,6 +24,7 @@
#include <linux/smp.h>
#include <linux/cpu.h>
#include <linux/sysctl.h>
+#include <linux/tick.h>
#include <asm/system.h>
#include <asm/processor.h>
@@ -59,6 +60,7 @@ void cpu_idle(void)
set_thread_flag(TIF_POLLING_NRFLAG);
while (1) {
+ tick_nohz_stop_sched_tick();
while (!need_resched() && !cpu_should_die()) {
ppc64_runlatch_off();
@@ -90,6 +92,7 @@ void cpu_idle(void)
HMT_medium();
ppc64_runlatch_on();
+ tick_nohz_restart_sched_tick();
if (cpu_should_die())
cpu_die();
preempt_enable_no_resched();
Index: working/arch/powerpc/platforms/iseries/setup.c
===================================================================
--- working.orig/arch/powerpc/platforms/iseries/setup.c
+++ working/arch/powerpc/platforms/iseries/setup.c
@@ -26,6 +26,7 @@
#include <linux/major.h>
#include <linux/root_dev.h>
#include <linux/kernel.h>
+#include <linux/tick.h>
#include <asm/processor.h>
#include <asm/machdep.h>
@@ -562,6 +563,7 @@ static void yield_shared_processor(void)
static void iseries_shared_idle(void)
{
while (1) {
+ tick_nohz_stop_sched_tick();
while (!need_resched() && !hvlpevent_is_pending()) {
local_irq_disable();
ppc64_runlatch_off();
@@ -575,6 +577,7 @@ static void iseries_shared_idle(void)
}
ppc64_runlatch_on();
+ tick_nohz_restart_sched_tick();
if (hvlpevent_is_pending())
process_iSeries_events();
@@ -590,6 +593,7 @@ static void iseries_dedicated_idle(void)
set_thread_flag(TIF_POLLING_NRFLAG);
while (1) {
+ tick_nohz_stop_sched_tick();
if (!need_resched()) {
while (!need_resched()) {
ppc64_runlatch_off();
@@ -606,6 +610,7 @@ static void iseries_dedicated_idle(void)
}
ppc64_runlatch_on();
+ tick_nohz_restart_sched_tick();
preempt_enable_no_resched();
schedule();
preempt_disable();
^ permalink raw reply
* [PATCH 1/5] Implement {read,update}_persistent_clock.
From: Tony Breeds @ 2007-09-19 6:49 UTC (permalink / raw)
To: linuxppc-dev, Paul Mackerras; +Cc: Thomas Gleixner, Realtime Kernel
With these functions implemented we cooperate better with the generic
timekeeping code. This obsoletes the need for the timer sysdev as a bonus.
Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>
---
* Compile tested for arch/powerpc/configs/*_defconfig
* Booted on pSeries, iSeries, Cell and PS3
arch/powerpc/Kconfig | 3 +
arch/powerpc/kernel/time.c | 85 ++++++++++-------------------------
arch/powerpc/sysdev/Makefile | 5 --
arch/powerpc/sysdev/timer.c | 81 ---------------------------------
4 files changed, 29 insertions(+), 145 deletions(-)
Index: working/arch/powerpc/Kconfig
===================================================================
--- working.orig/arch/powerpc/Kconfig
+++ working/arch/powerpc/Kconfig
@@ -21,6 +21,9 @@ config MMU
bool
default y
+config GENERIC_CMOS_UPDATE
+ def_bool y
+
config GENERIC_HARDIRQS
bool
default y
Index: working/arch/powerpc/kernel/time.c
===================================================================
--- working.orig/arch/powerpc/kernel/time.c
+++ working/arch/powerpc/kernel/time.c
@@ -74,16 +74,11 @@
#endif
#include <asm/smp.h>
-/* keep track of when we need to update the rtc */
-time_t last_rtc_update;
#ifdef CONFIG_PPC_ISERIES
static unsigned long __initdata iSeries_recal_titan;
static signed long __initdata iSeries_recal_tb;
#endif
-/* The decrementer counts down by 128 every 128ns on a 601. */
-#define DECREMENTER_COUNT_601 (1000000000 / HZ)
-
#define XSEC_PER_SEC (1024*1024)
#ifdef CONFIG_PPC64
@@ -349,39 +344,6 @@ void udelay(unsigned long usecs)
}
EXPORT_SYMBOL(udelay);
-static __inline__ void timer_check_rtc(void)
-{
- /*
- * update the rtc when needed, this should be performed on the
- * right fraction of a second. Half or full second ?
- * Full second works on mk48t59 clocks, others need testing.
- * Note that this update is basically only used through
- * the adjtimex system calls. Setting the HW clock in
- * any other way is a /dev/rtc and userland business.
- * This is still wrong by -0.5/+1.5 jiffies because of the
- * timer interrupt resolution and possible delay, but here we
- * hit a quantization limit which can only be solved by higher
- * resolution timers and decoupling time management from timer
- * interrupts. This is also wrong on the clocks
- * which require being written at the half second boundary.
- * We should have an rtc call that only sets the minutes and
- * seconds like on Intel to avoid problems with non UTC clocks.
- */
- if (ppc_md.set_rtc_time && ntp_synced() &&
- xtime.tv_sec - last_rtc_update >= 659 &&
- abs((xtime.tv_nsec/1000) - (1000000-1000000/HZ)) < 500000/HZ) {
- struct rtc_time tm;
- to_tm(xtime.tv_sec + 1 + timezone_offset, &tm);
- tm.tm_year -= 1900;
- tm.tm_mon -= 1;
- if (ppc_md.set_rtc_time(&tm) == 0)
- last_rtc_update = xtime.tv_sec + 1;
- else
- /* Try again one minute later */
- last_rtc_update += 60;
- }
-}
-
/*
* This version of gettimeofday has microsecond resolution.
*/
@@ -690,7 +652,6 @@ void timer_interrupt(struct pt_regs * re
tb_last_jiffy = tb_next_jiffy;
do_timer(1);
timer_recalc_offset(tb_last_jiffy);
- timer_check_rtc();
}
write_sequnlock(&xtime_lock);
}
@@ -802,11 +763,6 @@ int do_settimeofday(struct timespec *tv)
set_normalized_timespec(&xtime, new_sec, new_nsec);
set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
- /* In case of a large backwards jump in time with NTP, we want the
- * clock to be updated as soon as the PLL is again in lock.
- */
- last_rtc_update = new_sec - 658;
-
ntp_clear();
new_xsec = xtime.tv_nsec;
@@ -882,12 +838,35 @@ void __init generic_calibrate_decr(void)
#endif
}
-unsigned long get_boot_time(void)
+int update_persistent_clock(struct timespec now)
{
struct rtc_time tm;
- if (ppc_md.get_boot_time)
- return ppc_md.get_boot_time();
+ if (!ppc_md.set_rtc_time)
+ return 0;
+
+ to_tm(now.tv_sec + 1 + timezone_offset, &tm);
+ tm.tm_year -= 1900;
+ tm.tm_mon -= 1;
+
+ return ppc_md.set_rtc_time(&tm);
+}
+
+unsigned long read_persistent_clock(void)
+{
+ struct rtc_time tm;
+ static int first = 1;
+
+ /* XXX this is a litle fragile but will work okay in the short term */
+ if (first) {
+ first = 0;
+ if (ppc_md.time_init)
+ timezone_offset = ppc_md.time_init();
+
+ /* get_boot_time() isn't guaranteed to be safe to call late */
+ if (ppc_md.get_boot_time)
+ return ppc_md.get_boot_time() -timezone_offset;
+ }
if (!ppc_md.get_rtc_time)
return 0;
ppc_md.get_rtc_time(&tm);
@@ -899,14 +878,10 @@ unsigned long get_boot_time(void)
void __init time_init(void)
{
unsigned long flags;
- unsigned long tm = 0;
struct div_result res;
u64 scale, x;
unsigned shift;
- if (ppc_md.time_init != NULL)
- timezone_offset = ppc_md.time_init();
-
if (__USE_RTC()) {
/* 601 processor: dec counts down by 128 every 128ns */
ppc_tb_freq = 1000000000;
@@ -981,19 +956,14 @@ void __init time_init(void)
/* Save the current timebase to pretty up CONFIG_PRINTK_TIME */
boot_tb = get_tb_or_rtc();
- tm = get_boot_time();
-
write_seqlock_irqsave(&xtime_lock, flags);
/* If platform provided a timezone (pmac), we correct the time */
if (timezone_offset) {
sys_tz.tz_minuteswest = -timezone_offset / 60;
sys_tz.tz_dsttime = 0;
- tm -= timezone_offset;
}
- xtime.tv_sec = tm;
- xtime.tv_nsec = 0;
do_gtod.varp = &do_gtod.vars[0];
do_gtod.var_idx = 0;
do_gtod.varp->tb_orig_stamp = tb_last_jiffy;
@@ -1011,9 +981,6 @@ void __init time_init(void)
time_freq = 0;
- last_rtc_update = xtime.tv_sec;
- set_normalized_timespec(&wall_to_monotonic,
- -xtime.tv_sec, -xtime.tv_nsec);
write_sequnlock_irqrestore(&xtime_lock, flags);
/* Not exact, but the timer interrupt takes care of this */
Index: working/arch/powerpc/sysdev/Makefile
===================================================================
--- working.orig/arch/powerpc/sysdev/Makefile
+++ working/arch/powerpc/sysdev/Makefile
@@ -20,11 +20,6 @@ obj-$(CONFIG_MV64X60) += $(mv64x60-y) m
obj-$(CONFIG_RTC_DRV_CMOS) += rtc_cmos_setup.o
obj-$(CONFIG_AXON_RAM) += axonram.o
-# contains only the suspend handler for time
-ifeq ($(CONFIG_RTC_CLASS),)
-obj-$(CONFIG_PM) += timer.o
-endif
-
ifeq ($(CONFIG_PPC_MERGE),y)
obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
obj-$(CONFIG_PPC_I8259) += i8259.o
Index: working/arch/powerpc/sysdev/timer.c
===================================================================
--- working.orig/arch/powerpc/sysdev/timer.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Common code to keep time when machine suspends.
- *
- * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
- *
- * GPLv2
- */
-
-#include <linux/time.h>
-#include <linux/sysdev.h>
-#include <asm/rtc.h>
-
-static unsigned long suspend_rtc_time;
-
-/*
- * Reset the time after a sleep.
- */
-static int timer_resume(struct sys_device *dev)
-{
- struct timeval tv;
- struct timespec ts;
- struct rtc_time cur_rtc_tm;
- unsigned long cur_rtc_time, diff;
-
- /* get current RTC time and convert to seconds */
- get_rtc_time(&cur_rtc_tm);
- cur_rtc_time = mktime(cur_rtc_tm.tm_year + 1900,
- cur_rtc_tm.tm_mon + 1,
- cur_rtc_tm.tm_mday,
- cur_rtc_tm.tm_hour,
- cur_rtc_tm.tm_min,
- cur_rtc_tm.tm_sec);
-
- diff = cur_rtc_time - suspend_rtc_time;
-
- /* adjust time of day by seconds that elapsed while
- * we were suspended */
- do_gettimeofday(&tv);
- ts.tv_sec = tv.tv_sec + diff;
- ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC;
- do_settimeofday(&ts);
-
- return 0;
-}
-
-static int timer_suspend(struct sys_device *dev, pm_message_t state)
-{
- struct rtc_time suspend_rtc_tm;
- WARN_ON(!ppc_md.get_rtc_time);
-
- get_rtc_time(&suspend_rtc_tm);
- suspend_rtc_time = mktime(suspend_rtc_tm.tm_year + 1900,
- suspend_rtc_tm.tm_mon + 1,
- suspend_rtc_tm.tm_mday,
- suspend_rtc_tm.tm_hour,
- suspend_rtc_tm.tm_min,
- suspend_rtc_tm.tm_sec);
-
- return 0;
-}
-
-static struct sysdev_class timer_sysclass = {
- .resume = timer_resume,
- .suspend = timer_suspend,
- set_kset_name("timer"),
-};
-
-static struct sys_device device_timer = {
- .id = 0,
- .cls = &timer_sysclass,
-};
-
-static int time_init_device(void)
-{
- int error = sysdev_class_register(&timer_sysclass);
- if (!error)
- error = sysdev_register(&device_timer);
- return error;
-}
-
-device_initcall(time_init_device);
^ permalink raw reply
* [PATCH 3/5] Implement clockevents driver for powerpc
From: Tony Breeds @ 2007-09-19 6:49 UTC (permalink / raw)
To: linuxppc-dev, Paul Mackerras; +Cc: Thomas Gleixner, Realtime Kernel
In-Reply-To: <1190184586.867449.381310088392.qpush@thor>
Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>
---
arch/powerpc/Kconfig | 3
arch/powerpc/kernel/smp.c | 3
arch/powerpc/kernel/time.c | 134 +++++++++++++++++++++++++------------
include/asm-powerpc/time.h | 1
4 files changed, 98 insertions(+), 43 deletions(-)
Index: working/arch/powerpc/Kconfig
===================================================================
--- working.orig/arch/powerpc/Kconfig
+++ working/arch/powerpc/Kconfig
@@ -30,6 +30,9 @@ config GENERIC_TIME
config GENERIC_TIME_VSYSCALL
def_bool y
+config GENERIC_CLOCKEVENTS
+ def_bool y
+
config GENERIC_HARDIRQS
bool
default y
Index: working/arch/powerpc/kernel/smp.c
===================================================================
--- working.orig/arch/powerpc/kernel/smp.c
+++ working/arch/powerpc/kernel/smp.c
@@ -560,6 +560,9 @@ int __devinit start_secondary(void *unus
if (system_state > SYSTEM_BOOTING)
snapshot_timebase();
+ /* FIXME: should be in if() above */
+ secondary_cpu_time_init();
+
spin_lock(&call_lock);
cpu_set(cpu, cpu_online_map);
spin_unlock(&call_lock);
Index: working/arch/powerpc/kernel/time.c
===================================================================
--- working.orig/arch/powerpc/kernel/time.c
+++ working/arch/powerpc/kernel/time.c
@@ -76,6 +76,7 @@
/* powerpc clocksource/clockevent code */
+#include <linux/clockchips.h>
#include <linux/clocksource.h>
static cycle_t timebase_read(void);
@@ -90,6 +91,27 @@ static struct clocksource clocksource_ti
.read = timebase_read,
};
+#define DECREMENTER_MAX 0x7fffffff
+
+static int decrementer_set_next_event(unsigned long evt,
+ struct clock_event_device *dev);
+static void decrementer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *dev);
+
+static struct clock_event_device decrementer_clockevent = {
+ .name = "decrementer",
+ .rating = 200,
+ .shift = 32,
+ .mult = 0, /* To be filled in */
+ .irq = -1,
+ .set_next_event = decrementer_set_next_event,
+ .set_mode = decrementer_set_mode,
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+};
+
+static DEFINE_PER_CPU(struct clock_event_device, decrementers);
+void init_decrementer_clockevent(void);
+
#ifdef CONFIG_PPC_ISERIES
static unsigned long __initdata iSeries_recal_titan;
static signed long __initdata iSeries_recal_tb;
@@ -510,10 +532,12 @@ void __init iSeries_time_init_early(void
void timer_interrupt(struct pt_regs * regs)
{
struct pt_regs *old_regs;
- int next_dec;
int cpu = smp_processor_id();
- unsigned long ticks;
- u64 tb_next_jiffy;
+ struct clock_event_device *evt = &per_cpu(decrementers, cpu);
+
+ /* Ensure a positive value is written to the decrementer, or else
+ * some CPUs will continuue to take decrementer exceptions */
+ set_dec(DECREMENTER_MAX);
#ifdef CONFIG_PPC32
if (atomic_read(&ppc_n_lost_interrupts) != 0)
@@ -523,7 +547,6 @@ void timer_interrupt(struct pt_regs * re
old_regs = set_irq_regs(regs);
irq_enter();
- profile_tick(CPU_PROFILING);
calculate_steal_time();
#ifdef CONFIG_PPC_ISERIES
@@ -531,44 +554,20 @@ void timer_interrupt(struct pt_regs * re
get_lppaca()->int_dword.fields.decr_int = 0;
#endif
- while ((ticks = tb_ticks_since(per_cpu(last_jiffy, cpu)))
- >= tb_ticks_per_jiffy) {
- /* Update last_jiffy */
- per_cpu(last_jiffy, cpu) += tb_ticks_per_jiffy;
- /* Handle RTCL overflow on 601 */
- if (__USE_RTC() && per_cpu(last_jiffy, cpu) >= 1000000000)
- per_cpu(last_jiffy, cpu) -= 1000000000;
-
- /*
- * We cannot disable the decrementer, so in the period
- * between this cpu's being marked offline in cpu_online_map
- * and calling stop-self, it is taking timer interrupts.
- * Avoid calling into the scheduler rebalancing code if this
- * is the case.
- */
- if (!cpu_is_offline(cpu))
- account_process_time(regs);
-
- /*
- * No need to check whether cpu is offline here; boot_cpuid
- * should have been fixed up by now.
- */
- if (cpu != boot_cpuid)
- continue;
+ /*
+ * We cannot disable the decrementer, so in the period
+ * between this cpu's being marked offline in cpu_online_map
+ * and calling stop-self, it is taking timer interrupts.
+ * Avoid calling into the scheduler rebalancing code if this
+ * is the case.
+ */
+ if (!cpu_is_offline(cpu))
+ account_process_time(regs);
- write_seqlock(&xtime_lock);
- tb_next_jiffy = tb_last_jiffy + tb_ticks_per_jiffy;
- if (__USE_RTC() && tb_next_jiffy >= 1000000000)
- tb_next_jiffy -= 1000000000;
- if (per_cpu(last_jiffy, cpu) >= tb_next_jiffy) {
- tb_last_jiffy = tb_next_jiffy;
- do_timer(1);
- }
- write_sequnlock(&xtime_lock);
- }
-
- next_dec = tb_ticks_per_jiffy - ticks;
- set_dec(next_dec);
+ if (evt->event_handler)
+ evt->event_handler(evt);
+ else
+ evt->set_next_event(DECREMENTER_MAX, evt);
#ifdef CONFIG_PPC_ISERIES
if (firmware_has_feature(FW_FEATURE_ISERIES) && hvlpevent_is_pending())
@@ -781,8 +780,58 @@ void __init clocksource_init(void)
printk(KERN_INFO "clocksource: %s mult[%x] shift[%d] registered\n",
clocksource_timebase.name,
clocksource_timebase.mult, clocksource_timebase.shift);
+
+ return;
+}
+
+static int decrementer_set_next_event(unsigned long evt,
+ struct clock_event_device *dev)
+{
+ set_dec(evt);
+ return 0;
+}
+
+static void decrementer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *dev)
+{
+ if (mode != CLOCK_EVT_MODE_ONESHOT)
+ decrementer_set_next_event(DECREMENTER_MAX, dev);
+}
+
+static void register_decrementer_clockevent(int cpu)
+{
+ struct clock_event_device *dec = &per_cpu(decrementers, cpu);
+
+ *dec = decrementer_clockevent;
+ dec->cpumask = cpumask_of_cpu(cpu);
+
+ printk(KERN_ERR "clockevent: %s mult[%lx] shift[%d] cpu[%d]\n",
+ dec->name, dec->mult, dec->shift, cpu);
+
+ clockevents_register_device(dec);
+}
+
+void init_decrementer_clockevent(void)
+{
+ int cpu = smp_processor_id();
+
+ decrementer_clockevent.mult = div_sc(ppc_tb_freq, NSEC_PER_SEC,
+ decrementer_clockevent.shift);
+ decrementer_clockevent.max_delta_ns =
+ clockevent_delta2ns(DECREMENTER_MAX, &decrementer_clockevent);
+ decrementer_clockevent.min_delta_ns = 1000;
+
+ register_decrementer_clockevent(cpu);
}
+void secondary_cpu_time_init(void)
+{
+ /* FIME: Should make unrelatred change to move snapshot_timebase
+ * call here ! */
+ register_decrementer_clockevent(smp_processor_id());
+}
+
+
/* This function is only called on the boot processor */
void __init time_init(void)
{
@@ -898,8 +947,7 @@ void __init time_init(void)
#endif
clocksource_init();
- /* Not exact, but the timer interrupt takes care of this */
- set_dec(tb_ticks_per_jiffy);
+ init_decrementer_clockevent();
}
Index: working/include/asm-powerpc/time.h
===================================================================
--- working.orig/include/asm-powerpc/time.h
+++ working/include/asm-powerpc/time.h
@@ -245,6 +245,7 @@ extern void snapshot_timebases(void);
#define snapshot_timebases() do { } while (0)
#endif
+extern void secondary_cpu_time_init(void);
extern void iSeries_time_init_early(void);
#endif /* __KERNEL__ */
^ permalink raw reply
* Re: [PATCH 1/5] Implement {read,update}_persistent_clock.
From: Tony Breeds @ 2007-09-19 6:53 UTC (permalink / raw)
To: linuxppc-dev, Paul Mackerras; +Cc: Thomas Gleixner, Realtime Kernel
In-Reply-To: <1190184586.867449.381310088392.qpush@thor>
On Wed, Sep 19, 2007 at 04:49:46PM +1000, Tony Breeds wrote:
> With these functions implemented we cooperate better with the generic
> timekeeping code. This obsoletes the need for the timer sysdev as a bonus.
I should have added that this patch series applies on top of Benh's 601
fixes.
Yours Tony
linux.conf.au http://linux.conf.au/ || http://lca2008.linux.org.au/
Jan 28 - Feb 02 2008 The Australian Linux Technical Conference!
^ permalink raw reply
* Re: [PATCH 1/1] ppc64: Convert cpu_sibling_map to a per_cpu data array ppc64 v2
From: Stephen Rothwell @ 2007-09-19 6:56 UTC (permalink / raw)
To: travis
Cc: linux-mm, Andi Kleen, linux-kernel, linuxppc-dev, sparclinux,
Andrew Morton, Christoph Lameter
In-Reply-To: <20070917183507.506104000@sgi.com>
[-- Attachment #1: Type: text/plain, Size: 541 bytes --]
Hi Mike,
On Mon, 17 Sep 2007 11:35:08 -0700 travis@sgi.com wrote:
>
> v2:
>
> This patch applies after:
>
> convert-cpu_sibling_map-to-a-per_cpu-data-array-ppc64.patch
>
> and should fix the "reference cpu_sibling_map before setup_per_cpu_areas()
> has been called" problem. In addtion, the cpu_sibiling_map macro has been
> removed [this was missed in my original submission.]
This one make it work, thanks.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: PSC in UART mode on TQM5200S
From: Leopold Stotch @ 2007-09-19 7:04 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-embedded
In-Reply-To: <fa686aa40709180701w17273a11wda8c9ece79aad483@mail.gmail.com>
Thank you for the answer, Grant !
I knew nothing about port_config register before your answer :-(
I haven't changed any processor registers yet
because i'm still searching where i can do this.
Can you tell me, is it UBoot specific or kernel specific or both ?
And i already know about MPC5200's device tree in 2.6.x kernel but not
in 2.4.x...
On 9/18/07, Grant Likely <grant.likely@secretlab.ca> wrote:
> On 9/18/07, Leopold Stotch <l.butterz@gmail.com> wrote:
> > Hello, everyone !
> >
> > I have TQM5200S module and development board.
> > It runs factory UBoot and latest DENX's linuxppc_2_4_devel kernel.
> > I want to configure all TQM5200S's onboard PSC's as UART's.
> > TQM5200S's onboard PSC's are connected to custom board
> > that makes all electrical things as my hardware engineer says...
> > So changed
> > $HOME/linuxppc_2_4_devel/arch/ppc/platforms/tqm5200.h
> > the following way:
> >
> > #ifdef CONFIG_PS2MULT
> > #define RS_TABLE_SIZE 4
> > #else
> > #if defined(CONFIG_SPI_EVAL) || defined(CONFIG_TB5200)
> > #define RS_TABLE_SIZE 2
> > #elif defined(CONFIG_CAM5200)
> > #define RS_TABLE_SIZE 6
> > #else
> > #define RS_TABLE_SIZE 3
> > #endif
> > #endif
> >
> > changed to
> >
> > #ifdef CONFIG_PS2MULT
> > #define RS_TABLE_SIZE 4
> > #else
> > #if defined(CONFIG_SPI_EVAL) || defined(CONFIG_TB5200)
> > #define RS_TABLE_SIZE 2
> > #elif defined(CONFIG_CAM5200)
> > #define RS_TABLE_SIZE 6
> > #else
> > #define RS_TABLE_SIZE 6
> > #endif
> > #endif
> >
> > and
> >
> > #else /* default */
> > #define SERIAL_PORT_DFNS \
> > STD_PSC_OP(1) \
> > STD_PSC_OP(2) \
> > STD_PSC_OP(3)
> > #endif
> >
> > changed to
> >
> > #else /* default */
> > #define SERIAL_PORT_DFNS \
> > STD_PSC_OP(1) \
> > STD_PSC_OP(2) \
> > STD_PSC_OP(3) \
> > STD_PSC_OP(4) \
> > STD_PSC_OP(5) \
> > STD_PSC_OP(6)
> > #endif
> >
> > After rebuilding the kernel, dmesg says:
> >
> > ...
> > ttyS0 on PSC1
> > ttyS1 on PSC2
> > ttyS2 on PSC3
> > ttyS3 on PSC4
> > ttyS4 on PSC5
> > ttyS5 on PSC6
> > ...
> >
> > But when i do "echo 1 > /dev/ttyS4" i receive nothing at the other end.
>
> Have you made the appropriate changes to the port_config register?
>
> Cheers,
> g.
>
>
>
> --
> Grant Likely, B.Sc., P.Eng.
> Secret Lab Technologies Ltd.
> grant.likely@secretlab.ca
> (403) 399-0195
>
--
Best regards,
Leopold Stotch
^ 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