* Re: [PATCH 2/5] Implement generic time of day clocksource for powerpc machines.
From: Daniel Walker @ 2007-09-20 1:54 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Thomas Gleixner, johnstul, Realtime Kernel
In-Reply-To: <18161.53509.342082.588911@cargo.ozlabs.ibm.com>
On Thu, 2007-09-20 at 11:46 +1000, Paul Mackerras wrote:
> Daniel Walker writes:
>
> > On Thu, 2007-09-20 at 10:52 +1000, Paul Mackerras wrote:
> > > Daniel Walker writes:
> > >
> > > > If you switch to the rtc do the shift and mult need to change?
> > >
> > > You can't switch; any given CPU chip will have either the RTC or the
> > > timebase but not both.
> >
> > The code is switching between to clock read functions .. If they are
>
> What part of "you can't switch" wasn't clear? __USE_RTC() is a
> constant on any given machine.
Maybe say "It a constant" up front .. The value that is output from the
clocksource read is converted to nanoseconds .. This clocksource is only
designed to work with the timebase, so it doesn't make sense to output
an rtc value.
Daniel
^ permalink raw reply
* Re: [PATCH 2/5] Implement generic time of day clocksource for powerpc machines.
From: Paul Mackerras @ 2007-09-20 1:46 UTC (permalink / raw)
To: Daniel Walker; +Cc: linuxppc-dev, Thomas Gleixner, johnstul, Realtime Kernel
In-Reply-To: <1190252151.11899.66.camel@imap.mvista.com>
Daniel Walker writes:
> On Thu, 2007-09-20 at 10:52 +1000, Paul Mackerras wrote:
> > Daniel Walker writes:
> >
> > > If you switch to the rtc do the shift and mult need to change?
> >
> > You can't switch; any given CPU chip will have either the RTC or the
> > timebase but not both.
>
> The code is switching between to clock read functions .. If they are
What part of "you can't switch" wasn't clear? __USE_RTC() is a
constant on any given machine.
Paul.
^ permalink raw reply
* Patches added to powerpc.git for-2.6.24 branch
From: Paul Mackerras @ 2007-09-20 1:42 UTC (permalink / raw)
To: linuxppc-dev
Adrian Bunk (1):
[POWERPC] Remove APUS support from arch/ppc
Andre Detsch (1):
[POWERPC] spufs: Fix race condition on gang->aff_ref_spu
Anton Vorontsov (3):
[POWERPC] QE: extern par_io_config_pin and par_io_data_set funcs
[POWERPC] fsl_soc: add support for fsl_spi
[POWERPC] MPC832x_RDB: Update dts to use SPI1 in QE, register mmc_spi stub
Domen Puncer (1):
[POWERPC] MPC5200 low power mode
Guennadi Liakhovetski (1):
[POWERPC] linkstation updates
Jeremy Kerr (6):
[POWERPC] spufs: Remove asmlinkage from do_spu_create
[POWERPC] spufs: Remove spu_harvest
[POWERPC] cell: Unify spufs syscall path
[POWERPC] spufs: Remove asmlinkage from spufs_calls
[POWERPC] spufs: Fix restore_decr_wrapped() to match CBE Handbook
[POWERPC] cell: Remove DEBUG for SPU callbacks
Jesper Juhl (1):
[POWERPC] Don't cast kmalloc return value in ibmebus.c
John Rigby (1):
[POWERPC] 52xx: Fix mpc52xx_uart_of_assign to use correct index
Jon Loeliger (2):
[POWERPC] 86xx: Remove unnecessary loops_per_jiffy initialization code.
[POWERPC] 85xx: Remove unnecessary loops_per_jiffy initialization code.
Kumar Gala (10):
ucc_geth: kill unused include
[POWERPC] 85xx: Renamed mpc8544_ds.c to mpc85xx_ds.c
[POWERPC] 85xx: Clean up from 85xx_ds rename
[POWERPC] Handle alignment faults on SPE load/store instructions
[POWERPC] 85xx: Add basic Uniprocessor MPC8572 DS port
[POWERPC] DTS cleanup
[POWERPC] Move PCI nodes to be sibilings with SOC nodes
[POWERPC] 83xx: Removed PCI exclude of PHB
[POWERPC] Add cpu feature for SPE handling
[POWERPC] Fix modpost warnings from head*.S on ppc32
Michael Ellerman (15):
[POWERPC] spufs: Extract the file descriptor search logic in SPU coredump code
[POWERPC] spufs: Remove ctx_info and ctx_info_list
[POWERPC] spufs: Call spu_acquire_saved() before calculating the SPU note sizes
[POWERPC] spufs: Use computed sizes/#defines rather than literals in SPU coredump code
[POWERPC] spufs: Write some SPU coredump values as ASCII
[POWERPC] spufs: Correctly calculate the size of the local-store to dump
[POWERPC] spufs: Don't return -ENOSYS as extra notes size if spufs is not loaded
[POWERPC] spufs: Get rid of spufs_coredump_num_notes, it's not needed if we NULL terminate
[POWERPC] spufs: Internal __spufs_get_foo() routines should take a spu_context *
[POWERPC] spufs: Add contents of npc file to SPU coredumps
[POWERPC] spufs: Combine spufs_coredump_calls with spufs_calls
[POWERPC] spufs: Cleanup ELF coredump extra notes logic
[POWERPC] spufs: Handle errors in SPU coredump code, and support coredump to a pipe
[POWERPC] spufs: Respect RLIMIT_CORE in spu coredump code
[POWERPC] spufs: Add DEFINE_SPUFS_ATTRIBUTE()
Michael Neuling (1):
[POWERPC] Remove barriers from the SLB shadow buffer update
Olaf Hering (1):
[POWERPC] Fix pmac_zilog debug arg
Scott Wood (2):
[POWERPC] fsl_soc.c cleanup
[PPC] Add clrbits8 and setbits8.
Sebastian Siewior (2):
[POWERPC] spufs: Make file-internal functions & variables static
[POWERPC] spufs: Make isolated loader properly aligned
Stephen Rothwell (4):
[POWERPC] Fix section mismatch in PCI code
[POWERPC] Remove cmd_line from head*.S
[POWERPC] Size swapper_pg_dir correctly
[POWERPC] FWNMI is only used on pSeries
Timur Tabi (2):
[POWERPC] add clrsetbits macros
[POWERPC] 86xx: Fix definition of global-utilites structure
^ permalink raw reply
* Re: [PATCH 2/5] Implement generic time of day clocksource for powerpc machines.
From: Daniel Walker @ 2007-09-20 1:35 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Thomas Gleixner, johnstul, Realtime Kernel
In-Reply-To: <18161.50240.599267.768383@cargo.ozlabs.ibm.com>
On Thu, 2007-09-20 at 10:52 +1000, Paul Mackerras wrote:
> Daniel Walker writes:
>
> > If you switch to the rtc do the shift and mult need to change?
>
> You can't switch; any given CPU chip will have either the RTC or the
> timebase but not both.
The code is switching between to clock read functions .. If they are
running at different frequencies then the time isn't going to be
converted to nanosecond properly.
So is the rtc running at the same frequency as the timebase? I'd guess
no..
> > > + /* XXX this assumes clock->shift == 22 */
> > > + /* 4611686018 ~= 2^(20+64-22) / 1e9 */
> > > + t2x = (u64) clock->mult * 4611686018ULL;
> >
> > It might make the code more readable if you put that constant into a
> > macro that gives it a name.
>
> The comment already gives more information than some arbitrary name
> would.
I'm not a powerpc expect, but I have no idea what that constant is..
Daniel
^ permalink raw reply
* Cleanups for physmap_of.c (v2)
From: David Gibson @ 2007-09-20 1:22 UTC (permalink / raw)
To: Vitaly Wool, David Woodhouse; +Cc: Paul Mackerras, 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.
- parse_obsolete_partitions() now returns 0 if no partition
information is found, instead of returning -ENOENT which the caller
had to handle specially.
- (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>
---
Reworked to apply on top of jwb's bugfix for not correctly handling
parse_obsolete_partitions() -ENOENT return value.
Index: working-2.6/drivers/mtd/maps/physmap_of.c
===================================================================
--- working-2.6.orig/drivers/mtd/maps/physmap_of.c 2007-09-20 11:16:37.000000000 +1000
+++ working-2.6/drivers/mtd/maps/physmap_of.c 2007-09-20 11:18:22.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;
@@ -50,17 +47,15 @@ static int parse_obsolete_partitions(str
part = of_get_property(dp, "partitions", &plen);
if (!part)
- return -ENOENT;
+ return 0; /* No partitions found */
dev_warn(&dev->dev, "Device tree uses obsolete partition map binding\n");
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,89 +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);
- if (nr_parts == -ENOENT)
- nr_parts = 0;
- }
+ 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);
}
@@ -229,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;
}
@@ -283,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;
}
@@ -297,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",
@@ -337,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
* Re: [PATCH v2] [POWERPC] Fix build errors when BLOCK=n
From: Paul Mackerras @ 2007-09-20 0:58 UTC (permalink / raw)
To: Emil Medve
Cc: linux-ide, linuxppc-dev, kumar.gala, bzolnier, linuxppc-embedded
In-Reply-To: <1190227172-593-1-git-send-email-Emilian.Medve@Freescale.com>
Emil Medve writes:
> --- a/arch/powerpc/kernel/ppc_ksyms.c
> +++ b/arch/powerpc/kernel/ppc_ksyms.c
> @@ -12,12 +12,15 @@
> #include <linux/irq.h>
> #include <linux/pci.h>
> #include <linux/delay.h>
> +#if defined(CONFIG_IDE) || defined(CONFIG_IDE_MODULE)
> #include <linux/ide.h>
> +#endif
Why are we still including linux/ide.h at all here?
> #include <linux/bitops.h>
>
> #include <asm/page.h>
> #include <asm/semaphore.h>
> #include <asm/processor.h>
> +#include <asm/cacheflush.h>
What's the point of adding this?
Paul.
^ permalink raw reply
* Re: [PATCH 2/5] Implement generic time of day clocksource for powerpc machines.
From: Paul Mackerras @ 2007-09-20 0:52 UTC (permalink / raw)
To: Daniel Walker; +Cc: linuxppc-dev, Thomas Gleixner, johnstul, Realtime Kernel
In-Reply-To: <1190216594.11899.3.camel@imap.mvista.com>
Daniel Walker writes:
> If you switch to the rtc do the shift and mult need to change?
You can't switch; any given CPU chip will have either the RTC or the
timebase but not both.
> > + /* XXX this assumes clock->shift == 22 */
> > + /* 4611686018 ~= 2^(20+64-22) / 1e9 */
> > + t2x = (u64) clock->mult * 4611686018ULL;
>
> It might make the code more readable if you put that constant into a
> macro that gives it a name.
The comment already gives more information than some arbitrary name
would.
Paul.
^ permalink raw reply
* Re: [PATCH 2/3] usb: ehci-ppc-of dts bindings.
From: David Gibson @ 2007-09-20 0:52 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: linuxppc-dev, linux-usb-devel
In-Reply-To: <d0e5786123822b4d178932d9048f6a22@kernel.crashing.org>
On Wed, Sep 19, 2007 at 06:50:02PM +0200, Segher Boessenkool wrote:
> >>> + Required properties:
> >>> + - device_type : should be "usb".
> >> No device_type please. The published USB binding doesn't define
> >> one on purpose.
> >
> > Could you please, explain why?
> > Sorry, I don't think I get the concept of device description here.
>
> "device_type" is meant to be used only by OF for determining the OF
> programming model for a device. No such thing has been defined for
> USB busses, so the USB binding does not define a "device_type" either.
>
> Nothing in a flat device tree should ever define a device_type, except
> perhaps for compatibility with legacy kernel code.
This is not necessarily true. As Segher says, device_type originally
indicated the OF programming model for a device. However, we've
extended the notion for the flat device tree to allow device_type to
cover "device classes" which could have certain common properties and
semantics. However, in this case, a meaningful class binding must
already be defined: it might make sense for usb to have a defined
device_type, but it's not been defined so far, so for now you must
omit device_type (if a device_type is defined in future, it's easier
to add legacy hooks that will include devices which are missing the
relevant device_type marker than to work around devices which *do*
have the marker, but pre-date and don't follow the defined class
binding).
> >>> + - compatible : should be "ehci".
> >> Just "ehci" isn't enough -- compare to OHCI, which is the name for
> >> a kind of USB host controller as well as for a kind of Firewire
> >> host controller.
> >
> > Actually, I though device type="usb" + compatible="ehci" would be
> > enough.
>
> "compatible" values are their own namespace, you should in principle
> be able to find a driver for a device with them without having to look
> at other properties.
Yes. Regardless of the state of any class / device_type binding, the
compatible property *alone* should be sufficient to select a 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
* Re: [PATCH 10/25] spusched: fix null pointer dereference in find_victim
From: Jeremy Kerr @ 2007-09-20 0:13 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Christoph Hellwig
In-Reply-To: <20070914074424.GD18011@lst.de>
Christoph,
> Didn't we want to try to get this into 2.6.23?
Done! it's in -rc7 :)
Jeremy
^ permalink raw reply
* Re: Cleanups for physmap_of.c
From: David Gibson @ 2007-09-19 23:49 UTC (permalink / raw)
To: Josh Boyer; +Cc: Vitaly Wool, Paul Mackerras, linuxppc-dev
In-Reply-To: <20070919071433.69daf024@weaponx.rchland.ibm.com>
On Wed, Sep 19, 2007 at 07:14:33AM -0500, Josh Boyer wrote:
> On Wed, 19 Sep 2007 14:16:46 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
>
> > 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.
>
> Most of that looks good. Just a couple issues below. Mostly it
> doesn't apply cleanly to my tree because you didn't base if off of the
> patch I sent out last week to fix optional partitions.
Ah, oops. Didn't remember that patch.
> > - (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.
>
> Later when? If we're all in agreement, then why don't we just apply
> your patch after you fix it up and I can move the file in my git tree.
> That way we don't forget about it.
Ok by me. Well, except that it will need Makefile and Kconfig changes
for that, too. I was going to send another patch with that once this
one was reviewed and merged.
[snip]
> > @@ -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;
>
> You dropped the printk here. Any particular reason why?
I thought the the -ENOMEM was specific enough; we don't give
explanatory messages for other ENOMEM conditions in the driver.
> >
> > 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);
>
> You reintroduced the optional partitions bug I fixed with:
>
> http://git.infradead.org/?p=users/jwboyer/powerpc.git;a=commit;h=7cafc8f8c89d1f49039b7c345ca832fbd2d1e639
Ah yes. Actually on consideration, your patch seems a roundabout way
of fixing it. I'm inclined instead to change
parse_obsolete_partitions() to return 0 instead of -ENOENT.
I guess I'll fold that fix in.
--
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: Patches for 2.6.24
From: Grant Likely @ 2007-09-19 23:51 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <fa686aa40709120902q28d4d8bcr93020005dcf4f6f7@mail.gmail.com>
Paul,
Here are the links to the patches I need pulled.
Cheers,
g.
On 9/12/07, Grant Likely <grant.likely@secretlab.ca> wrote:
> On 9/12/07, Kumar Gala <galak@kernel.crashing.org> wrote:
> > On Sep 12, 2007, at 10:48 AM, Grant Likely wrote:
> > > http://patchwork.ozlabs.org/linuxppc/patch?id=13235
> > > http://patchwork.ozlabs.org/linuxppc/patch?id=13249
> >
> > bootwrapper patches should be ack'd by david gibson and picked up by
> > paul at this point.
>
> Okay, David has already acked these. Paulus, can you please pick them up?
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
^ permalink raw reply
* Re: Configuration-Problem ext-interrupt on mpc52xx
From: David Gibson @ 2007-09-19 23:40 UTC (permalink / raw)
To: S. Fricke; +Cc: linuxppc-dev
In-Reply-To: <20070919190146.GI5682@sfrouter>
[-- Attachment #1: Type: text/plain, Size: 1906 bytes --]
On Wed, Sep 19, 2007 at 09:01:46PM +0200, S. Fricke wrote:
> Hello,
>
> > On 9/19/07, S. Fricke <silvio.fricke@googlemail.com> wrote:
> > > Hi,
> > >
> > > how can i configure an "ext interrupt" to high-level? I want a interruption on
> > > IRQ2, but I checked with an oscilloscope that the pin has a low state and I
> > > needs a high state.
> > >
> > > I have tried, after I got the irq (with irq_of_parse_and_map), set it with
> > >
> > > set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
> > >
> > > But I think it is a system-configuration (irq_desc) and no
> > > device-configuration.
> >
> > You shouldn't need to do this. You set your sense level in the device tree.
> >
> > From your previous email, your device node looks like this:
> > > intpin@0 {
> > > interrupt-parent = <500>;
> > > interrupts = <1 2 2>;
> > > };
> >
> > Which is IRQ2, EDGE_FALLING.
> >
> > If you change your interrupts property to <1 2 0>, then your sense is
> > set to LEVEL_HIGH. (Seriously, you need to read the interrupts
> > section of Documentation/powerpc/mpc52xx-device-tree-bindings.txt.)
>
> I have read it! But another driver on Boot-time pulled my interrupt
Erm.. if the interrupt is shared with something else which expects a
different trigger/polarity, you're kind of stuffed....
> to low, I can't do anything except for looking at the oscilloscope
>
> I'm going to disable all unneeded drivers tomorrow morning.
>
> TIA:
> Silvio Fricke
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
--
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
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH] phy: export phy_mii_ioctl
From: Jon Smirl @ 2007-09-19 21:18 UTC (permalink / raw)
To: Domen Puncer; +Cc: netdev, linuxppc-embedded
In-Reply-To: <9e4733910709191144l6ddb66eaq84f3d1488bcf1443@mail.gmail.com>
On 9/19/07, Jon Smirl <jonsmirl@gmail.com> wrote:
> This needs a cleanup too, but it is unrelated....
Another set of related warnings that need clean up....
CC drivers/spi/mpc52xx_psc_spi.o
drivers/spi/mpc52xx_psc_spi.c: In function 'mpc52xx_psc_spi_activate_cs':
drivers/spi/mpc52xx_psc_spi.c:110: warning: passing argument 1 of
'in_be16' from incompatible pointer type
drivers/spi/mpc52xx_psc_spi.c:116: warning: passing argument 1 of
'out_be16' from incompatible pointer type
drivers/spi/mpc52xx_psc_spi.c: In function 'mpc52xx_psc_spi_port_config':
drivers/spi/mpc52xx_psc_spi.c:417: warning: passing argument 1 of
'out_be16' from incompatible pointer type
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply
* Re: [PATCH] powerpc mm init_32 gdb regions
From: Kumar Gala @ 2007-09-19 20:31 UTC (permalink / raw)
To: Ed Swarthout; +Cc: linuxppc-dev
In-Reply-To: <11901785761816-git-send-email-Ed.Swarthout@freescale.com>
On Sep 19, 2007, at 12:09 AM, Ed Swarthout wrote:
> 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
> +
should this be #ifdef CONFIG_PROC_KCORE protected?
> +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
* Re: [PATCH] powerpc: rheap-managed bootmem allocator
From: Timur Tabi @ 2007-09-19 20:16 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <7307F27A-9C96-464A-9285-55DAB9A9A89D@kernel.crashing.org>
Kumar Gala wrote:
> seems like we should have a way to set bootmem_size via board/platform
> code and not require a cmdline arg.
I can add a Kconfig option for it, but since there is no Kconfig for the rheap
itself, I didn't know where to put it. Once Sylvain's patch is accepted, I
can update this patch by adding this Kconfig option:
config PPC_RHEAP_BOOTMEM
int "Default size (in KB) of the rheap bootmem allocator"
default 0
---help---
This is the default size (in KB) of the boot memory to allocate (via
alloc_bootmem). This value can be overridden on the kernel command
line using the "rhbootmem" option (e.g. "rhbootmem=2M")
One thing I don't like, however, is the name. It doesn't really make sense to
call it the "rheap bootmem allocator" because the fact that it uses an rheap
is hidden from the callers of rheap_bootmem_alloc().
--
Timur Tabi
Linux Kernel Developer @ Freescale
^ permalink raw reply
* Re: [PATCH] powerpc: rheap-managed bootmem allocator
From: Kumar Gala @ 2007-09-19 20:12 UTC (permalink / raw)
To: Timur Tabi; +Cc: linuxppc-dev
In-Reply-To: <1190229304592-git-send-email-timur@freescale.com>
On Sep 19, 2007, at 2:15 PM, Timur Tabi wrote:
> Add the ability to allocate a block of memory via alloc_bootmem()
> and manage
> that memory with a remote heap (rheap).
>
> Signed-off-by: Timur Tabi <timur@freescale.com>
> ---
>
> This patch will conflict with Sylvain's "powerpc: Changes the
> config mechanism
> for rheap" patch, but that patch hasn't been accepted yet, so I'm
> posting this
> for review and comment.
>
> arch/powerpc/lib/rheap.c | 79 ++++++++++++++++++++++++++++++++
> +++++++++++
> include/asm-powerpc/rheap.h | 4 ++
> 2 files changed, 83 insertions(+), 0 deletions(-)
>
> diff --git a/arch/powerpc/lib/rheap.c b/arch/powerpc/lib/rheap.c
> index ada5b42..d2c8913 100644
> --- a/arch/powerpc/lib/rheap.c
> +++ b/arch/powerpc/lib/rheap.c
> @@ -18,6 +18,8 @@
> #include <linux/mm.h>
> #include <linux/err.h>
> #include <linux/slab.h>
> +#include <linux/bootmem.h>
> +#include <linux/module.h>
>
> #include <asm/rheap.h>
>
> @@ -729,3 +731,80 @@ void rh_dump_blk(rh_info_t * info, rh_block_t
> * blk)
> "blk @0x%p: 0x%lx-0x%lx (%u)\n",
> blk, blk->start, blk->start + blk->size, blk->size);
> }
> +
> +/* Bootmem-allocated rheap
> + *
> + * If the "rhbootmem=X" command-line parameter is specified, then
> the RHEAP
> + * code will allocate a chunk of memory using alloc_bootmem() and
> create an
> + * rheap for it.
> +*/
> +
> +static rh_info_t bootmem_rh_info;
> +static rh_block_t bootmem_rh_block[16];
> +
> +static void *bootmem_ptr;
> +static unsigned long bootmem_size;
> +
> +static int __init early_parse_rhbootmem(char *p)
> +{
> + if (!p)
> + return 1;
> +
> + bootmem_size = _ALIGN_UP(memparse(p, &p), 32);
> +
> + return 0;
seems like we should have a way to set bootmem_size via board/
platform code and not require a cmdline arg.
> +}
> +early_param("rhbootmem", early_parse_rhbootmem);
> +
^ permalink raw reply
* Re: [PATCH v2] [POWERPC] Fix build errors when BLOCK=n
From: Bartlomiej Zolnierkiewicz @ 2007-09-19 20:00 UTC (permalink / raw)
To: Emil Medve; +Cc: linux-ide, linuxppc-dev, kumar.gala, paulus, linuxppc-embedded
In-Reply-To: <1190227172-593-1-git-send-email-Emilian.Medve@Freescale.com>
On Wednesday 19 September 2007, Emil Medve wrote:
> These are the symptom error messages:
>
> CC arch/powerpc/kernel/setup_32.o
> In file included from include/linux/blkdev.h:17,
> from include/linux/ide.h:13,
> from arch/powerpc/kernel/setup_32.c:13:
> include/linux/bsg.h:67: warning: 'struct request_queue' declared inside parameter list
> include/linux/bsg.h:67: warning: its scope is only this definition or declaration, which is probably not what you want
> include/linux/bsg.h:71: warning: 'struct request_queue' declared inside parameter list
> In file included from arch/powerpc/kernel/setup_32.c:13:
> include/linux/ide.h:857: error: field 'wrq' has incomplete type
>
> CC arch/powerpc/kernel/ppc_ksyms.o
> In file included from include/linux/blkdev.h:17,
> from include/linux/ide.h:13,
> from arch/powerpc/kernel/ppc_ksyms.c:15:
> include/linux/bsg.h:67: warning: 'struct request_queue' declared inside parameter list
> include/linux/bsg.h:67: warning: its scope is only this definition or declaration, which is probably not what you want
> include/linux/bsg.h:71: warning: 'struct request_queue' declared inside parameter list
> In file included from arch/powerpc/kernel/ppc_ksyms.c:15:
> include/linux/ide.h:857: error: field 'wrq' has incomplete type
>
> 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
>
> Moved the EXPORT_SYMBOL(ppc_ide_md) from ppc_ksysms.c next to its declaration
> in setup_32.c
>
> Signed-off-by: Emil Medve <Emilian.Medve@Freescale.com>
looks OK for me
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
^ permalink raw reply
* Re: Sequoia kernel crash workaround.
From: Josh Boyer @ 2007-09-19 20:08 UTC (permalink / raw)
To: Olof Johansson; +Cc: linuxppc-dev, Josh Boyer, Stefan Roese, David Gibson
In-Reply-To: <20070919193024.GA28163@lixom.net>
On Wed, 19 Sep 2007 14:30:24 -0500
Olof Johansson <olof@lixom.net> wrote:
> On Wed, Sep 19, 2007 at 09:19:47PM +0200, Stefan Roese wrote:
> > Hi Valentine,
> >
> > On Wednesday 19 September 2007, Valentine Barshak wrote:
> > > Disabling write pipelining really helps.
> > > Josh, David, what is the right place to put this workaround to?
> > >
> > > Is it OK to do mtdcr(PLB4A0_ACR, mfdcr(PLB4A0_ACR) & ~PLB4_WRP); in
> > > arch/powerpc/boot/cuboot-sequoia.c:sequoia_fixups()?
> > > or
> > > should this be done in
> > > arch/powerpc/platforms/44x/sequoia.c:sequoia_setup_arch()
> > > with dcr_map, dcr_read/write stuff?
> >
> > I vote for putting it into sequoia.c, since it's very likely to happen that
> > Sequoia will at one point be booted without the bootwrapper. Or perhaps it
> > should go into some common code checking the PVR and disabling it when this
> > 440EPx/GRx is detected, since all those boards are affected.
>
> This is what we have setup_cpu functions in the cpu table for. Please
> put it there instead of in board code.
Yes, agreed.
josh
^ permalink raw reply
* [PATCH v2] qe: miscellaneous code improvements and fixes to the QE library
From: Timur Tabi @ 2007-09-19 20:08 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Timur Tabi
This patch makes numerous miscellaneous code improvements to the QE library.
1. Remove struct ucc_common and merge ucc_init_guemr() into ucc_set_type()
(every caller of ucc_init_guemr() also calls ucc_set_type()). Modify all
callers of ucc_set_type() accordingly.
2. Remove the unused enum ucc_pram_initial_offset.
3. Refactor qe_setbrg(), also implement work-around for errata QE_General4.
4. Several printk() calls were missing the terminating \n.
5. Add __iomem where needed.
6. In ucc_slow_init() the RBASE and TBASE registers in the PRAM were programmed
with the wrong value.
7. Add the protocol type to struct us_info and updated ucc_slow_init() to
use it, instead of always programming QE_CR_PROTOCOL_UNSPECIFIED.
8. Rename ucc_slow_restart_x() to ucc_slow_restart_tx()
9. Add several macros in qe.h (mostly for slow UCC support, but also to
standardize some naming convention) and remove several unused macros.
10. Update ucc_geth.c to use the new macros.
11. Add ucc_slow_info.protocol to specify which QE_CR_PROTOCOL_xxx protcol
to use when initializing the UCC in ucc_slow_init().
12. Rename ucc_slow_pram.rfcr to rbmr and ucc_slow_pram.tfcr to tbmr, since
these are the real names of the registers.
Signed-off-by: Timur Tabi <timur@freescale.com>
---
Applied changes based on Scott's suggestions.
This patch applies on top of Anton Vorontsov's patch "ucc_geth: fix compilation",
which has been applied to the netdev tree, but not the powerpc tree.
arch/powerpc/sysdev/qe_lib/qe.c | 36 +++--
arch/powerpc/sysdev/qe_lib/qe_ic.c | 2 -
arch/powerpc/sysdev/qe_lib/qe_io.c | 35 ++---
arch/powerpc/sysdev/qe_lib/ucc.c | 68 ++++++----
arch/powerpc/sysdev/qe_lib/ucc_fast.c | 127 ++++++++---------
arch/powerpc/sysdev/qe_lib/ucc_slow.c | 48 +++----
drivers/net/ucc_geth.c | 2 +-
include/asm-powerpc/immap_qe.h | 23 +--
include/asm-powerpc/qe.h | 243 +++++++++++++++++++++++----------
include/asm-powerpc/ucc.h | 24 +---
include/asm-powerpc/ucc_slow.h | 9 +-
11 files changed, 345 insertions(+), 272 deletions(-)
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index 90f8740..3d57d38 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -141,7 +141,7 @@ EXPORT_SYMBOL(qe_issue_cmd);
* 16 BRGs, which can be connected to the QE channels or output
* as clocks. The BRGs are in two different block of internal
* memory mapped space.
- * The baud rate clock is the system clock divided by something.
+ * The BRG clock is the QE clock divided by 2.
* It was set up long ago during the initial boot phase and is
* is given to us.
* Baud rate clocks are zero-based in the driver code (as that maps
@@ -165,28 +165,38 @@ unsigned int get_brg_clk(void)
return brg_clk;
}
-/* This function is used by UARTS, or anything else that uses a 16x
- * oversampled clock.
+/* Program the BRG to the given sampling rate and multiplier
+ *
+ * @brg: the BRG, 1-16
+ * @rate: the desired sampling rate
+ * @multiplier: corresponds to the value programmed in GUMR_L[RDCR] or
+ * GUMR_L[TDCR]. E.g., if this BRG is the RX clock, and GUMR_L[RDCR]=01,
+ * then 'multiplier' should be 8.
+ *
+ * Also note that the value programmed into the BRGC register must be even.
*/
-void qe_setbrg(u32 brg, u32 rate)
+void qe_setbrg(unsigned int brg, unsigned int rate, unsigned int multiplier)
{
- volatile u32 *bp;
u32 divisor, tempval;
- int div16 = 0;
+ u32 div16 = 0;
- bp = &qe_immr->brg.brgc[brg];
+ divisor = get_brg_clk() / (rate * multiplier);
- divisor = (get_brg_clk() / rate);
if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
- div16 = 1;
+ div16 = QE_BRGC_DIV16;
divisor /= 16;
}
- tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | QE_BRGC_ENABLE;
- if (div16)
- tempval |= QE_BRGC_DIV16;
+ /* Errata QE_General4, which affects some MPC832x and MPC836x SOCs, says
+ that the BRG divisor must be even if you're not using divide-by-16
+ mode. */
+ if (!div16 && (divisor & 1))
+ divisor++;
+
+ tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
+ QE_BRGC_ENABLE | div16;
- out_be32(bp, tempval);
+ out_be32(&qe_immr->brg.brgc[brg - 1], tempval);
}
/* Initialize SNUMs (thread serial numbers) according to
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index 55e6f39..9a2d1ed 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -405,8 +405,6 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags)
set_irq_data(qe_ic->virq_high, qe_ic);
set_irq_chained_handler(qe_ic->virq_high, qe_ic_cascade_high);
}
-
- printk("QEIC (%d IRQ sources) at %p\n", NR_QE_IC_INTS, qe_ic->regs);
}
void qe_ic_set_highest_priority(unsigned int virq, int high)
diff --git a/arch/powerpc/sysdev/qe_lib/qe_io.c b/arch/powerpc/sysdev/qe_lib/qe_io.c
index e32b45b..a114cb0 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_io.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_io.c
@@ -195,29 +195,22 @@ EXPORT_SYMBOL(par_io_of_config);
#ifdef DEBUG
static void dump_par_io(void)
{
- int i;
+ unsigned int i;
- printk(KERN_INFO "PAR IO registars:\n");
- printk(KERN_INFO "Base address: 0x%08x\n", (u32) par_io);
+ printk(KERN_INFO "%s: par_io=%p\n", __FUNCTION__, par_io);
for (i = 0; i < num_par_io_ports; i++) {
- printk(KERN_INFO "cpodr[%d] : addr - 0x%08x, val - 0x%08x\n",
- i, (u32) & par_io[i].cpodr,
- in_be32(&par_io[i].cpodr));
- printk(KERN_INFO "cpdata[%d]: addr - 0x%08x, val - 0x%08x\n",
- i, (u32) & par_io[i].cpdata,
- in_be32(&par_io[i].cpdata));
- printk(KERN_INFO "cpdir1[%d]: addr - 0x%08x, val - 0x%08x\n",
- i, (u32) & par_io[i].cpdir1,
- in_be32(&par_io[i].cpdir1));
- printk(KERN_INFO "cpdir2[%d]: addr - 0x%08x, val - 0x%08x\n",
- i, (u32) & par_io[i].cpdir2,
- in_be32(&par_io[i].cpdir2));
- printk(KERN_INFO "cppar1[%d]: addr - 0x%08x, val - 0x%08x\n",
- i, (u32) & par_io[i].cppar1,
- in_be32(&par_io[i].cppar1));
- printk(KERN_INFO "cppar2[%d]: addr - 0x%08x, val - 0x%08x\n",
- i, (u32) & par_io[i].cppar2,
- in_be32(&par_io[i].cppar2));
+ printk(KERN_INFO " cpodr[%u]=%08x\n", i,
+ in_be32(&par_io[i].cpodr));
+ printk(KERN_INFO " cpdata[%u]=%08x\n", i,
+ in_be32(&par_io[i].cpdata));
+ printk(KERN_INFO " cpdir1[%u]=%08x\n", i,
+ in_be32(&par_io[i].cpdir1));
+ printk(KERN_INFO " cpdir2[%u]=%08x\n", i,
+ in_be32(&par_io[i].cpdir2));
+ printk(KERN_INFO " cppar1[%u]=%08x\n", i,
+ in_be32(&par_io[i].cppar1));
+ printk(KERN_INFO " cppar2[%u]=%08x\n", i,
+ in_be32(&par_io[i].cppar2));
}
}
diff --git a/arch/powerpc/sysdev/qe_lib/ucc.c b/arch/powerpc/sysdev/qe_lib/ucc.c
index f970e54..3f70021 100644
--- a/arch/powerpc/sysdev/qe_lib/ucc.c
+++ b/arch/powerpc/sysdev/qe_lib/ucc.c
@@ -43,43 +43,57 @@ int ucc_set_qe_mux_mii_mng(int ucc_num)
}
EXPORT_SYMBOL(ucc_set_qe_mux_mii_mng);
-int ucc_set_type(int ucc_num, struct ucc_common *regs,
- enum ucc_speed_type speed)
+/* Configure the UCC to either Slow or Fast.
+ *
+ * A given UCC can be figured to support either "slow" devices (e.g. UART)
+ * or "fast" devices (e.g. Ethernet).
+ *
+ * 'ucc_num' is the UCC number, from 0 - 7.
+ *
+ * This function also sets the UCC_GUEMR_SET_RESERVED3 bit because that bit
+ * must always be set to 1.
+ */
+int ucc_set_type(unsigned int ucc_num, enum ucc_speed_type speed)
{
- u8 guemr = 0;
+ u8 __iomem *guemr;
+ u8 mode; /* The GUEMR register mode bits */
- /* check if the UCC number is in range. */
- if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0))
+ /* The GUEMR register is at the same location for both slow and fast
+ devices, so we just use uccX.slow.guemr. */
+ switch (ucc_num) {
+ case 0: guemr = &qe_immr->ucc1.slow.guemr;
+ break;
+ case 1: guemr = &qe_immr->ucc2.slow.guemr;
+ break;
+ case 2: guemr = &qe_immr->ucc3.slow.guemr;
+ break;
+ case 3: guemr = &qe_immr->ucc4.slow.guemr;
+ break;
+ case 4: guemr = &qe_immr->ucc5.slow.guemr;
+ break;
+ case 5: guemr = &qe_immr->ucc6.slow.guemr;
+ break;
+ case 6: guemr = &qe_immr->ucc7.slow.guemr;
+ break;
+ case 7: guemr = &qe_immr->ucc8.slow.guemr;
+ break;
+ default:
return -EINVAL;
+ }
- guemr = regs->guemr;
- guemr &= ~(UCC_GUEMR_MODE_MASK_RX | UCC_GUEMR_MODE_MASK_TX);
switch (speed) {
case UCC_SPEED_TYPE_SLOW:
- guemr |= (UCC_GUEMR_MODE_SLOW_RX | UCC_GUEMR_MODE_SLOW_TX);
+ mode = UCC_GUEMR_MODE_SLOW_RX | UCC_GUEMR_MODE_SLOW_TX;
break;
case UCC_SPEED_TYPE_FAST:
- guemr |= (UCC_GUEMR_MODE_FAST_RX | UCC_GUEMR_MODE_FAST_TX);
+ mode = UCC_GUEMR_MODE_FAST_RX | UCC_GUEMR_MODE_FAST_TX;
break;
default:
return -EINVAL;
}
- regs->guemr = guemr;
- return 0;
-}
-
-int ucc_init_guemr(struct ucc_common *regs)
-{
- u8 guemr = 0;
-
- if (!regs)
- return -EINVAL;
-
- /* Set bit 3 (which is reserved in the GUEMR register) to 1 */
- guemr = UCC_GUEMR_SET_RESERVED3;
-
- regs->guemr = guemr;
+ out_8(guemr, (in_8(guemr) & ~UCC_GUEMR_MODE_MASK) |
+ UCC_GUEMR_SET_RESERVED3 | mode);
return 0;
}
@@ -160,7 +174,7 @@ int ucc_set_qe_mux_rxtx(int ucc_num, enum qe_clock clock, enum comm_dir mode)
if (!((mode == COMM_DIR_RX) || (mode == COMM_DIR_TX))) {
printk(KERN_ERR
- "ucc_set_qe_mux_rxtx: bad comm mode type passed.");
+ "ucc_set_qe_mux_rxtx: bad comm mode type passed.\n");
return -EINVAL;
}
@@ -235,8 +249,8 @@ int ucc_set_qe_mux_rxtx(int ucc_num, enum qe_clock clock, enum comm_dir mode)
}
if (source == -1) {
- printk(KERN_ERR
- "ucc_set_qe_mux_rxtx: Bad combination of clock and UCC.");
+ printk(KERN_ERR "%s: Bad combination of clock and UCC.\n",
+ __FUNCTION__);
return -ENOENT;
}
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_fast.c b/arch/powerpc/sysdev/qe_lib/ucc_fast.c
index 3df202e..3223acb 100644
--- a/arch/powerpc/sysdev/qe_lib/ucc_fast.c
+++ b/arch/powerpc/sysdev/qe_lib/ucc_fast.c
@@ -30,46 +30,45 @@
void ucc_fast_dump_regs(struct ucc_fast_private * uccf)
{
- printk(KERN_INFO "UCC%d Fast registers:", uccf->uf_info->ucc_num);
- printk(KERN_INFO "Base address: 0x%08x", (u32) uccf->uf_regs);
-
- printk(KERN_INFO "gumr : addr - 0x%08x, val - 0x%08x",
- (u32) & uccf->uf_regs->gumr, in_be32(&uccf->uf_regs->gumr));
- printk(KERN_INFO "upsmr : addr - 0x%08x, val - 0x%08x",
- (u32) & uccf->uf_regs->upsmr, in_be32(&uccf->uf_regs->upsmr));
- printk(KERN_INFO "utodr : addr - 0x%08x, val - 0x%04x",
- (u32) & uccf->uf_regs->utodr, in_be16(&uccf->uf_regs->utodr));
- printk(KERN_INFO "udsr : addr - 0x%08x, val - 0x%04x",
- (u32) & uccf->uf_regs->udsr, in_be16(&uccf->uf_regs->udsr));
- printk(KERN_INFO "ucce : addr - 0x%08x, val - 0x%08x",
- (u32) & uccf->uf_regs->ucce, in_be32(&uccf->uf_regs->ucce));
- printk(KERN_INFO "uccm : addr - 0x%08x, val - 0x%08x",
- (u32) & uccf->uf_regs->uccm, in_be32(&uccf->uf_regs->uccm));
- printk(KERN_INFO "uccs : addr - 0x%08x, val - 0x%02x",
- (u32) & uccf->uf_regs->uccs, uccf->uf_regs->uccs);
- printk(KERN_INFO "urfb : addr - 0x%08x, val - 0x%08x",
- (u32) & uccf->uf_regs->urfb, in_be32(&uccf->uf_regs->urfb));
- printk(KERN_INFO "urfs : addr - 0x%08x, val - 0x%04x",
- (u32) & uccf->uf_regs->urfs, in_be16(&uccf->uf_regs->urfs));
- printk(KERN_INFO "urfet : addr - 0x%08x, val - 0x%04x",
- (u32) & uccf->uf_regs->urfet, in_be16(&uccf->uf_regs->urfet));
- printk(KERN_INFO "urfset: addr - 0x%08x, val - 0x%04x",
- (u32) & uccf->uf_regs->urfset,
- in_be16(&uccf->uf_regs->urfset));
- printk(KERN_INFO "utfb : addr - 0x%08x, val - 0x%08x",
- (u32) & uccf->uf_regs->utfb, in_be32(&uccf->uf_regs->utfb));
- printk(KERN_INFO "utfs : addr - 0x%08x, val - 0x%04x",
- (u32) & uccf->uf_regs->utfs, in_be16(&uccf->uf_regs->utfs));
- printk(KERN_INFO "utfet : addr - 0x%08x, val - 0x%04x",
- (u32) & uccf->uf_regs->utfet, in_be16(&uccf->uf_regs->utfet));
- printk(KERN_INFO "utftt : addr - 0x%08x, val - 0x%04x",
- (u32) & uccf->uf_regs->utftt, in_be16(&uccf->uf_regs->utftt));
- printk(KERN_INFO "utpt : addr - 0x%08x, val - 0x%04x",
- (u32) & uccf->uf_regs->utpt, in_be16(&uccf->uf_regs->utpt));
- printk(KERN_INFO "urtry : addr - 0x%08x, val - 0x%08x",
- (u32) & uccf->uf_regs->urtry, in_be32(&uccf->uf_regs->urtry));
- printk(KERN_INFO "guemr : addr - 0x%08x, val - 0x%02x",
- (u32) & uccf->uf_regs->guemr, uccf->uf_regs->guemr);
+ printk(KERN_INFO "UCC%u Fast registers:\n", uccf->uf_info->ucc_num);
+ printk(KERN_INFO "Base address: 0x%p\n", uccf->uf_regs);
+
+ printk(KERN_INFO "gumr : addr=0x%p, val=0x%08x\n",
+ &uccf->uf_regs->gumr, in_be32(&uccf->uf_regs->gumr));
+ printk(KERN_INFO "upsmr : addr=0x%p, val=0x%08x\n",
+ &uccf->uf_regs->upsmr, in_be32(&uccf->uf_regs->upsmr));
+ printk(KERN_INFO "utodr : addr=0x%p, val=0x%04x\n",
+ &uccf->uf_regs->utodr, in_be16(&uccf->uf_regs->utodr));
+ printk(KERN_INFO "udsr : addr=0x%p, val=0x%04x\n",
+ &uccf->uf_regs->udsr, in_be16(&uccf->uf_regs->udsr));
+ printk(KERN_INFO "ucce : addr=0x%p, val=0x%08x\n",
+ &uccf->uf_regs->ucce, in_be32(&uccf->uf_regs->ucce));
+ printk(KERN_INFO "uccm : addr=0x%p, val=0x%08x\n",
+ &uccf->uf_regs->uccm, in_be32(&uccf->uf_regs->uccm));
+ printk(KERN_INFO "uccs : addr=0x%p, val=0x%02x\n",
+ &uccf->uf_regs->uccs, uccf->uf_regs->uccs);
+ printk(KERN_INFO "urfb : addr=0x%p, val=0x%08x\n",
+ &uccf->uf_regs->urfb, in_be32(&uccf->uf_regs->urfb));
+ printk(KERN_INFO "urfs : addr=0x%p, val=0x%04x\n",
+ &uccf->uf_regs->urfs, in_be16(&uccf->uf_regs->urfs));
+ printk(KERN_INFO "urfet : addr=0x%p, val=0x%04x\n",
+ &uccf->uf_regs->urfet, in_be16(&uccf->uf_regs->urfet));
+ printk(KERN_INFO "urfset: addr=0x%p, val=0x%04x\n",
+ &uccf->uf_regs->urfset, in_be16(&uccf->uf_regs->urfset));
+ printk(KERN_INFO "utfb : addr=0x%p, val=0x%08x\n",
+ &uccf->uf_regs->utfb, in_be32(&uccf->uf_regs->utfb));
+ printk(KERN_INFO "utfs : addr=0x%p, val=0x%04x\n",
+ &uccf->uf_regs->utfs, in_be16(&uccf->uf_regs->utfs));
+ printk(KERN_INFO "utfet : addr=0x%p, val=0x%04x\n",
+ &uccf->uf_regs->utfet, in_be16(&uccf->uf_regs->utfet));
+ printk(KERN_INFO "utftt : addr=0x%p, val=0x%04x\n",
+ &uccf->uf_regs->utftt, in_be16(&uccf->uf_regs->utftt));
+ printk(KERN_INFO "utpt : addr=0x%p, val=0x%04x\n",
+ &uccf->uf_regs->utpt, in_be16(&uccf->uf_regs->utpt));
+ printk(KERN_INFO "urtry : addr=0x%p, val=0x%08x\n",
+ &uccf->uf_regs->urtry, in_be32(&uccf->uf_regs->urtry));
+ printk(KERN_INFO "guemr : addr=0x%p, val=0x%02x\n",
+ &uccf->uf_regs->guemr, uccf->uf_regs->guemr);
}
EXPORT_SYMBOL(ucc_fast_dump_regs);
@@ -149,55 +148,57 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
/* check if the UCC port number is in range. */
if ((uf_info->ucc_num < 0) || (uf_info->ucc_num > UCC_MAX_NUM - 1)) {
- printk(KERN_ERR "%s: illegal UCC number", __FUNCTION__);
+ printk(KERN_ERR "%s: illegal UCC number\n", __FUNCTION__);
return -EINVAL;
}
/* Check that 'max_rx_buf_length' is properly aligned (4). */
if (uf_info->max_rx_buf_length & (UCC_FAST_MRBLR_ALIGNMENT - 1)) {
- printk(KERN_ERR "%s: max_rx_buf_length not aligned", __FUNCTION__);
+ printk(KERN_ERR "%s: max_rx_buf_length not aligned\n",
+ __FUNCTION__);
return -EINVAL;
}
/* Validate Virtual Fifo register values */
if (uf_info->urfs < UCC_FAST_URFS_MIN_VAL) {
- printk(KERN_ERR "%s: urfs is too small", __FUNCTION__);
+ printk(KERN_ERR "%s: urfs is too small\n", __FUNCTION__);
return -EINVAL;
}
if (uf_info->urfs & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
- printk(KERN_ERR "%s: urfs is not aligned", __FUNCTION__);
+ printk(KERN_ERR "%s: urfs is not aligned\n", __FUNCTION__);
return -EINVAL;
}
if (uf_info->urfet & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
- printk(KERN_ERR "%s: urfet is not aligned.", __FUNCTION__);
+ printk(KERN_ERR "%s: urfet is not aligned.\n", __FUNCTION__);
return -EINVAL;
}
if (uf_info->urfset & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
- printk(KERN_ERR "%s: urfset is not aligned", __FUNCTION__);
+ printk(KERN_ERR "%s: urfset is not aligned\n", __FUNCTION__);
return -EINVAL;
}
if (uf_info->utfs & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
- printk(KERN_ERR "%s: utfs is not aligned", __FUNCTION__);
+ printk(KERN_ERR "%s: utfs is not aligned\n", __FUNCTION__);
return -EINVAL;
}
if (uf_info->utfet & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
- printk(KERN_ERR "%s: utfet is not aligned", __FUNCTION__);
+ printk(KERN_ERR "%s: utfet is not aligned\n", __FUNCTION__);
return -EINVAL;
}
if (uf_info->utftt & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
- printk(KERN_ERR "%s: utftt is not aligned", __FUNCTION__);
+ printk(KERN_ERR "%s: utftt is not aligned\n", __FUNCTION__);
return -EINVAL;
}
uccf = kzalloc(sizeof(struct ucc_fast_private), GFP_KERNEL);
if (!uccf) {
- printk(KERN_ERR "%s: Cannot allocate private data", __FUNCTION__);
+ printk(KERN_ERR "%s: Cannot allocate private data\n",
+ __FUNCTION__);
return -ENOMEM;
}
@@ -206,7 +207,7 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
/* Set the PHY base address */
uccf->uf_regs = ioremap(uf_info->regs, sizeof(struct ucc_fast));
if (uccf->uf_regs == NULL) {
- printk(KERN_ERR "%s: Cannot map UCC registers", __FUNCTION__);
+ printk(KERN_ERR "%s: Cannot map UCC registers\n", __FUNCTION__);
return -ENOMEM;
}
@@ -226,18 +227,10 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
uccf->rx_discarded = 0;
#endif /* STATISTICS */
- /* Init Guemr register */
- if ((ret = ucc_init_guemr((struct ucc_common *) (uf_regs)))) {
- printk(KERN_ERR "%s: cannot init GUEMR", __FUNCTION__);
- ucc_fast_free(uccf);
- return ret;
- }
-
/* Set UCC to fast type */
- if ((ret = ucc_set_type(uf_info->ucc_num,
- (struct ucc_common *) (uf_regs),
- UCC_SPEED_TYPE_FAST))) {
- printk(KERN_ERR "%s: cannot set UCC type", __FUNCTION__);
+ ret = ucc_set_type(uf_info->ucc_num, UCC_SPEED_TYPE_FAST);
+ if (ret) {
+ printk(KERN_ERR "%s: cannot set UCC type\n", __FUNCTION__);
ucc_fast_free(uccf);
return ret;
}
@@ -276,7 +269,8 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
uccf->ucc_fast_tx_virtual_fifo_base_offset =
qe_muram_alloc(uf_info->utfs, UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
if (IS_ERR_VALUE(uccf->ucc_fast_tx_virtual_fifo_base_offset)) {
- printk(KERN_ERR "%s: cannot allocate MURAM for TX FIFO", __FUNCTION__);
+ printk(KERN_ERR "%s: cannot allocate MURAM for TX FIFO\n",
+ __FUNCTION__);
uccf->ucc_fast_tx_virtual_fifo_base_offset = 0;
ucc_fast_free(uccf);
return -ENOMEM;
@@ -288,7 +282,8 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
UCC_FAST_RECEIVE_VIRTUAL_FIFO_SIZE_FUDGE_FACTOR,
UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
if (IS_ERR_VALUE(uccf->ucc_fast_rx_virtual_fifo_base_offset)) {
- printk(KERN_ERR "%s: cannot allocate MURAM for RX FIFO", __FUNCTION__);
+ printk(KERN_ERR "%s: cannot allocate MURAM for RX FIFO\n",
+ __FUNCTION__);
uccf->ucc_fast_rx_virtual_fifo_base_offset = 0;
ucc_fast_free(uccf);
return -ENOMEM;
@@ -318,7 +313,7 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
if ((uf_info->rx_clock != QE_CLK_NONE) &&
ucc_set_qe_mux_rxtx(uf_info->ucc_num, uf_info->rx_clock,
COMM_DIR_RX)) {
- printk(KERN_ERR "%s: illegal value for RX clock",
+ printk(KERN_ERR "%s: illegal value for RX clock\n",
__FUNCTION__);
ucc_fast_free(uccf);
return -EINVAL;
@@ -327,7 +322,7 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
if ((uf_info->tx_clock != QE_CLK_NONE) &&
ucc_set_qe_mux_rxtx(uf_info->ucc_num, uf_info->tx_clock,
COMM_DIR_TX)) {
- printk(KERN_ERR "%s: illegal value for TX clock",
+ printk(KERN_ERR "%s: illegal value for TX clock\n",
__FUNCTION__);
ucc_fast_free(uccf);
return -EINVAL;
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_slow.c b/arch/powerpc/sysdev/qe_lib/ucc_slow.c
index 1f65c26..0174b3a 100644
--- a/arch/powerpc/sysdev/qe_lib/ucc_slow.c
+++ b/arch/powerpc/sysdev/qe_lib/ucc_slow.c
@@ -115,11 +115,15 @@ void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode)
out_be32(&us_regs->gumr_l, gumr_l);
}
+/* Initialize the UCC for Slow operations
+ *
+ * The caller should initialize the following us_info
+ */
int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** uccs_ret)
{
struct ucc_slow_private *uccs;
u32 i;
- struct ucc_slow *us_regs;
+ struct ucc_slow __iomem *us_regs;
u32 gumr;
struct qe_bd *bd;
u32 id;
@@ -131,7 +135,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
/* check if the UCC port number is in range. */
if ((us_info->ucc_num < 0) || (us_info->ucc_num > UCC_MAX_NUM - 1)) {
- printk(KERN_ERR "%s: illegal UCC number", __FUNCTION__);
+ printk(KERN_ERR "%s: illegal UCC number\n", __FUNCTION__);
return -EINVAL;
}
@@ -143,13 +147,14 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
*/
if ((!us_info->rfw) &&
(us_info->max_rx_buf_length & (UCC_SLOW_MRBLR_ALIGNMENT - 1))) {
- printk(KERN_ERR "max_rx_buf_length not aligned.");
+ printk(KERN_ERR "max_rx_buf_length not aligned.\n");
return -EINVAL;
}
uccs = kzalloc(sizeof(struct ucc_slow_private), GFP_KERNEL);
if (!uccs) {
- printk(KERN_ERR "%s: Cannot allocate private data", __FUNCTION__);
+ printk(KERN_ERR "%s: Cannot allocate private data\n",
+ __FUNCTION__);
return -ENOMEM;
}
@@ -158,7 +163,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
/* Set the PHY base address */
uccs->us_regs = ioremap(us_info->regs, sizeof(struct ucc_slow));
if (uccs->us_regs == NULL) {
- printk(KERN_ERR "%s: Cannot map UCC registers", __FUNCTION__);
+ printk(KERN_ERR "%s: Cannot map UCC registers\n", __FUNCTION__);
return -ENOMEM;
}
@@ -182,22 +187,14 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
return -ENOMEM;
}
id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
- qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, id, QE_CR_PROTOCOL_UNSPECIFIED,
+ qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, id, us_info->protocol,
uccs->us_pram_offset);
uccs->us_pram = qe_muram_addr(uccs->us_pram_offset);
- /* Init Guemr register */
- if ((ret = ucc_init_guemr((struct ucc_common *) us_regs))) {
- printk(KERN_ERR "%s: cannot init GUEMR", __FUNCTION__);
- ucc_slow_free(uccs);
- return ret;
- }
-
/* Set UCC to slow type */
- if ((ret = ucc_set_type(us_info->ucc_num,
- (struct ucc_common *) us_regs,
- UCC_SPEED_TYPE_SLOW))) {
+ ret = ucc_set_type(us_info->ucc_num, UCC_SPEED_TYPE_SLOW);
+ if (ret) {
printk(KERN_ERR "%s: cannot set UCC type", __FUNCTION__);
ucc_slow_free(uccs);
return ret;
@@ -212,7 +209,8 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
qe_muram_alloc(us_info->rx_bd_ring_len * sizeof(struct qe_bd),
QE_ALIGNMENT_OF_BD);
if (IS_ERR_VALUE(uccs->rx_base_offset)) {
- printk(KERN_ERR "%s: cannot allocate RX BDs", __FUNCTION__);
+ printk(KERN_ERR "%s: cannot allocate %u RX BDs\n", __FUNCTION__,
+ us_info->rx_bd_ring_len);
uccs->rx_base_offset = 0;
ucc_slow_free(uccs);
return -ENOMEM;
@@ -292,12 +290,12 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
/* if the data is in cachable memory, the 'global' */
/* in the function code should be set. */
- uccs->us_pram->tfcr = uccs->us_pram->rfcr =
- us_info->data_mem_part | QE_BMR_BYTE_ORDER_BO_MOT;
+ uccs->us_pram->tbmr = UCC_BMR_BO_BE;
+ uccs->us_pram->rbmr = UCC_BMR_BO_BE;
/* rbase, tbase are offsets from MURAM base */
- out_be16(&uccs->us_pram->rbase, uccs->us_pram_offset);
- out_be16(&uccs->us_pram->tbase, uccs->us_pram_offset);
+ out_be16(&uccs->us_pram->rbase, uccs->rx_base_offset);
+ out_be16(&uccs->us_pram->tbase, uccs->tx_base_offset);
/* Mux clocking */
/* Grant Support */
@@ -311,7 +309,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
/* Rx clock routing */
if (ucc_set_qe_mux_rxtx(us_info->ucc_num, us_info->rx_clock,
COMM_DIR_RX)) {
- printk(KERN_ERR "%s: illegal value for RX clock",
+ printk(KERN_ERR "%s: illegal value for RX clock\n",
__FUNCTION__);
ucc_slow_free(uccs);
return -EINVAL;
@@ -319,7 +317,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
/* Tx clock routing */
if (ucc_set_qe_mux_rxtx(us_info->ucc_num, us_info->tx_clock,
COMM_DIR_TX)) {
- printk(KERN_ERR "%s: illegal value for TX clock",
+ printk(KERN_ERR "%s: illegal value for TX clock\n",
__FUNCTION__);
ucc_slow_free(uccs);
return -EINVAL;
@@ -343,8 +341,8 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
command = QE_INIT_TX;
else
command = QE_INIT_RX; /* We know at least one is TRUE */
- id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
- qe_issue_cmd(command, id, QE_CR_PROTOCOL_UNSPECIFIED, 0);
+
+ qe_issue_cmd(command, id, us_info->protocol, 0);
*uccs_ret = uccs;
return 0;
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 9a38dfe..96ebdf7 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -2919,7 +2919,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
test = in_be16(&ugeth->p_tx_glbl_pram->temoder);
/* Function code register value to be used later */
- function_code = QE_BMR_BYTE_ORDER_BO_MOT | UCC_FAST_FUNCTION_CODE_GBL;
+ function_code = UCC_BMR_BO_BE | UCC_BMR_GBL;
/* Required for QE */
/* function code register */
diff --git a/include/asm-powerpc/immap_qe.h b/include/asm-powerpc/immap_qe.h
index 1020b7f..0a0644b 100644
--- a/include/asm-powerpc/immap_qe.h
+++ b/include/asm-powerpc/immap_qe.h
@@ -260,7 +260,6 @@ struct ucc_slow {
__be16 utpt;
u8 res4[0x52];
u8 guemr; /* UCC general extended mode register */
- u8 res5[0x200 - 0x091];
} __attribute__ ((packed));
/* QE UCC Fast */
@@ -293,21 +292,13 @@ struct ucc_fast {
__be32 urtry; /* UCC retry counter register */
u8 res8[0x4C];
u8 guemr; /* UCC general extended mode register */
- u8 res9[0x100 - 0x091];
-} __attribute__ ((packed));
-
-/* QE UCC */
-struct ucc_common {
- u8 res1[0x90];
- u8 guemr;
- u8 res2[0x200 - 0x091];
} __attribute__ ((packed));
struct ucc {
union {
struct ucc_slow slow;
struct ucc_fast fast;
- struct ucc_common common;
+ u8 res[0x200]; /* UCC blocks are 512 bytes each */
};
} __attribute__ ((packed));
@@ -406,7 +397,7 @@ struct dbg {
/* RISC Special Registers (Trap and Breakpoint) */
struct rsp {
- u8 fixme[0x100];
+ u32 reg[0x40]; /* 64 32-bit registers */
} __attribute__ ((packed));
struct qe_immap {
@@ -435,11 +426,13 @@ struct qe_immap {
u8 res13[0x600];
struct upc upc2; /* MultiPHY UTOPIA POS Ctrlr 2*/
struct sdma sdma; /* SDMA */
- struct dbg dbg; /* Debug Space */
- struct rsp rsp[0x2]; /* RISC Special Registers
+ struct dbg dbg; /* 0x104080 - 0x1040FF
+ Debug Space */
+ struct rsp rsp[0x2]; /* 0x104100 - 0x1042FF
+ RISC Special Registers
(Trap and Breakpoint) */
- u8 res14[0x300];
- u8 res15[0x3A00];
+ u8 res14[0x300]; /* 0x104300 - 0x1045FF */
+ u8 res15[0x3A00]; /* 0x104600 - 0x107FFF */
u8 res16[0x8000]; /* 0x108000 - 0x110000 */
u8 muram[0xC000]; /* 0x110000 - 0x11C000
Multi-user RAM */
diff --git a/include/asm-powerpc/qe.h b/include/asm-powerpc/qe.h
index 9d304b1..a92e07a 100644
--- a/include/asm-powerpc/qe.h
+++ b/include/asm-powerpc/qe.h
@@ -35,7 +35,7 @@ extern int par_io_of_config(struct device_node *np);
/* QE internal API */
int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input);
-void qe_setbrg(u32 brg, u32 rate);
+void qe_setbrg(unsigned int brg, unsigned int rate, unsigned int multiplier);
int qe_get_snum(void);
void qe_put_snum(u8 snum);
unsigned long qe_muram_alloc(int size, int align);
@@ -46,14 +46,28 @@ void *qe_muram_addr(unsigned long offset);
/* Buffer descriptors */
struct qe_bd {
- u16 status;
- u16 length;
- u32 buf;
+ __be16 status;
+ __be16 length;
+ __be32 buf;
} __attribute__ ((packed));
#define BD_STATUS_MASK 0xffff0000
#define BD_LENGTH_MASK 0x0000ffff
+#define BD_SC_EMPTY 0x8000 /* Receive is empty */
+#define BD_SC_READY 0x8000 /* Transmit is ready */
+#define BD_SC_WRAP 0x2000 /* Last buffer descriptor */
+#define BD_SC_INTRPT 0x1000 /* Interrupt on change */
+#define BD_SC_LAST 0x0800 /* Last buffer in frame */
+#define BD_SC_CM 0x0200 /* Continous mode */
+#define BD_SC_ID 0x0100 /* Rec'd too many idles */
+#define BD_SC_P 0x0100 /* xmt preamble */
+#define BD_SC_BR 0x0020 /* Break received */
+#define BD_SC_FR 0x0010 /* Framing error */
+#define BD_SC_PR 0x0008 /* Parity error */
+#define BD_SC_OV 0x0002 /* Overrun */
+#define BD_SC_CD 0x0001 /* ?? */
+
/* Alignment */
#define QE_INTR_TABLE_ALIGN 16 /* ??? */
#define QE_ALIGNMENT_OF_BD 8
@@ -266,15 +280,12 @@ enum qe_clock {
/* QE CECR Protocol - For non-MCC, specifies mode for QE CECR command */
#define QE_CR_PROTOCOL_UNSPECIFIED 0x00 /* For all other protocols */
#define QE_CR_PROTOCOL_HDLC_TRANSPARENT 0x00
+#define QE_CR_PROTOCOL_QMC 0x02
+#define QE_CR_PROTOCOL_UART 0x04
#define QE_CR_PROTOCOL_ATM_POS 0x0A
#define QE_CR_PROTOCOL_ETHERNET 0x0C
#define QE_CR_PROTOCOL_L2_SWITCH 0x0D
-/* BMR byte order */
-#define QE_BMR_BYTE_ORDER_BO_PPC 0x08 /* powerpc little endian */
-#define QE_BMR_BYTE_ORDER_BO_MOT 0x10 /* motorola big endian */
-#define QE_BMR_BYTE_ORDER_BO_MAX 0x18
-
/* BRG configuration register */
#define QE_BRGC_ENABLE 0x00010000
#define QE_BRGC_DIVISOR_SHIFT 1
@@ -321,41 +332,41 @@ enum qe_clock {
#define UPGCR_ADDR 0x10000000 /* Master MPHY Addr multiplexing */
#define UPGCR_DIAG 0x01000000 /* Diagnostic mode */
-/* UCC */
+/* UCC GUEMR register */
#define UCC_GUEMR_MODE_MASK_RX 0x02
-#define UCC_GUEMR_MODE_MASK_TX 0x01
#define UCC_GUEMR_MODE_FAST_RX 0x02
-#define UCC_GUEMR_MODE_FAST_TX 0x01
#define UCC_GUEMR_MODE_SLOW_RX 0x00
+#define UCC_GUEMR_MODE_MASK_TX 0x01
+#define UCC_GUEMR_MODE_FAST_TX 0x01
#define UCC_GUEMR_MODE_SLOW_TX 0x00
+#define UCC_GUEMR_MODE_MASK (UCC_GUEMR_MODE_MASK_RX | UCC_GUEMR_MODE_MASK_TX)
#define UCC_GUEMR_SET_RESERVED3 0x10 /* Bit 3 in the guemr is reserved but
must be set 1 */
/* structure representing UCC SLOW parameter RAM */
struct ucc_slow_pram {
- u16 rbase; /* RX BD base address */
- u16 tbase; /* TX BD base address */
- u8 rfcr; /* Rx function code */
- u8 tfcr; /* Tx function code */
- u16 mrblr; /* Rx buffer length */
- u32 rstate; /* Rx internal state */
- u32 rptr; /* Rx internal data pointer */
- u16 rbptr; /* rb BD Pointer */
- u16 rcount; /* Rx internal byte count */
- u32 rtemp; /* Rx temp */
- u32 tstate; /* Tx internal state */
- u32 tptr; /* Tx internal data pointer */
- u16 tbptr; /* Tx BD pointer */
- u16 tcount; /* Tx byte count */
- u32 ttemp; /* Tx temp */
- u32 rcrc; /* temp receive CRC */
- u32 tcrc; /* temp transmit CRC */
+ __be16 rbase; /* RX BD base address */
+ __be16 tbase; /* TX BD base address */
+ u8 rbmr; /* RX bus mode register (same as CPM's RFCR) */
+ u8 tbmr; /* TX bus mode register (same as CPM's TFCR) */
+ __be16 mrblr; /* Rx buffer length */
+ __be32 rstate; /* Rx internal state */
+ __be32 rptr; /* Rx internal data pointer */
+ __be16 rbptr; /* rb BD Pointer */
+ __be16 rcount; /* Rx internal byte count */
+ __be32 rtemp; /* Rx temp */
+ __be32 tstate; /* Tx internal state */
+ __be32 tptr; /* Tx internal data pointer */
+ __be16 tbptr; /* Tx BD pointer */
+ __be16 tcount; /* Tx byte count */
+ __be32 ttemp; /* Tx temp */
+ __be32 rcrc; /* temp receive CRC */
+ __be32 tcrc; /* temp transmit CRC */
} __attribute__ ((packed));
/* General UCC SLOW Mode Register (GUMRH & GUMRL) */
-#define UCC_SLOW_GUMR_H_CRC16 0x00004000
-#define UCC_SLOW_GUMR_H_CRC16CCITT 0x00000000
-#define UCC_SLOW_GUMR_H_CRC32CCITT 0x00008000
+#define UCC_SLOW_GUMR_H_SAM_QMC 0x00000000
+#define UCC_SLOW_GUMR_H_SAM_SATM 0x00008000
#define UCC_SLOW_GUMR_H_REVD 0x00002000
#define UCC_SLOW_GUMR_H_TRX 0x00001000
#define UCC_SLOW_GUMR_H_TTX 0x00000800
@@ -375,9 +386,33 @@ struct ucc_slow_pram {
#define UCC_SLOW_GUMR_L_TCI 0x10000000
#define UCC_SLOW_GUMR_L_RINV 0x02000000
#define UCC_SLOW_GUMR_L_TINV 0x01000000
-#define UCC_SLOW_GUMR_L_TEND 0x00020000
+#define UCC_SLOW_GUMR_L_TEND 0x00040000
+#define UCC_SLOW_GUMR_L_TDCR_MASK 0x00030000
+#define UCC_SLOW_GUMR_L_TDCR_32 0x00030000
+#define UCC_SLOW_GUMR_L_TDCR_16 0x00020000
+#define UCC_SLOW_GUMR_L_TDCR_8 0x00010000
+#define UCC_SLOW_GUMR_L_TDCR_1 0x00000000
+#define UCC_SLOW_GUMR_L_RDCR_MASK 0x0000c000
+#define UCC_SLOW_GUMR_L_RDCR_32 0x0000c000
+#define UCC_SLOW_GUMR_L_RDCR_16 0x00008000
+#define UCC_SLOW_GUMR_L_RDCR_8 0x00004000
+#define UCC_SLOW_GUMR_L_RDCR_1 0x00000000
+#define UCC_SLOW_GUMR_L_RENC_NRZI 0x00000800
+#define UCC_SLOW_GUMR_L_RENC_NRZ 0x00000000
+#define UCC_SLOW_GUMR_L_TENC_NRZI 0x00000100
+#define UCC_SLOW_GUMR_L_TENC_NRZ 0x00000000
+#define UCC_SLOW_GUMR_L_DIAG_MASK 0x000000c0
+#define UCC_SLOW_GUMR_L_DIAG_LE 0x000000c0
+#define UCC_SLOW_GUMR_L_DIAG_ECHO 0x00000080
+#define UCC_SLOW_GUMR_L_DIAG_LOOP 0x00000040
+#define UCC_SLOW_GUMR_L_DIAG_NORM 0x00000000
#define UCC_SLOW_GUMR_L_ENR 0x00000020
#define UCC_SLOW_GUMR_L_ENT 0x00000010
+#define UCC_SLOW_GUMR_L_MODE_MASK 0x0000000F
+#define UCC_SLOW_GUMR_L_MODE_BISYNC 0x00000008
+#define UCC_SLOW_GUMR_L_MODE_AHDLC 0x00000006
+#define UCC_SLOW_GUMR_L_MODE_UART 0x00000004
+#define UCC_SLOW_GUMR_L_MODE_QMC 0x00000002
/* General UCC FAST Mode Register */
#define UCC_FAST_GUMR_TCI 0x20000000
@@ -394,53 +429,111 @@ struct ucc_slow_pram {
#define UCC_FAST_GUMR_ENR 0x00000020
#define UCC_FAST_GUMR_ENT 0x00000010
-/* Slow UCC Event Register (UCCE) */
-#define UCC_SLOW_UCCE_GLR 0x1000
-#define UCC_SLOW_UCCE_GLT 0x0800
-#define UCC_SLOW_UCCE_DCC 0x0400
-#define UCC_SLOW_UCCE_FLG 0x0200
-#define UCC_SLOW_UCCE_AB 0x0200
-#define UCC_SLOW_UCCE_IDLE 0x0100
-#define UCC_SLOW_UCCE_GRA 0x0080
-#define UCC_SLOW_UCCE_TXE 0x0010
-#define UCC_SLOW_UCCE_RXF 0x0008
-#define UCC_SLOW_UCCE_CCR 0x0008
-#define UCC_SLOW_UCCE_RCH 0x0008
-#define UCC_SLOW_UCCE_BSY 0x0004
-#define UCC_SLOW_UCCE_TXB 0x0002
-#define UCC_SLOW_UCCE_TX 0x0002
-#define UCC_SLOW_UCCE_RX 0x0001
-#define UCC_SLOW_UCCE_GOV 0x0001
-#define UCC_SLOW_UCCE_GUN 0x0002
-#define UCC_SLOW_UCCE_GINT 0x0004
-#define UCC_SLOW_UCCE_IQOV 0x0008
-
-#define UCC_SLOW_UCCE_HDLC_SET (UCC_SLOW_UCCE_TXE | UCC_SLOW_UCCE_BSY | \
- UCC_SLOW_UCCE_GRA | UCC_SLOW_UCCE_TXB | UCC_SLOW_UCCE_RXF | \
- UCC_SLOW_UCCE_DCC | UCC_SLOW_UCCE_GLT | UCC_SLOW_UCCE_GLR)
-#define UCC_SLOW_UCCE_ENET_SET (UCC_SLOW_UCCE_TXE | UCC_SLOW_UCCE_BSY | \
- UCC_SLOW_UCCE_GRA | UCC_SLOW_UCCE_TXB | UCC_SLOW_UCCE_RXF)
-#define UCC_SLOW_UCCE_TRANS_SET (UCC_SLOW_UCCE_TXE | UCC_SLOW_UCCE_BSY | \
- UCC_SLOW_UCCE_GRA | UCC_SLOW_UCCE_TX | UCC_SLOW_UCCE_RX | \
- UCC_SLOW_UCCE_DCC | UCC_SLOW_UCCE_GLT | UCC_SLOW_UCCE_GLR)
-#define UCC_SLOW_UCCE_UART_SET (UCC_SLOW_UCCE_BSY | UCC_SLOW_UCCE_GRA | \
- UCC_SLOW_UCCE_TXB | UCC_SLOW_UCCE_TX | UCC_SLOW_UCCE_RX | \
- UCC_SLOW_UCCE_GLT | UCC_SLOW_UCCE_GLR)
-#define UCC_SLOW_UCCE_QMC_SET (UCC_SLOW_UCCE_IQOV | UCC_SLOW_UCCE_GINT | \
- UCC_SLOW_UCCE_GUN | UCC_SLOW_UCCE_GOV)
-
-#define UCC_SLOW_UCCE_OTHER (UCC_SLOW_UCCE_TXE | UCC_SLOW_UCCE_BSY | \
- UCC_SLOW_UCCE_GRA | UCC_SLOW_UCCE_DCC | UCC_SLOW_UCCE_GLT | \
- UCC_SLOW_UCCE_GLR)
-
-#define UCC_SLOW_INTR_TX UCC_SLOW_UCCE_TXB
-#define UCC_SLOW_INTR_RX (UCC_SLOW_UCCE_RXF | UCC_SLOW_UCCE_RX)
-#define UCC_SLOW_INTR (UCC_SLOW_INTR_TX | UCC_SLOW_INTR_RX)
+/* UART Slow UCC Event Register (UCCE) */
+#define UCC_UART_UCCE_AB 0x0200
+#define UCC_UART_UCCE_IDLE 0x0100
+#define UCC_UART_UCCE_GRA 0x0080
+#define UCC_UART_UCCE_BRKE 0x0040
+#define UCC_UART_UCCE_BRKS 0x0020
+#define UCC_UART_UCCE_CCR 0x0008
+#define UCC_UART_UCCE_BSY 0x0004
+#define UCC_UART_UCCE_TX 0x0002
+#define UCC_UART_UCCE_RX 0x0001
+
+/* HDLC Slow UCC Event Register (UCCE) */
+#define UCC_HDLC_UCCE_GLR 0x1000
+#define UCC_HDLC_UCCE_GLT 0x0800
+#define UCC_HDLC_UCCE_IDLE 0x0100
+#define UCC_HDLC_UCCE_BRKE 0x0040
+#define UCC_HDLC_UCCE_BRKS 0x0020
+#define UCC_HDLC_UCCE_TXE 0x0010
+#define UCC_HDLC_UCCE_RXF 0x0008
+#define UCC_HDLC_UCCE_BSY 0x0004
+#define UCC_HDLC_UCCE_TXB 0x0002
+#define UCC_HDLC_UCCE_RXB 0x0001
+
+/* BISYNC Slow UCC Event Register (UCCE) */
+#define UCC_BISYNC_UCCE_GRA 0x0080
+#define UCC_BISYNC_UCCE_TXE 0x0010
+#define UCC_BISYNC_UCCE_RCH 0x0008
+#define UCC_BISYNC_UCCE_BSY 0x0004
+#define UCC_BISYNC_UCCE_TXB 0x0002
+#define UCC_BISYNC_UCCE_RXB 0x0001
+
+/* Gigabit Ethernet Fast UCC Event Register (UCCE) */
+#define UCC_GETH_UCCE_MPD 0x80000000
+#define UCC_GETH_UCCE_SCAR 0x40000000
+#define UCC_GETH_UCCE_GRA 0x20000000
+#define UCC_GETH_UCCE_CBPR 0x10000000
+#define UCC_GETH_UCCE_BSY 0x08000000
+#define UCC_GETH_UCCE_RXC 0x04000000
+#define UCC_GETH_UCCE_TXC 0x02000000
+#define UCC_GETH_UCCE_TXE 0x01000000
+#define UCC_GETH_UCCE_TXB7 0x00800000
+#define UCC_GETH_UCCE_TXB6 0x00400000
+#define UCC_GETH_UCCE_TXB5 0x00200000
+#define UCC_GETH_UCCE_TXB4 0x00100000
+#define UCC_GETH_UCCE_TXB3 0x00080000
+#define UCC_GETH_UCCE_TXB2 0x00040000
+#define UCC_GETH_UCCE_TXB1 0x00020000
+#define UCC_GETH_UCCE_TXB0 0x00010000
+#define UCC_GETH_UCCE_RXB7 0x00008000
+#define UCC_GETH_UCCE_RXB6 0x00004000
+#define UCC_GETH_UCCE_RXB5 0x00002000
+#define UCC_GETH_UCCE_RXB4 0x00001000
+#define UCC_GETH_UCCE_RXB3 0x00000800
+#define UCC_GETH_UCCE_RXB2 0x00000400
+#define UCC_GETH_UCCE_RXB1 0x00000200
+#define UCC_GETH_UCCE_RXB0 0x00000100
+#define UCC_GETH_UCCE_RXF7 0x00000080
+#define UCC_GETH_UCCE_RXF6 0x00000040
+#define UCC_GETH_UCCE_RXF5 0x00000020
+#define UCC_GETH_UCCE_RXF4 0x00000010
+#define UCC_GETH_UCCE_RXF3 0x00000008
+#define UCC_GETH_UCCE_RXF2 0x00000004
+#define UCC_GETH_UCCE_RXF1 0x00000002
+#define UCC_GETH_UCCE_RXF0 0x00000001
+
+/* UPSMR, when used as a UART */
+#define UCC_UART_UPSMR_FLC 0x8000
+#define UCC_UART_UPSMR_SL 0x4000
+#define UCC_UART_UPSMR_CL_MASK 0x3000
+#define UCC_UART_UPSMR_CL_8 0x3000
+#define UCC_UART_UPSMR_CL_7 0x2000
+#define UCC_UART_UPSMR_CL_6 0x1000
+#define UCC_UART_UPSMR_CL_5 0x0000
+#define UCC_UART_UPSMR_UM_MASK 0x0c00
+#define UCC_UART_UPSMR_UM_NORMAL 0x0000
+#define UCC_UART_UPSMR_UM_MAN_MULTI 0x0400
+#define UCC_UART_UPSMR_UM_AUTO_MULTI 0x0c00
+#define UCC_UART_UPSMR_FRZ 0x0200
+#define UCC_UART_UPSMR_RZS 0x0100
+#define UCC_UART_UPSMR_SYN 0x0080
+#define UCC_UART_UPSMR_DRT 0x0040
+#define UCC_UART_UPSMR_PEN 0x0010
+#define UCC_UART_UPSMR_RPM_MASK 0x000c
+#define UCC_UART_UPSMR_RPM_ODD 0x0000
+#define UCC_UART_UPSMR_RPM_LOW 0x0004
+#define UCC_UART_UPSMR_RPM_EVEN 0x0008
+#define UCC_UART_UPSMR_RPM_HIGH 0x000C
+#define UCC_UART_UPSMR_TPM_MASK 0x0003
+#define UCC_UART_UPSMR_TPM_ODD 0x0000
+#define UCC_UART_UPSMR_TPM_LOW 0x0001
+#define UCC_UART_UPSMR_TPM_EVEN 0x0002
+#define UCC_UART_UPSMR_TPM_HIGH 0x0003
/* UCC Transmit On Demand Register (UTODR) */
#define UCC_SLOW_TOD 0x8000
#define UCC_FAST_TOD 0x8000
+/* UCC Bus Mode Register masks */
+/* Not to be confused with the Bundle Mode Register */
+#define UCC_BMR_GBL 0x20
+#define UCC_BMR_BO_BE 0x10
+#define UCC_BMR_CETM 0x04
+#define UCC_BMR_DTB 0x02
+#define UCC_BMR_BDB 0x01
+
/* Function code masks */
#define FC_GBL 0x20
#define FC_DTB_LCL 0x02
diff --git a/include/asm-powerpc/ucc.h b/include/asm-powerpc/ucc.h
index afe3076..f96ea54 100644
--- a/include/asm-powerpc/ucc.h
+++ b/include/asm-powerpc/ucc.h
@@ -28,35 +28,13 @@ enum ucc_speed_type {
UCC_SPEED_TYPE_FAST, UCC_SPEED_TYPE_SLOW
};
-/* Initial UCCs Parameter RAM address relative to: MEM_MAP_BASE (IMMR).
-*/
-enum ucc_pram_initial_offset {
- UCC_PRAM_OFFSET_UCC1 = 0x8400,
- UCC_PRAM_OFFSET_UCC2 = 0x8500,
- UCC_PRAM_OFFSET_UCC3 = 0x8600,
- UCC_PRAM_OFFSET_UCC4 = 0x9000,
- UCC_PRAM_OFFSET_UCC5 = 0x8000,
- UCC_PRAM_OFFSET_UCC6 = 0x8100,
- UCC_PRAM_OFFSET_UCC7 = 0x8200,
- UCC_PRAM_OFFSET_UCC8 = 0x8300
-};
-
/* ucc_set_type
* Sets UCC to slow or fast mode.
*
* ucc_num - (In) number of UCC (0-7).
- * regs - (In) pointer to registers base for the UCC.
* speed - (In) slow or fast mode for UCC.
*/
-int ucc_set_type(int ucc_num, struct ucc_common *regs,
- enum ucc_speed_type speed);
-
-/* ucc_init_guemr
- * Init the Guemr register.
- *
- * regs - (In) pointer to registers base for the UCC.
- */
-int ucc_init_guemr(struct ucc_common *regs);
+int ucc_set_type(unsigned int ucc_num, enum ucc_speed_type speed);
int ucc_set_qe_mux_mii_mng(int ucc_num);
diff --git a/include/asm-powerpc/ucc_slow.h b/include/asm-powerpc/ucc_slow.h
index fdaac9d..0980e6a 100644
--- a/include/asm-powerpc/ucc_slow.h
+++ b/include/asm-powerpc/ucc_slow.h
@@ -148,9 +148,10 @@ enum ucc_slow_diag_mode {
struct ucc_slow_info {
int ucc_num;
+ int protocol; /* QE_CR_PROTOCOL_xxx */
enum qe_clock rx_clock;
enum qe_clock tx_clock;
- u32 regs;
+ phys_addr_t regs;
int irq;
u16 uccm_mask;
int data_mem_part;
@@ -186,7 +187,7 @@ struct ucc_slow_info {
struct ucc_slow_private {
struct ucc_slow_info *us_info;
- struct ucc_slow *us_regs; /* a pointer to memory map of UCC regs */
+ struct ucc_slow __iomem *us_regs; /* Ptr to memory map of UCC regs */
struct ucc_slow_pram *us_pram; /* a pointer to the parameter RAM */
u32 us_pram_offset;
int enabled_tx; /* Whether channel is enabled for Tx (ENT) */
@@ -277,12 +278,12 @@ void ucc_slow_graceful_stop_tx(struct ucc_slow_private * uccs);
*/
void ucc_slow_stop_tx(struct ucc_slow_private * uccs);
-/* ucc_slow_restart_x
+/* ucc_slow_restart_tx
* Restarts transmitting on a specified slow UCC.
*
* uccs - (In) pointer to the slow UCC structure.
*/
-void ucc_slow_restart_x(struct ucc_slow_private * uccs);
+void ucc_slow_restart_tx(struct ucc_slow_private *uccs);
u32 ucc_slow_get_qe_cr_subblock(int uccs_num);
--
1.5.2.4
^ permalink raw reply related
* Re: Sequoia kernel crash workaround.
From: Olof Johansson @ 2007-09-19 19:30 UTC (permalink / raw)
To: Stefan Roese; +Cc: linuxppc-dev, Josh Boyer, David Gibson
In-Reply-To: <200709192119.48259.sr@denx.de>
On Wed, Sep 19, 2007 at 09:19:47PM +0200, Stefan Roese wrote:
> Hi Valentine,
>
> On Wednesday 19 September 2007, Valentine Barshak wrote:
> > Disabling write pipelining really helps.
> > Josh, David, what is the right place to put this workaround to?
> >
> > Is it OK to do mtdcr(PLB4A0_ACR, mfdcr(PLB4A0_ACR) & ~PLB4_WRP); in
> > arch/powerpc/boot/cuboot-sequoia.c:sequoia_fixups()?
> > or
> > should this be done in
> > arch/powerpc/platforms/44x/sequoia.c:sequoia_setup_arch()
> > with dcr_map, dcr_read/write stuff?
>
> I vote for putting it into sequoia.c, since it's very likely to happen that
> Sequoia will at one point be booted without the bootwrapper. Or perhaps it
> should go into some common code checking the PVR and disabling it when this
> 440EPx/GRx is detected, since all those boards are affected.
This is what we have setup_cpu functions in the cpu table for. Please
put it there instead of in board code.
-Olof
^ permalink raw reply
* Re: Sequoia kernel crash workaround.
From: Stefan Roese @ 2007-09-19 19:19 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Josh Boyer, David Gibson
In-Reply-To: <46F16CC9.3010003@ru.mvista.com>
Hi Valentine,
On Wednesday 19 September 2007, Valentine Barshak wrote:
> Disabling write pipelining really helps.
> Josh, David, what is the right place to put this workaround to?
>
> Is it OK to do mtdcr(PLB4A0_ACR, mfdcr(PLB4A0_ACR) & ~PLB4_WRP); in
> arch/powerpc/boot/cuboot-sequoia.c:sequoia_fixups()?
> or
> should this be done in
> arch/powerpc/platforms/44x/sequoia.c:sequoia_setup_arch()
> with dcr_map, dcr_read/write stuff?
I vote for putting it into sequoia.c, since it's very likely to happen that
Sequoia will at one point be booted without the bootwrapper. Or perhaps it
should go into some common code checking the PVR and disabling it when this
440EPx/GRx is detected, since all those boards are affected.
Best regards,
Stefan
^ permalink raw reply
* [PATCH] powerpc: rheap-managed bootmem allocator
From: Timur Tabi @ 2007-09-19 19:15 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Timur Tabi
Add the ability to allocate a block of memory via alloc_bootmem() and manage
that memory with a remote heap (rheap).
Signed-off-by: Timur Tabi <timur@freescale.com>
---
This patch will conflict with Sylvain's "powerpc: Changes the config mechanism
for rheap" patch, but that patch hasn't been accepted yet, so I'm posting this
for review and comment.
arch/powerpc/lib/rheap.c | 79 +++++++++++++++++++++++++++++++++++++++++++
include/asm-powerpc/rheap.h | 4 ++
2 files changed, 83 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/lib/rheap.c b/arch/powerpc/lib/rheap.c
index ada5b42..d2c8913 100644
--- a/arch/powerpc/lib/rheap.c
+++ b/arch/powerpc/lib/rheap.c
@@ -18,6 +18,8 @@
#include <linux/mm.h>
#include <linux/err.h>
#include <linux/slab.h>
+#include <linux/bootmem.h>
+#include <linux/module.h>
#include <asm/rheap.h>
@@ -729,3 +731,80 @@ void rh_dump_blk(rh_info_t * info, rh_block_t * blk)
"blk @0x%p: 0x%lx-0x%lx (%u)\n",
blk, blk->start, blk->start + blk->size, blk->size);
}
+
+/* Bootmem-allocated rheap
+ *
+ * If the "rhbootmem=X" command-line parameter is specified, then the RHEAP
+ * code will allocate a chunk of memory using alloc_bootmem() and create an
+ * rheap for it.
+*/
+
+static rh_info_t bootmem_rh_info;
+static rh_block_t bootmem_rh_block[16];
+
+static void *bootmem_ptr;
+static unsigned long bootmem_size;
+
+static int __init early_parse_rhbootmem(char *p)
+{
+ if (!p)
+ return 1;
+
+ bootmem_size = _ALIGN_UP(memparse(p, &p), 32);
+
+ return 0;
+}
+early_param("rhbootmem", early_parse_rhbootmem);
+
+static int __init rheap_bootmem_init(void)
+{
+ if (!bootmem_size)
+ return 0;
+
+ bootmem_ptr = __alloc_bootmem(bootmem_size, 32, 0);
+ if (!bootmem_ptr) {
+ printk(KERN_ERR "rheap: cannot allocate %lu bootmem bytes\n",
+ bootmem_size);
+ return -ENOMEM;
+ }
+
+ rh_init(&bootmem_rh_info, 32, ARRAY_SIZE(bootmem_rh_block),
+ bootmem_rh_block);
+
+ rh_attach_region(&bootmem_rh_info, bootmem_ptr, bootmem_size);
+
+ printk(KERN_INFO "rheap: allocated %lu bootmem bytes\n", bootmem_size);
+
+ return 0;
+}
+arch_initcall(rheap_bootmem_init);
+
+/* Allocatate a block from the bootmem
+ *
+ * This function allocates a block of memory from the bootmem
+ */
+void *rheap_bootmem_alloc(size_t size)
+{
+ return rh_alloc(&bootmem_rh_info, size, "BOOTMEM");
+}
+EXPORT_SYMBOL(rheap_bootmem_alloc);
+
+/* Free a previously allocated block
+ */
+void rheap_bootmem_free(void *p, size_t size)
+{
+ if (p)
+ rh_free(&bootmem_rh_info, p);
+}
+EXPORT_SYMBOL(rheap_bootmem_free);
+
+/* Returns 1 if pointer is inside bootmem
+ *
+ * This function tells you if the given pointer points to the allocated
+ * bootmem.
+ */
+int rheap_is_bootmem(void *p)
+{
+ return (p >= bootmem_ptr) && (p < (bootmem_ptr + bootmem_size));
+}
+EXPORT_SYMBOL(rheap_is_bootmem);
diff --git a/include/asm-powerpc/rheap.h b/include/asm-powerpc/rheap.h
index 1723817..5a8dee1 100644
--- a/include/asm-powerpc/rheap.h
+++ b/include/asm-powerpc/rheap.h
@@ -86,4 +86,8 @@ extern void rh_dump(rh_info_t * info);
/* Set owner of taken block */
extern int rh_set_owner(rh_info_t * info, unsigned long start, const char *owner);
+void *rheap_bootmem_alloc(size_t size);
+void rheap_bootmem_free(void *p, size_t size);
+int rheap_is_bootmem(void *p);
+
#endif /* __ASM_PPC_RHEAP_H__ */
--
1.5.2.4
^ permalink raw reply related
* Re: Sequoia kernel crash workaround.
From: Josh Boyer @ 2007-09-19 19:12 UTC (permalink / raw)
To: Valentine Barshak; +Cc: linuxppc-dev, David Gibson
In-Reply-To: <46F16CC9.3010003@ru.mvista.com>
On Wed, 19 Sep 2007 22:39:05 +0400
Valentine Barshak <vbarshak@ru.mvista.com> wrote:
> I've observed kernel crashes on Sequoia board several times.
> Kernel often crashes with high network/memory loads.
> This is due to 440EPx h/w issue.
>
> According to the errata:
> CHIP_8: Incorrect Write to DDR SDRAM.
> Category: 3
> Overview:
> The write address can be corrupted during writes to DDR SDRAM when write
> pipelining is enabled on PLB0. The probability of encountering the
> problem increases with the amount of back-pressure applied by the SDRAM.
> Impact: Data can be written to the wrong address in SDRAM.
> Workaround:
> Disable write pipelining to DDR SDRAM by setting PLB4A0_ACR[WRP] = 0.
> Only primary write transfers are broadcast and the write address
> corruption is avoided.
Ew. That sounds nasty.
> Disabling write pipelining really helps.
> Josh, David, what is the right place to put this workaround to?
>
> Is it OK to do mtdcr(PLB4A0_ACR, mfdcr(PLB4A0_ACR) & ~PLB4_WRP); in
> arch/powerpc/boot/cuboot-sequoia.c:sequoia_fixups()?
> or
> should this be done in
> arch/powerpc/platforms/44x/sequoia.c:sequoia_setup_arch()
> with dcr_map, dcr_read/write stuff?
Hm, do you happen to know if AMCC is going to release a newer revision
of 440EPx with that fixed? If so, we should probably do it
conditionally based off of PVR.
As for where to do it, I'd rather it be in sequoia_setup_arch() than
the bootwrapper. Eventually bootloaders like U-Boot will take a raw
vmlinux so the wrapper won't even be there anymore.
I don't see any reason to use the dcr_map stuff either. Just check the
PVR, check if the PLB is already set up correctly, and if not set it
with the regular mfdcr/mtdcr functions. And a comment about why that's
being done would be good.
That's my $0.02 anyway.
josh
^ permalink raw reply
* Re: Problem booting linux with device tree table
From: Jon Loeliger @ 2007-09-19 19:05 UTC (permalink / raw)
To: Bartlomiej Sieka; +Cc: linuxppc-embedded@ozlabs.org
In-Reply-To: <46EF8715.4030707@semihalf.com>
On Tue, 2007-09-18 at 03:06, Bartlomiej Sieka wrote:
> The following switches to dtc taken from
> http://www.denx.de/wiki/UBoot/UBootFdtInfo work for me:
>
> dtc -b 0 -V 17 -R 4 -S 0x3000 -I dts -O dtb -f tqm5200.dts > tqm5200.dtb
-V 17 is the current default, btw.
jdl
^ permalink raw reply
* Re: Configuration-Problem ext-interrupt on mpc52xx
From: S. Fricke @ 2007-09-19 19:01 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <fa686aa40709190809v284618d4r65674a1409ab0b57@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1493 bytes --]
Hello,
> On 9/19/07, S. Fricke <silvio.fricke@googlemail.com> wrote:
> > Hi,
> >
> > how can i configure an "ext interrupt" to high-level? I want a interruption on
> > IRQ2, but I checked with an oscilloscope that the pin has a low state and I
> > needs a high state.
> >
> > I have tried, after I got the irq (with irq_of_parse_and_map), set it with
> >
> > set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
> >
> > But I think it is a system-configuration (irq_desc) and no
> > device-configuration.
>
> You shouldn't need to do this. You set your sense level in the device tree.
>
> From your previous email, your device node looks like this:
> > intpin@0 {
> > interrupt-parent = <500>;
> > interrupts = <1 2 2>;
> > };
>
> Which is IRQ2, EDGE_FALLING.
>
> If you change your interrupts property to <1 2 0>, then your sense is
> set to LEVEL_HIGH. (Seriously, you need to read the interrupts
> section of Documentation/powerpc/mpc52xx-device-tree-bindings.txt.)
I have read it! But another driver on Boot-time pulled my interrupt to low, I
can't do anything except for looking at the oscilloscope
I'm going to disable all unneeded drivers tomorrow morning.
TIA:
Silvio Fricke
--
-- S. Fricke ----------------------------- MAILTO:silvio.fricke@gmail.com --
Diplom-Informatiker (FH)
Linux-Entwicklung
----------------------------------------------------------------------------
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox