* Re: [PATCH v2] create modalias file in sysfs for bus of_platform
From: Stephen Rothwell @ 2008-01-22 14:58 UTC (permalink / raw)
To: Olaf Hering; +Cc: sparclinux, linuxppc-dev
In-Reply-To: <20080122144053.GA13019@aepfle.de>
[-- Attachment #1: Type: text/plain, Size: 2185 bytes --]
Hi Olaf,
Thanks for doing this. Patches to drivers/of should also be cc'd to the
Sparc guys as they share this stuff with is, now.
Also, drivers/macintosh/macio_sysfs.c does this for itself, so that
should probably be removed.
On Tue, 22 Jan 2008 15:40:53 +0100 Olaf Hering <olaf@aepfle.de> wrote:
>
> Create /sys/bus/of_platform/devices/*/modalias file to allow autoloading
> of modules. modalias files are already present for many other bus types.
>
> Signed-off-by: Olaf Hering <olaf@aepfle.de>
>
> ---
> drivers/of/device.c | 19 +++++++++++++++++++
> 1 file changed, 19 insertions(+)
>
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -86,7 +86,20 @@ static ssize_t dev_show_devspec(struct d
> return sprintf(buf, "%s", ofdev->node->full_name);
> }
>
> +static ssize_t dev_show_modalias(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct of_device *ofdev = to_of_device(dev);
> + ssize_t len = 0;
> +
> + len = of_device_get_modalias(ofdev, buf, PAGE_SIZE);
Should you pass (PAGE_SIZE - 1 (or 2)) here?
> + buf[len] = '\n';
> + buf[len+1] = 0;
> + return len+1;
> +}
> +
> static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL);
> +static DEVICE_ATTR(modalias, S_IRUGO, dev_show_modalias, NULL);
>
> /**
> * of_release_dev - free an of device structure when all users of it are finished.
> @@ -116,6 +129,11 @@ int of_device_register(struct of_device
> return rc;
>
> rc = device_create_file(&ofdev->dev, &dev_attr_devspec);
> + if (rc) {
> + device_unregister(&ofdev->dev);
> + return rc;
> + }
> + rc = device_create_file(&ofdev->dev, &dev_attr_modalias);
> if (rc)
> device_unregister(&ofdev->dev);
>
> @@ -126,6 +144,7 @@ EXPORT_SYMBOL(of_device_register);
> void of_device_unregister(struct of_device *ofdev)
> {
> device_remove_file(&ofdev->dev, &dev_attr_devspec);
> + device_remove_file(&ofdev->dev, &dev_attr_modalias);
> device_unregister(&ofdev->dev);
> }
> EXPORT_SYMBOL(of_device_unregister);
--
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: ppc32: Weird process scheduling behaviour with 2.6.24-rc
From: Michel Dänzer @ 2008-01-22 14:56 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Ingo Molnar
In-Reply-To: <1200659696.23161.81.camel@thor.sulgenrain.local>
On Fri, 2008-01-18 at 13:34 +0100, Michel Dänzer wrote:
> This is on a PowerBook5,8.
>
> In a nutshell, things seem more sluggish in general than with 2.6.23.
> But in particular, processes running at nice levels >0 can get most of
> the CPU cycles available, slowing down processes running at nice level
> 0.
The canonical test case I've come up with is to run an infinite loop
with
sudo -u nobody nice -n 19 sh -c 'while true; do true; done'
This makes my X session (X server running at nice level -1, clients at
0) unusably sluggish (it can even take several seconds to process ctrl-c
to interrupt the infinite loop) with 2.6.24-rc but works as expected
with 2.6.23.
Anybody else seeing this?
> I've seen this since .24-rc5 (the first .24-rc I tried), and it's still
> there with -rc8. I'd be surprised if this kind of behaviour remained
> unfixed for that long if it affected x86, so I presume it's powerpc
> specific.
Or maybe not... I've bisected this down to the scheduler changes between
df3d80f5a5c74168be42788364d13cf6c83c7b9c/23fd50450a34f2558070ceabb0bfebc1c9604af5 and b5869ce7f68b233ceb81465a7644be0d9a5f3dbb . I'll try and bisect it further, but this is my main work machine, so I can't reboot it too often. I'm CC'ing Ingo in case he has any ideas offhand.
--
Earthling Michel Dänzer | http://tungstengraphics.com
Libre software enthusiast | Debian, X and DRI developer
^ permalink raw reply
* [PATCH v2] create modalias file in sysfs for bus of_platform
From: Olaf Hering @ 2008-01-22 14:40 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <20080122142109.GA12967@aepfle.de>
Create /sys/bus/of_platform/devices/*/modalias file to allow autoloading
of modules. modalias files are already present for many other bus types.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
drivers/of/device.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -86,7 +86,20 @@ static ssize_t dev_show_devspec(struct d
return sprintf(buf, "%s", ofdev->node->full_name);
}
+static ssize_t dev_show_modalias(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct of_device *ofdev = to_of_device(dev);
+ ssize_t len = 0;
+
+ len = of_device_get_modalias(ofdev, buf, PAGE_SIZE);
+ buf[len] = '\n';
+ buf[len+1] = 0;
+ return len+1;
+}
+
static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL);
+static DEVICE_ATTR(modalias, S_IRUGO, dev_show_modalias, NULL);
/**
* of_release_dev - free an of device structure when all users of it are finished.
@@ -116,6 +129,11 @@ int of_device_register(struct of_device
return rc;
rc = device_create_file(&ofdev->dev, &dev_attr_devspec);
+ if (rc) {
+ device_unregister(&ofdev->dev);
+ return rc;
+ }
+ rc = device_create_file(&ofdev->dev, &dev_attr_modalias);
if (rc)
device_unregister(&ofdev->dev);
@@ -126,6 +144,7 @@ EXPORT_SYMBOL(of_device_register);
void of_device_unregister(struct of_device *ofdev)
{
device_remove_file(&ofdev->dev, &dev_attr_devspec);
+ device_remove_file(&ofdev->dev, &dev_attr_modalias);
device_unregister(&ofdev->dev);
}
EXPORT_SYMBOL(of_device_unregister);
^ permalink raw reply
* Re: [PATCH 3/4] Convert axon_msi to an of_platform driver
From: Stephen Rothwell @ 2008-01-22 14:38 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, cbe-oss-dev
In-Reply-To: <c04b1ca531fcd78c42c5a13802c1c331f9b4c8a7.1200999872.git.michael@ellerman.id.au>
[-- Attachment #1: Type: text/plain, Size: 399 bytes --]
Hi Michael,
On Tue, 22 Jan 2008 22:04:40 +1100 (EST) Michael Ellerman <michael@ellerman.id.au> wrote:
>
> +#include <asm/of_platform.h>
You must have missed the lectures :-) Please use linux/of_platform.h
> +static struct of_device_id axon_msi_device_id[] = {
const, please.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH 2/4] Create and hook up of_platform_device_shutdown
From: Stephen Rothwell @ 2008-01-22 14:34 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, cbe-oss-dev
In-Reply-To: <bb8d7cc1a060af291ef6efb0f4222f81fa91f417.1200999872.git.michael@ellerman.id.au>
[-- Attachment #1: Type: text/plain, Size: 787 bytes --]
Hi Michael,
Just a couple of things.
On Tue, 22 Jan 2008 22:04:40 +1100 (EST) Michael Ellerman <michael@ellerman.id.au> wrote:
>
> +static void of_platform_device_shutdown(struct device * dev)
^
No space, please.
Also, I wonder if we should check that the drivers that already have
specified a shutdown routine (drivers/input/misc/sparcspkr.c,
drivers/usb/host/ohci-ppc-of.c and drivers/watchdog/mpc5200_wdt.c) are
actually ok if it actually gets called. :-)
Also, patches like this should be cc'd to (at least) the sparc guys
(sparclinux@vger.kernel.org) since they share this stuff with us, now.
--
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
* [PATCH] create modalias file in sysfs for bus of_platform
From: Olaf Hering @ 2008-01-22 14:21 UTC (permalink / raw)
To: linuxppc-dev
Create /sys/bus/of_platform/devices/*/modalias file to allow autoloading
of modules. modalias files are already present for many other bus types.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
drivers/of/device.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -86,7 +86,19 @@ static ssize_t dev_show_devspec(struct d
return sprintf(buf, "%s", ofdev->node->full_name);
}
+static ssize_t dev_show_modalias(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct of_device *ofdev = to_of_device(dev);
+ ssize_t len = 0;
+
+ if (ofdev)
+ len = of_device_get_modalias(ofdev, buf, PAGE_SIZE);
+ return len;
+}
+
static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL);
+static DEVICE_ATTR(modalias, S_IRUGO, dev_show_modalias, NULL);
/**
* of_release_dev - free an of device structure when all users of it are finished.
@@ -116,6 +128,11 @@ int of_device_register(struct of_device
return rc;
rc = device_create_file(&ofdev->dev, &dev_attr_devspec);
+ if (rc) {
+ device_unregister(&ofdev->dev);
+ return rc;
+ }
+ rc = device_create_file(&ofdev->dev, &dev_attr_modalias);
if (rc)
device_unregister(&ofdev->dev);
@@ -126,6 +143,7 @@ EXPORT_SYMBOL(of_device_register);
void of_device_unregister(struct of_device *ofdev)
{
device_remove_file(&ofdev->dev, &dev_attr_devspec);
+ device_remove_file(&ofdev->dev, &dev_attr_modalias);
device_unregister(&ofdev->dev);
}
EXPORT_SYMBOL(of_device_unregister);
^ permalink raw reply
* Re: [PATCH] create modalias file in sysfs for bus vio
From: Stephen Rothwell @ 2008-01-22 14:05 UTC (permalink / raw)
To: Olaf Hering; +Cc: linuxppc-dev
In-Reply-To: <20080122083328.GA11928@aepfle.de>
[-- Attachment #1: Type: text/plain, Size: 824 bytes --]
Hi Olaf,
Thanks for this. Just a couple of nits ...
On Tue, 22 Jan 2008 09:33:28 +0100 Olaf Hering <olaf@aepfle.de> wrote:
>
> +static ssize_t modalias_show (struct device *dev, struct device_attribute *attr,
^
No space here, please.
> + char *buf)
> +{
> + struct device_node *of_node = dev->archdata.of_node;
> + const char *compat;
> + int i = 0;
> +
> + if (of_node) {
> + compat = of_get_property(of_node, "compatible", &i);
> + i = sprintf (buf, "vio:T%sS%s\n", of_node->type, compat ? compat : "");
^
Or here.
It would be nice if we could factor out the "vio:T%sS%s" string as it is
also used in vio_hotplug().
--
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: Generated xilinx linux 2.6 image sections
From: greenlean @ 2008-01-22 13:28 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <15015244.post@talk.nabble.com>
Now It's running the problem was the DDR controller I was including the 512
one but I'm working with a 256 DDR module .......
Thanks for the orientation, really usefull.
Bye.
Stephen Neuendorffer wrote:
>
> The testapps are generated using a different linker script.
>
> Based on what you sent out, it looks like your EDK design has a memory
> at 0x10000000, but this is
> not reflected in the linux image you've generated. This makes me
> suspect that you haven't generated the BSP and copied the appropriate
> xparameters file over xparameters_xup.h (assuming you are using
> CONFIG_XILINX_XUPV2P).
>
> Steve
>
>> -----Original Message-----
>> From: linuxppc-embedded-bounces+stephen=neuendorffer.name@ozlabs.org
> [mailto:linuxppc-embedded-
>> bounces+stephen=neuendorffer.name@ozlabs.org] On Behalf Of greenlean
>> Sent: Monday, January 21, 2008 5:06 AM
>> To: linuxppc-embedded@ozlabs.org
>> Subject: Generated xilinx linux 2.6 image sections
>>
>>
>> Hi all,
>>
>> I'm trying to boot the 2.6 xilinx kernel downloaded from their git
> server in
>> the XUPV2P board I'm really having troubles (I can't see anything in
> the
>> minicom console terminal). I'm not seeing anything, neither the
> ucompressing
>> kernel string nor the prompt with the memory addresses that kernel
> prompt at
>> first time, so I have started to distrust of anything.
>>
>>
>> Linuxppc-embedded@ozlabs.org
>> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
>
--
View this message in context: http://www.nabble.com/Generated-xilinx-linux-2.6--image-sections-tp14997109p15018508.html
Sent from the linuxppc-embedded mailing list archive at Nabble.com.
^ permalink raw reply
* [PATCH 4/4] Avoid DMA exception when using axon_msi with IOMMU
From: Michael Ellerman @ 2008-01-22 11:04 UTC (permalink / raw)
To: linuxppc-dev; +Cc: cbe-oss-dev
In-Reply-To: <3ce7be4c77581ce103a8da9f33a734270c9dc6e8.1200999872.git.michael@ellerman.id.au>
There's a brown-paper-bag bug in axon_msi, we pass the address of our
FIFO directly to the hardware, without DMA mapping it. This leads to
DMA exceptions if you enable MSI & the IOMMU.
The fix is to correctly DMA map the fifo, dma_alloc_coherent() does
what we want - and we need to track the virt & phys addresses.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/cell/axon_msi.c | 21 ++++++++++-----------
1 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 8de3d23..c546879 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -65,7 +65,8 @@
struct axon_msic {
struct irq_host *irq_host;
- __le32 *fifo;
+ __le32 *fifo_virt;
+ dma_addr_t fifo_phys;
dcr_host_t dcr_host;
u32 read_offset;
};
@@ -91,7 +92,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
while (msic->read_offset != write_offset) {
idx = msic->read_offset / sizeof(__le32);
- msi = le32_to_cpu(msic->fifo[idx]);
+ msi = le32_to_cpu(msic->fifo_virt[idx]);
msi &= 0xFFFF;
pr_debug("axon_msi: woff %x roff %x msi %x\n",
@@ -306,7 +307,6 @@ static int axon_msi_shutdown(struct of_device *device)
static int axon_msi_probe(struct of_device *device,
const struct of_device_id *device_id)
{
- struct page *page;
struct device_node *dn = device->node;
struct axon_msic *msic;
unsigned int virq;
@@ -338,16 +338,14 @@ static int axon_msi_probe(struct of_device *device,
goto out_free_msic;
}
- page = alloc_pages_node(of_node_to_nid(dn), GFP_KERNEL,
- get_order(MSIC_FIFO_SIZE_BYTES));
- if (!page) {
+ msic->fifo_virt = dma_alloc_coherent(&device->dev, MSIC_FIFO_SIZE_BYTES,
+ &msic->fifo_phys, GFP_KERNEL);
+ if (!msic->fifo_virt) {
printk(KERN_ERR "axon_msi: couldn't allocate fifo for %s\n",
dn->full_name);
goto out_free_msic;
}
- msic->fifo = page_address(page);
-
msic->irq_host = irq_alloc_host(of_node_get(dn), IRQ_HOST_MAP_NOMAP,
NR_IRQS, &msic_host_ops, 0);
if (!msic->irq_host) {
@@ -370,9 +368,9 @@ static int axon_msi_probe(struct of_device *device,
pr_debug("axon_msi: irq 0x%x setup for axon_msi\n", virq);
/* Enable the MSIC hardware */
- msic_dcr_write(msic, MSIC_BASE_ADDR_HI_REG, (u64)msic->fifo >> 32);
+ msic_dcr_write(msic, MSIC_BASE_ADDR_HI_REG, msic->fifo_phys >> 32);
msic_dcr_write(msic, MSIC_BASE_ADDR_LO_REG,
- (u64)msic->fifo & 0xFFFFFFFF);
+ msic->fifo_phys & 0xFFFFFFFF);
msic_dcr_write(msic, MSIC_CTRL_REG,
MSIC_CTRL_IRQ_ENABLE | MSIC_CTRL_ENABLE |
MSIC_CTRL_FIFO_SIZE);
@@ -390,7 +388,8 @@ static int axon_msi_probe(struct of_device *device,
out_free_host:
kfree(msic->irq_host);
out_free_fifo:
- __free_pages(virt_to_page(msic->fifo), get_order(MSIC_FIFO_SIZE_BYTES));
+ dma_free_coherent(&device->dev, MSIC_FIFO_SIZE_BYTES, msic->fifo_virt,
+ msic->fifo_phys);
out_free_msic:
kfree(msic);
out:
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 3/4] Convert axon_msi to an of_platform driver
From: Michael Ellerman @ 2008-01-22 11:04 UTC (permalink / raw)
To: linuxppc-dev; +Cc: cbe-oss-dev
In-Reply-To: <3ce7be4c77581ce103a8da9f33a734270c9dc6e8.1200999872.git.michael@ellerman.id.au>
Now that we create of_platform devices earlier on cell, we can make the
axon_msi driver an of_platform driver. This makes the code cleaner in
several ways, and most importantly means we have a struct device.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/cell/axon_msi.c | 76 ++++++++++++++-----------------
1 files changed, 34 insertions(+), 42 deletions(-)
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 095988f..8de3d23 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -13,8 +13,8 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/msi.h>
-#include <linux/reboot.h>
+#include <asm/of_platform.h>
#include <asm/dcr.h>
#include <asm/machdep.h>
#include <asm/prom.h>
@@ -67,12 +67,9 @@ struct axon_msic {
struct irq_host *irq_host;
__le32 *fifo;
dcr_host_t dcr_host;
- struct list_head list;
u32 read_offset;
};
-static LIST_HEAD(axon_msic_list);
-
static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val)
{
pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n);
@@ -292,30 +289,25 @@ static struct irq_host_ops msic_host_ops = {
.map = msic_host_map,
};
-static int axon_msi_notify_reboot(struct notifier_block *nb,
- unsigned long code, void *data)
+static int axon_msi_shutdown(struct of_device *device)
{
- struct axon_msic *msic;
+ struct axon_msic *msic = device->dev.platform_data;
u32 tmp;
- list_for_each_entry(msic, &axon_msic_list, list) {
- pr_debug("axon_msi: disabling %s\n",
- msic->irq_host->of_node->full_name);
- tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG);
- tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE;
- msic_dcr_write(msic, MSIC_CTRL_REG, tmp);
- }
+ pr_debug("axon_msi: disabling %s\n",
+ msic->irq_host->of_node->full_name);
+ tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG);
+ tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE;
+ msic_dcr_write(msic, MSIC_CTRL_REG, tmp);
return 0;
}
-static struct notifier_block axon_msi_reboot_notifier = {
- .notifier_call = axon_msi_notify_reboot
-};
-
-static int axon_msi_setup_one(struct device_node *dn)
+static int axon_msi_probe(struct of_device *device,
+ const struct of_device_id *device_id)
{
struct page *page;
+ struct device_node *dn = device->node;
struct axon_msic *msic;
unsigned int virq;
int dcr_base, dcr_len;
@@ -385,7 +377,11 @@ static int axon_msi_setup_one(struct device_node *dn)
MSIC_CTRL_IRQ_ENABLE | MSIC_CTRL_ENABLE |
MSIC_CTRL_FIFO_SIZE);
- list_add(&msic->list, &axon_msic_list);
+ device->dev.platform_data = msic;
+
+ ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs;
+ ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs;
+ ppc_md.msi_check_device = axon_msi_check_device;
printk(KERN_DEBUG "axon_msi: setup MSIC on %s\n", dn->full_name);
@@ -402,28 +398,24 @@ out:
return -1;
}
-static int axon_msi_init(void)
-{
- struct device_node *dn;
- int found = 0;
-
- pr_debug("axon_msi: initialising ...\n");
-
- for_each_compatible_node(dn, NULL, "ibm,axon-msic") {
- if (axon_msi_setup_one(dn) == 0)
- found++;
- }
-
- if (found) {
- ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs;
- ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs;
- ppc_md.msi_check_device = axon_msi_check_device;
-
- register_reboot_notifier(&axon_msi_reboot_notifier);
+static struct of_device_id axon_msi_device_id[] = {
+ {
+ .compatible = "ibm,axon-msic"
+ },
+ {}
+};
- pr_debug("axon_msi: registered callbacks!\n");
- }
+static struct of_platform_driver axon_msi_driver = {
+ .match_table = axon_msi_device_id,
+ .probe = axon_msi_probe,
+ .shutdown = axon_msi_shutdown,
+ .driver = {
+ .name = "axon-msi"
+ },
+};
- return 0;
+static int __init axon_msi_init(void)
+{
+ return of_register_platform_driver(&axon_msi_driver);
}
-arch_initcall(axon_msi_init);
+subsys_initcall(axon_msi_init);
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 2/4] Create and hook up of_platform_device_shutdown
From: Michael Ellerman @ 2008-01-22 11:04 UTC (permalink / raw)
To: linuxppc-dev; +Cc: cbe-oss-dev
In-Reply-To: <3ce7be4c77581ce103a8da9f33a734270c9dc6e8.1200999872.git.michael@ellerman.id.au>
Although of_platform_device's can have a shutdown routine, at the moment
the bus code doesn't actually call it. So add the required glue to
hook the shutdown routine.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
drivers/of/platform.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index b47bb2d..9152479 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -85,6 +85,15 @@ static int of_platform_device_resume(struct device * dev)
return error;
}
+static void of_platform_device_shutdown(struct device * dev)
+{
+ struct of_device *of_dev = to_of_device(dev);
+ struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
+
+ if (dev->driver && drv->shutdown)
+ drv->shutdown(of_dev);
+}
+
int of_bus_type_init(struct bus_type *bus, const char *name)
{
bus->name = name;
@@ -93,6 +102,7 @@ int of_bus_type_init(struct bus_type *bus, const char *name)
bus->remove = of_platform_device_remove;
bus->suspend = of_platform_device_suspend;
bus->resume = of_platform_device_resume;
+ bus->shutdown = of_platform_device_shutdown;
return bus_register(bus);
}
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 1/4] Search for and publish cell OF platform devices earlier
From: Michael Ellerman @ 2008-01-22 11:04 UTC (permalink / raw)
To: linuxppc-dev; +Cc: cbe-oss-dev
Currently cell publishes OF devices at device_initcall() time, which
means the earliest a driver can bind to a device is also device_initcall()
time. We have a driver we want to register before other devices, so
publish the devices at subsys_initcall() time.
This should not cause any behaviour change for existing drivers, as they
are still bound at device_initcall() time.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/cell/setup.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index e6534b5..a7f609b 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -98,7 +98,7 @@ static int __init cell_publish_devices(void)
}
return 0;
}
-machine_device_initcall(cell, cell_publish_devices);
+machine_subsys_initcall(cell, cell_publish_devices);
static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc)
{
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* Re: [PATCH 2/3] i2c: Convert all new-style drivers to use module aliasing
From: Jean Delvare @ 2008-01-22 10:09 UTC (permalink / raw)
To: Jon Smirl; +Cc: David Brownell, linuxppc-dev, Linux I2C
In-Reply-To: <9e4733910801210850j39b9d51fy706b58ca15805f35@mail.gmail.com>
Hi Jon,
On Mon, 21 Jan 2008 11:50:13 -0500, Jon Smirl wrote:
> In my version of these patches new style drivers could be loaded with
> both the driver_name/name scheme and the modalias. In these patches
> new style drivers can only be loaded via modalias. Is that what you
> intended? I'm all for making new style driver only use the modalias
> scheme.
Yes, this is what I intended. I see no point in having two ways to
achieve the same result, it makes things more complex, more costly and
possibly confusing.
I would reconsider if someone points out a very good reason to keep both
schemes in parallel.
--
Jean Delvare
^ permalink raw reply
* Re: [PATCH 1/2] 8xx: Analogue & Micro Adder875 board support.
From: Stephen Rothwell @ 2008-01-22 9:57 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20080117223140.GA17300@loki.buserror.net>
[-- Attachment #1: Type: text/plain, Size: 350 bytes --]
Hi Scott,
Just one small thing.
On Thu, 17 Jan 2008 16:31:40 -0600 Scott Wood <scottwood@freescale.com> wrote:
>
> +static __initdata struct of_device_id __initdata of_bus_ids[] = {
You don't need to mark it __initdata twice ...
--
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: Generated xilinx linux 2.6 image sections
From: greenlean @ 2008-01-22 9:30 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <20080121184553.569BF179805C@mail212-sin.bigfish.com>
I've got two DDR memories declared on my EDK xparameters_ml300.h file
/* Definitions for driver DDR */
#define XPAR_XDDR_NUM_INSTANCES 1
/* Definitions for peripheral DDR_512MB_64MX64_RANK2_ROW13_COL10_CL2_5 */
#define XPAR_DDR_512MB_64MX64_RANK2_ROW13_COL10_CL2_5_ECC_BASEADDR
0xFFFFFFFF
#define XPAR_DDR_512MB_64MX64_RANK2_ROW13_COL10_CL2_5_ECC_HIGHADDR
0x00000000
#define XPAR_DDR_512MB_64MX64_RANK2_ROW13_COL10_CL2_5_DEVICE_ID 0
#define XPAR_DDR_512MB_64MX64_RANK2_ROW13_COL10_CL2_5_INCLUDE_ECC_INTR 0
/******************************************************************/
/* Definitions for peripheral DDR_512MB_64MX64_RANK2_ROW13_COL10_CL2_5 */
#define XPAR_DDR_512MB_64MX64_RANK2_ROW13_COL10_CL2_5_MEM0_BASEADDR
0x00000000
#define XPAR_DDR_512MB_64MX64_RANK2_ROW13_COL10_CL2_5_MEM0_HIGHADDR
0x0FFFFFFF
#define XPAR_DDR_512MB_64MX64_RANK2_ROW13_COL10_CL2_5_MEM1_BASEADDR
0x10000000
#define XPAR_DDR_512MB_64MX64_RANK2_ROW13_COL10_CL2_5_MEM1_HIGHADDR
0x1FFFFFFF
/******************************************************************/
/* Definitions for peripheral PLB_BRAM_IF_CNTLR_1 */
#define XPAR_PLB_BRAM_IF_CNTLR_1_BASEADDR 0xfffe0000
#define XPAR_PLB_BRAM_IF_CNTLR_1_HIGHADDR 0xffffffff
/******************************************************************/
And my .config file is using this configuration for the memory:
CONFIG_HIGHMEM_START=0xfe000000
CONFIG_LOWMEM_SIZE=0x30000000
CONFIG_KERNEL_START=0xc0000000
CONFIG_TASK_SIZE=0x80000000
CONFIG_CONSISTENT_START=0xff100000
CONFIG_CONSISTENT_SIZE=0x00200000
CONFIG_BOOT_LOAD=0x00400000
Should I change this options to make the kernel CONFIG_BOOT_LOAD start in
the seccond MEM1?, or is the problem caused by CONFIG_CONSISTENT_START?? How
are used this variables?? Is the kernel start address out of the memory ((
0xC0000000 > 0x1FFFFFFF??
I'm using a DDR 256 from Kingston KVR266X64C25/256 and when I run the
TestApp_Memory it fails at
-- Entering main() --
Starting MemoryTest for DDR_512MB_64Mx64_rank2_row13_col10_cl2_5:
Running 32-bit test...FAILED!
Running 16-bit test...FAILED!
Running 8-bit test...FAILED!
Starting MemoryTest for DDR_512MB_64Mx64_rank2_row13_col10_cl2_5:
Running 32-bit test...PASSED!
Running 16-bit test...PASSED!
Running 8-bit test...PASSED!
-- Exiting main() --
I thought that this didn't mind but the first test is form Mem0
(XUtil_MemoryTest32((Xuint32*)XPAR_DDR_512MB_64MX64_RANK2_ROW13_COL10_CL2_5_MEM0_BASEADDR)
and the second one is for mem1 (
XUtil_MemoryTest32((Xuint32*)XPAR_DDR_512MB_64MX64_RANK2_ROW13_COL10_CL2_5_MEM1_BASEADDR,
1024, 0xAAAA5555, XUT_ALLMEMTESTS);)
and the first one is failing so if the kernel is trying to boot from mem0
(CONFIG_BOOT_LOAD=0x00400000) i shouldn't boot, or should it?
Please, can someone confirm me this, while I try myself... I'm not sure how
this addresses works!!!
Stephen Neuendorffer wrote:
>
> The testapps are generated using a different linker script.
>
> Based on what you sent out, it looks like your EDK design has a memory
> at 0x10000000, but this is
> not reflected in the linux image you've generated. This makes me
> suspect that you haven't generated the BSP and copied the appropriate
> xparameters file over xparameters_xup.h (assuming you are using
> CONFIG_XILINX_XUPV2P).
>
> Steve
>
>> -----Original Message-----
>> From: linuxppc-embedded-bounces+stephen=neuendorffer.name@ozlabs.org
> [mailto:linuxppc-embedded-
>> bounces+stephen=neuendorffer.name@ozlabs.org] On Behalf Of greenlean
>> Sent: Monday, January 21, 2008 5:06 AM
>> To: linuxppc-embedded@ozlabs.org
>> Subject: Generated xilinx linux 2.6 image sections
>>
>>
>> Hi all,
>>
>> I'm trying to boot the 2.6 xilinx kernel downloaded from their git
> server in
>> the XUPV2P board I'm really having troubles (I can't see anything in
> the
>> minicom console terminal). I'm not seeing anything, neither the
> ucompressing
>> kernel string nor the prompt with the memory addresses that kernel
> prompt at
>> first time, so I have started to distrust of anything.
>>
>> When I download the kernel using xmd, I see:
>>
>> XMD% dow imagen_UART16550_ml300.elf
>> section, .text: 0x00400000-0x0040387b
>> section, .data: 0x00404000-0x004e6fff
>> section, .bss: 0x004e7000-0x004e919f
>> Downloaded Program imagen_UART16550_ml300.elf
>> Setting PC with Program Start Address 0x00400000
>>
>> and when I download some of the TestApp generated by EDK I see:
>>
>> XMD% dow perif.elf
>> section, .vectors: 0xfffe0000-0xfffe20c3
>> section, .text: 0x10000000-0x10003b7b
>> section, .init: 0x10003b7c-0x10003b9f
>> section, .fini: 0x10003ba0-0x10003bbf
>> section, .boot0: 0xfffe20c4-0xfffe20d3
>> section, .boot: 0xfffffffc-0xffffffff
>> section, .rodata: 0x10003bc0-0x10004111
>> section, .sdata2: 0x10004114-0x10004113
>> section, .sbss2: 0x10004114-0x10004113
>> section, .data: 0x10004114-0x10004243
>> section, .got: 0x10004244-0x10004243
>> section, .got1: 0x10004244-0x10004243
>> section, .got2: 0x10004244-0x1000425f
>> section, .ctors: 0x10004260-0x10004267
>> section, .dtors: 0x10004268-0x1000426f
>> section, .fixup: 0x10004270-0x1000426f
>> section, .eh_frame: 0x10004270-0x10004277
>> section, .jcr: 0x10004278-0x1000427b
>> section, .gcc_except_table: 0x1000427c-0x100042
>> section, .sdata: 0x1000427c-0x10004293
>> section, .sbss: 0x10004294-0x100042a3
>> section, .bss: 0x100042a4-0x10004473
>> section, .stack: 0x10004474-0x1000647f
>> section, .heap: 0x10006480-0x1000847f
>> Downloaded Program perif.elf
>> Setting PC with Program Start Address 0xfffffffc
>>
>> Does anybody know why the kernel elf don't have a boot section like
> the
>> TestApp generated by EDK?
>>
>> I suppossed this is because the image kernel is compressed, but
> despite
>> beeing compressed it should have a boot section or something similar
> ???
>> It's right that the kernel start address is set to the 0x00400000??
>>
>> Or does the section .text contains all the kernel code to uncompresse
> the
>> code of the kernel??
>>
>>
>>
>> --
>> View this message in context:
> http://www.nabble.com/Generated-xilinx-linux-2.6--image-sections-
>> tp14997109p14997109.html
>> Sent from the linuxppc-embedded mailing list archive at Nabble.com.
>>
>> _______________________________________________
>> Linuxppc-embedded mailing list
>> Linuxppc-embedded@ozlabs.org
>> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
>
--
View this message in context: http://www.nabble.com/Generated-xilinx-linux-2.6--image-sections-tp14997109p15015244.html
Sent from the linuxppc-embedded mailing list archive at Nabble.com.
^ permalink raw reply
* [PATCH] create modalias file in sysfs for bus vio
From: Olaf Hering @ 2008-01-22 8:33 UTC (permalink / raw)
To: linuxppc-dev
Create /sys/bus/vio/devices/*/modalias file to allow autoloading
of modules. modalias files are already present for many other bus types.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
arch/powerpc/kernel/vio.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -296,9 +296,24 @@ static ssize_t devspec_show(struct devic
return sprintf(buf, "%s\n", of_node ? of_node->full_name : "none");
}
+static ssize_t modalias_show (struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct device_node *of_node = dev->archdata.of_node;
+ const char *compat;
+ int i = 0;
+
+ if (of_node) {
+ compat = of_get_property(of_node, "compatible", &i);
+ i = sprintf (buf, "vio:T%sS%s\n", of_node->type, compat ? compat : "");
+ }
+ return i;
+}
+
static struct device_attribute vio_dev_attrs[] = {
__ATTR_RO(name),
__ATTR_RO(devspec),
+ __ATTR_RO(modalias),
__ATTR_NULL
};
^ permalink raw reply
* Re: Endian problem when accessing internel regs on 8347
From: Bruce_Leonard @ 2008-01-22 5:33 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-embedded
In-Reply-To: <20080121164006.GA3455@ld0162-tx32.am.freescale.net>
> > Can't anyone suggest anything I can try?
>
> Beer.
>
> -Scott
Right there with you Scott! I have to apologize for the noise on the
list. Turns out my problem doesn't have anything to do with in_be32. I
didn't have print statements in enough places. I was only printing out
what was returned from the ioctl call in user space and assumed (we know
what that means ;) ) that what was coming back from the ioctl call was
what was coming back from io_read32. With better instrumenting I find
that io_read32 is just fine. Apparently my return value from the ioctl
function in my driver is getting corrupted by the time it gets to my user
space app. I don't have an answer for that one yet, but now that I'm
turned in the correct direction hopefully it'll fall out pretty quickly.
Thanks for the patience.
See 'ya!
Bruce
^ permalink raw reply
* Re: [PATCH] Make IOMMU code safe for > 132 GB of memory
From: Michael Ellerman @ 2008-01-22 4:42 UTC (permalink / raw)
To: Jeremy Kerr; +Cc: linuxppc-dev, Arnd Bergmann
In-Reply-To: <200801221420.35565.jk@ozlabs.org>
[-- Attachment #1: Type: text/plain, Size: 709 bytes --]
On Tue, 2008-01-22 at 14:20 +1100, Jeremy Kerr wrote:
> > Currently the IOMMU code allocates one page for the segment table,
> > that isn't safe if we have more than 132 GB of RAM.
> >
> > Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
>
> Acked-by: Jeremy Kerr <jk@ozlabs.org>
>
> Can I have a Cell machine with > 132GB of RAM? :D
I have one under my desk, but I need it to warm my feet, otherwise I
could give it to you.
cheers
--
Michael Ellerman
OzLabs, IBM Australia Development Lab
wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)
We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH] Make IOMMU code safe for > 132 GB of memory
From: Jeremy Kerr @ 2008-01-22 3:20 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, Arnd Bergmann
In-Reply-To: <259a1d6aca476af7c572bdfea564a8a17aca3244.1200898886.git.michael@ellerman.id.au>
> Currently the IOMMU code allocates one page for the segment table,
> that isn't safe if we have more than 132 GB of RAM.
>
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Acked-by: Jeremy Kerr <jk@ozlabs.org>
Can I have a Cell machine with > 132GB of RAM? :D
Jeremy
^ permalink raw reply
* Re: [i2c] [PATCH 19 3/5] Clean up error returns
From: Benjamin Herrenschmidt @ 2008-01-21 23:06 UTC (permalink / raw)
To: Jon Smirl; +Cc: Jean Delvare, linuxppc-dev, i2c, linux-kernel
In-Reply-To: <9e4733910801200718q7304bc29q38e67580613189e4@mail.gmail.com>
On Sun, 2008-01-20 at 10:18 -0500, Jon Smirl wrote:
> > So it seems to me like the polling mode code is never actually used?
> > Unless some platforms include an "empty" IRQ in their device
> > definition. Which indeed seems to be the case... but then they set
> the
> > IRQ to 0, NOT to NO_IRQ, so I'm wondering if the change you propose
> is
> > really correct.
>
> All of this is very confusing to me, There are physical IRQs and
> virtual IRQs. Apparently zero is a legal physical IRQ but it is not a
> legal virtual IRQ. We only get virtual IRQs in this code. We need to
> get BenH to give us the right answer on these two cases.
Testing against NO_IRQ for a linux IRQ number should always be correct.
Physical IRQ numbers are remapped and shouldn't be visible to drivers,
NO_IRQ is a value that never exist for a valid logical interrupt number,
that is 0 for arch/powerpc and -1 for arch/ppc.
Ben.
^ permalink raw reply
* Re: [i2c] [PATCH 19 3/5] Clean up error returns
From: Benjamin Herrenschmidt @ 2008-01-21 23:04 UTC (permalink / raw)
To: Jean Delvare; +Cc: linuxppc-dev, linux-kernel, i2c
In-Reply-To: <20080121171025.524dc465@hyperion.delvare>
On Mon, 2008-01-21 at 17:10 +0100, Jean Delvare wrote:
> Hi Jon,
>
> On Sun, 20 Jan 2008 10:39:43 -0500, Jon Smirl wrote:
> > Here' s a version with the compares to zero switched to NO_IRQ. If I
> > understand how NO_IRQ works it is the correct change. My understanding
> > is that under ppc IRQ zero was legal and NO_IRQ was -1. But then the
> > whole kernel switched to NO_IRQ = zero. Powerpc updated to NO_IRQ=0
> > and used virtual IRQs to move a physical IRQ 0 to another IRQ number.
> > ppc was not changed. This driver does not appear to have been updated
> > to track this global change since it didn't initially use the NO_IRQ
> > define everywhere.
>
> As I have already applied the part of this patch that preserves error
> values in error paths, can you please send an incremental patch that
> only fixes the IRQ issues? These are separate issues so it's better to
> have separate patches anyway.
To be clear, nowadays, checking against 0 is correct unless you intend
the driver to work with arch/ppc (which we'll deprecate soon).
Ben.
^ permalink raw reply
* Re: [PATCH] Various new ibm405 DCRN #defines
From: Benjamin Herrenschmidt @ 2008-01-21 22:57 UTC (permalink / raw)
To: Joshua Williams; +Cc: linuxppc-dev
In-Reply-To: <47952018.7050702@qlogic.com>
On Mon, 2008-01-21 at 16:43 -0600, Joshua Williams wrote:
> Various new ibm405 DCRN #defines.
>
> Signed-off-by: Joshua Williams <joshua.williams@qlogic.com>
May I ask what for ? :-) Also, it's all arch/ppc, not arch/powerpc...
nothing we want to improve to much on at this stage unless there's a
really good reason.
Cheers,
Ben.
> ---
> arch/ppc/platforms/4xx/ibm405ep.h | 3 +++
> arch/ppc/platforms/4xx/ibm405gp.h | 9 +++++++++
> arch/ppc/platforms/4xx/ibm405gpr.h | 9 +++++++++
> include/asm-ppc/ibm405.h | 27 +++++++++++++++++++++++++++
> 4 files changed, 48 insertions(+), 0 deletions(-)
>
> diff --git a/arch/ppc/platforms/4xx/ibm405ep.h
> b/arch/ppc/platforms/4xx/ibm405ep.h
> index 3ef20a5..d82a4c7 100644
> --- a/arch/ppc/platforms/4xx/ibm405ep.h
> +++ b/arch/ppc/platforms/4xx/ibm405ep.h
> @@ -139,6 +139,9 @@
> #define DCRN_UIC0_BASE 0x0C0
> #define UIC0 DCRN_UIC0_BASE
>
> +/* DCRN_SDRAM0_BASE offsets - general 405 offsets in asm/ibm405.h */
> +#define DCRN_SDRAM0_STATUS 0x24 /* SDRAM Controller Status */
> +
> #include <asm/ibm405.h>
>
> #endif /* __ASM_IBM405EP_H__ */
> diff --git a/arch/ppc/platforms/4xx/ibm405gp.h
> b/arch/ppc/platforms/4xx/ibm405gp.h
> index 9f15e55..9f7e850 100644
> --- a/arch/ppc/platforms/4xx/ibm405gp.h
> +++ b/arch/ppc/platforms/4xx/ibm405gp.h
> @@ -142,6 +142,15 @@
> #define DCRN_UIC0_BASE 0x0C0
> #define UIC0 DCRN_UIC0_BASE
>
> +/* DCRN_SDRAM0_BASE offsets - general 405 offsets in asm/ibm405.h */
> +#define DCRN_SDRAM0_BESR0 0x00 /* Bus Error Syndrome Reg 0 */
> +#define DCRN_SDRAM0_BESR1 0x08 /* Bus Error Syndrome Reg 1 */
> +#define DCRN_SDRAM0_BEAR 0x10 /* Bus Error Address Reg */
> +#define DCRN_SDRAM0_B2CR 0x48 /* Memory Bank 2 Configuration Reg */
> +#define DCRN_SDRAM0_B3CR 0x4c /* Memory Bank 3 Configuration Reg */
> +#define DCRN_SDRAM0_ECCCFG 0x94 /* ECC Configuration */
> +#define DCRN_SDRAM0_ECCESR 0x98 /* ECC Error Status */
> +
> #include <asm/ibm405.h>
>
> #endif /* __ASM_IBM405GP_H__ */
> diff --git a/arch/ppc/platforms/4xx/ibm405gpr.h
> b/arch/ppc/platforms/4xx/ibm405gpr.h
> index 9e01f15..6f39042 100644
> --- a/arch/ppc/platforms/4xx/ibm405gpr.h
> +++ b/arch/ppc/platforms/4xx/ibm405gpr.h
> @@ -142,6 +142,15 @@
> #define DCRN_UIC0_BASE 0x0C0
> #define UIC0 DCRN_UIC0_BASE
>
> +/* DCRN_SDRAM0_BASE offsets - general 405 offsets in asm/ibm405.h */
> +#define DCRN_SDRAM0_BESR0 0x00 /* Bus Error Syndrome Reg 0 */
> +#define DCRN_SDRAM0_BESR1 0x08 /* Bus Error Syndrome Reg 1 */
> +#define DCRN_SDRAM0_BEAR 0x10 /* Bus Error Address Reg */
> +#define DCRN_SDRAM0_B2CR 0x48 /* Memory Bank 2 Configuration Reg */
> +#define DCRN_SDRAM0_B3CR 0x4c /* Memory Bank 3 Configuration Reg */
> +#define DCRN_SDRAM0_ECCCFG 0x94 /* ECC Configuration */
> +#define DCRN_SDRAM0_ECCESR 0x98 /* ECC Error Status */
> +
> #include <asm/ibm405.h>
>
> #endif /* __ASM_IBM405GPR_H__ */
> diff --git a/include/asm-ppc/ibm405.h b/include/asm-ppc/ibm405.h
> index 4e5be9e..04aaae6 100644
> --- a/include/asm-ppc/ibm405.h
> +++ b/include/asm-ppc/ibm405.h
> @@ -135,6 +135,26 @@
> #ifdef DCRN_EBC_BASE
> #define DCRN_EBCCFGADR (DCRN_EBC_BASE + 0x0) /* Peripheral Controller
> Address */
> #define DCRN_EBCCFGDATA (DCRN_EBC_BASE + 0x1) /* Peripheral Controller
> Data */
> +#define DCRN_EBC_PB0CR 0x00 /* Peripheral Bank 0 Config Reg */
> +#define DCRN_EBC_PB1CR 0x01 /* Peripheral Bank 1 Config Reg */
> +#define DCRN_EBC_PB2CR 0x02 /* Peripheral Bank 2 Config Reg */
> +#define DCRN_EBC_PB3CR 0x03 /* Peripheral Bank 3 Config Reg */
> +#define DCRN_EBC_PB4CR 0x04 /* Peripheral Bank 4 Config Reg */
> +#define DCRN_EBC_PB5CR 0x05 /* Peripheral Bank 5 Config Reg */
> +#define DCRN_EBC_PB6CR 0x06 /* Peripheral Bank 6 Config Reg */
> +#define DCRN_EBC_PB7CR 0x07 /* Peripheral Bank 7 Config Reg */
> +#define DCRN_EBC_PB0AP 0x10 /* Peripheral Bank 0 Access Parameters */
> +#define DCRN_EBC_PB1AP 0x11 /* Peripheral Bank 1 Access parameters */
> +#define DCRN_EBC_PB2AP 0x12 /* Peripheral Bank 2 Access Parameters */
> +#define DCRN_EBC_PB3AP 0x13 /* Peripheral Bank 3 Access Parameters */
> +#define DCRN_EBC_PB4AP 0x14 /* Peripheral Bank 4 Access Parameters */
> +#define DCRN_EBC_PB5AP 0x15 /* Peripheral Bank 5 Access Parameters */
> +#define DCRN_EBC_PB6AP 0x16 /* Peripheral Bank 6 Access Parameters */
> +#define DCRN_EBC_PB7AP 0x17 /* Peripheral Bank 7 Access Parameters */
> +#define DCRN_EBC_PBEAR 0x20 /* Peripheral Bus Error Address Reg */
> +#define DCRN_EBC_PBESR0 0x21 /* Peripheral Bus Error Status Reg 0 */
> +#define DCRN_EBC_PBESR1 0x22 /* Peripheral Bus Error Status Reg 1 */
> +#define DCRN_EBC_EPCR 0x23 /* External Peripheral Control Reg */
> #endif
>
> #ifdef DCRN_EXIER_BASE
> @@ -286,6 +306,13 @@
> #ifdef DCRN_SDRAM0_BASE
> #define DCRN_SDRAM0_CFGADDR (DCRN_SDRAM0_BASE + 0x0) /* Memory
> Controller Address */
> #define DCRN_SDRAM0_CFGDATA (DCRN_SDRAM0_BASE + 0x1) /* Memory
> Controller Data */
> +#define DCRN_SDRAM0_CFG 0x20 /* SDRAM Configuration */
> +#define DCRN_SDRAM0_STATUS 0x24 /* SDRAM Controller Status */
> +#define DCRN_SDRAM0_RTR 0x30 /* Refresh Timer Reg */
> +#define DCRN_SDRAM0_PMIT 0x34 /* Power Management Idle Timer */
> +#define DCRN_SDRAM0_B0CR 0x40 /* Memory Bank 0 Configuration Reg */
> +#define DCRN_SDRAM0_B1CR 0x44 /* Memory Bank 1 Configuration Reg */
> +#define DCRN_SDRAM0_TR 0x80 /* SDRAM Timing Reg */
> #endif
>
> #ifdef DCRN_OCM0_BASE
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
^ permalink raw reply
* [PATCH] Various new ibm405 DCRN #defines
From: Joshua Williams @ 2008-01-21 22:43 UTC (permalink / raw)
To: linuxppc-dev
Various new ibm405 DCRN #defines.
Signed-off-by: Joshua Williams <joshua.williams@qlogic.com>
---
arch/ppc/platforms/4xx/ibm405ep.h | 3 +++
arch/ppc/platforms/4xx/ibm405gp.h | 9 +++++++++
arch/ppc/platforms/4xx/ibm405gpr.h | 9 +++++++++
include/asm-ppc/ibm405.h | 27 +++++++++++++++++++++++++++
4 files changed, 48 insertions(+), 0 deletions(-)
diff --git a/arch/ppc/platforms/4xx/ibm405ep.h
b/arch/ppc/platforms/4xx/ibm405ep.h
index 3ef20a5..d82a4c7 100644
--- a/arch/ppc/platforms/4xx/ibm405ep.h
+++ b/arch/ppc/platforms/4xx/ibm405ep.h
@@ -139,6 +139,9 @@
#define DCRN_UIC0_BASE 0x0C0
#define UIC0 DCRN_UIC0_BASE
+/* DCRN_SDRAM0_BASE offsets - general 405 offsets in asm/ibm405.h */
+#define DCRN_SDRAM0_STATUS 0x24 /* SDRAM Controller Status */
+
#include <asm/ibm405.h>
#endif /* __ASM_IBM405EP_H__ */
diff --git a/arch/ppc/platforms/4xx/ibm405gp.h
b/arch/ppc/platforms/4xx/ibm405gp.h
index 9f15e55..9f7e850 100644
--- a/arch/ppc/platforms/4xx/ibm405gp.h
+++ b/arch/ppc/platforms/4xx/ibm405gp.h
@@ -142,6 +142,15 @@
#define DCRN_UIC0_BASE 0x0C0
#define UIC0 DCRN_UIC0_BASE
+/* DCRN_SDRAM0_BASE offsets - general 405 offsets in asm/ibm405.h */
+#define DCRN_SDRAM0_BESR0 0x00 /* Bus Error Syndrome Reg 0 */
+#define DCRN_SDRAM0_BESR1 0x08 /* Bus Error Syndrome Reg 1 */
+#define DCRN_SDRAM0_BEAR 0x10 /* Bus Error Address Reg */
+#define DCRN_SDRAM0_B2CR 0x48 /* Memory Bank 2 Configuration Reg */
+#define DCRN_SDRAM0_B3CR 0x4c /* Memory Bank 3 Configuration Reg */
+#define DCRN_SDRAM0_ECCCFG 0x94 /* ECC Configuration */
+#define DCRN_SDRAM0_ECCESR 0x98 /* ECC Error Status */
+
#include <asm/ibm405.h>
#endif /* __ASM_IBM405GP_H__ */
diff --git a/arch/ppc/platforms/4xx/ibm405gpr.h
b/arch/ppc/platforms/4xx/ibm405gpr.h
index 9e01f15..6f39042 100644
--- a/arch/ppc/platforms/4xx/ibm405gpr.h
+++ b/arch/ppc/platforms/4xx/ibm405gpr.h
@@ -142,6 +142,15 @@
#define DCRN_UIC0_BASE 0x0C0
#define UIC0 DCRN_UIC0_BASE
+/* DCRN_SDRAM0_BASE offsets - general 405 offsets in asm/ibm405.h */
+#define DCRN_SDRAM0_BESR0 0x00 /* Bus Error Syndrome Reg 0 */
+#define DCRN_SDRAM0_BESR1 0x08 /* Bus Error Syndrome Reg 1 */
+#define DCRN_SDRAM0_BEAR 0x10 /* Bus Error Address Reg */
+#define DCRN_SDRAM0_B2CR 0x48 /* Memory Bank 2 Configuration Reg */
+#define DCRN_SDRAM0_B3CR 0x4c /* Memory Bank 3 Configuration Reg */
+#define DCRN_SDRAM0_ECCCFG 0x94 /* ECC Configuration */
+#define DCRN_SDRAM0_ECCESR 0x98 /* ECC Error Status */
+
#include <asm/ibm405.h>
#endif /* __ASM_IBM405GPR_H__ */
diff --git a/include/asm-ppc/ibm405.h b/include/asm-ppc/ibm405.h
index 4e5be9e..04aaae6 100644
--- a/include/asm-ppc/ibm405.h
+++ b/include/asm-ppc/ibm405.h
@@ -135,6 +135,26 @@
#ifdef DCRN_EBC_BASE
#define DCRN_EBCCFGADR (DCRN_EBC_BASE + 0x0) /* Peripheral Controller
Address */
#define DCRN_EBCCFGDATA (DCRN_EBC_BASE + 0x1) /* Peripheral Controller
Data */
+#define DCRN_EBC_PB0CR 0x00 /* Peripheral Bank 0 Config Reg */
+#define DCRN_EBC_PB1CR 0x01 /* Peripheral Bank 1 Config Reg */
+#define DCRN_EBC_PB2CR 0x02 /* Peripheral Bank 2 Config Reg */
+#define DCRN_EBC_PB3CR 0x03 /* Peripheral Bank 3 Config Reg */
+#define DCRN_EBC_PB4CR 0x04 /* Peripheral Bank 4 Config Reg */
+#define DCRN_EBC_PB5CR 0x05 /* Peripheral Bank 5 Config Reg */
+#define DCRN_EBC_PB6CR 0x06 /* Peripheral Bank 6 Config Reg */
+#define DCRN_EBC_PB7CR 0x07 /* Peripheral Bank 7 Config Reg */
+#define DCRN_EBC_PB0AP 0x10 /* Peripheral Bank 0 Access Parameters */
+#define DCRN_EBC_PB1AP 0x11 /* Peripheral Bank 1 Access parameters */
+#define DCRN_EBC_PB2AP 0x12 /* Peripheral Bank 2 Access Parameters */
+#define DCRN_EBC_PB3AP 0x13 /* Peripheral Bank 3 Access Parameters */
+#define DCRN_EBC_PB4AP 0x14 /* Peripheral Bank 4 Access Parameters */
+#define DCRN_EBC_PB5AP 0x15 /* Peripheral Bank 5 Access Parameters */
+#define DCRN_EBC_PB6AP 0x16 /* Peripheral Bank 6 Access Parameters */
+#define DCRN_EBC_PB7AP 0x17 /* Peripheral Bank 7 Access Parameters */
+#define DCRN_EBC_PBEAR 0x20 /* Peripheral Bus Error Address Reg */
+#define DCRN_EBC_PBESR0 0x21 /* Peripheral Bus Error Status Reg 0 */
+#define DCRN_EBC_PBESR1 0x22 /* Peripheral Bus Error Status Reg 1 */
+#define DCRN_EBC_EPCR 0x23 /* External Peripheral Control Reg */
#endif
#ifdef DCRN_EXIER_BASE
@@ -286,6 +306,13 @@
#ifdef DCRN_SDRAM0_BASE
#define DCRN_SDRAM0_CFGADDR (DCRN_SDRAM0_BASE + 0x0) /* Memory
Controller Address */
#define DCRN_SDRAM0_CFGDATA (DCRN_SDRAM0_BASE + 0x1) /* Memory
Controller Data */
+#define DCRN_SDRAM0_CFG 0x20 /* SDRAM Configuration */
+#define DCRN_SDRAM0_STATUS 0x24 /* SDRAM Controller Status */
+#define DCRN_SDRAM0_RTR 0x30 /* Refresh Timer Reg */
+#define DCRN_SDRAM0_PMIT 0x34 /* Power Management Idle Timer */
+#define DCRN_SDRAM0_B0CR 0x40 /* Memory Bank 0 Configuration Reg */
+#define DCRN_SDRAM0_B1CR 0x44 /* Memory Bank 1 Configuration Reg */
+#define DCRN_SDRAM0_TR 0x80 /* SDRAM Timing Reg */
#endif
#ifdef DCRN_OCM0_BASE
^ permalink raw reply related
* Re: [patch v4 0/4] Cypress c67x00 (EZ-Host/EZ-OTG) support
From: Peter Korsgaard @ 2008-01-21 21:16 UTC (permalink / raw)
To: Grant Likely; +Cc: David Brownell, linuxppc-dev, linux-usb
In-Reply-To: <fa686aa40801211214u31581036m2ea2cf11d82c3f75@mail.gmail.com>
>>>>> "Grant" == Grant Likely <grant.likely@secretlab.ca> writes:
Grant> Personally, I'd prefer to see the v3 series picked up now (as I
Grant> believe all outstanding comments from the list have been addressed)
Grant> and have new patches build on top of that, but that's just my
Grant> preference.
Here's the v3->v4 without gadget diff:
diff --git a/MAINTAINERS b/MAINTAINERS
index 2340cfb..e3b7866 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3832,6 +3832,12 @@ L: linux-usb@vger.kernel.org
S: Maintained
W: http://www.kroah.com/linux-usb/
+USB CYPRESS C67X00 DRIVER
+P: Peter Korsgaard
+M: jacmet@sunsite.dk
+L: linux-usb@vger.kernel.org
+S: Maintained
+
USB DAVICOM DM9601 DRIVER
P: Peter Korsgaard
M: jacmet@sunsite.dk
diff --git a/drivers/usb/c67x00/c67x00-drv.c b/drivers/usb/c67x00/c67x00-drv.c
index 0f0720a..c2ea3b6 100644
--- a/drivers/usb/c67x00/c67x00-drv.c
+++ b/drivers/usb/c67x00/c67x00-drv.c
@@ -1,7 +1,7 @@
/*
* c67x00-drv.c: Cypress C67X00 USB Common infrastructure
*
- * Copyright (C) 2006-2007 Barco N.V.
+ * Copyright (C) 2006-2008 Barco N.V.
* Derived from the Cypress cy7c67200/300 ezusb linux driver and
* based on multiple host controller drivers inside the linux kernel.
*
@@ -30,8 +30,8 @@
* The c67x00 has 2 SIE's (serial interface engine) wich can be configured
* to be host, device or OTG (with some limitations, E.G. only SIE1 can be OTG).
*
- * Depending on the platform configuration, the SIE's are created (setup_sie)
- * and the corresponding subdriver is initialized (c67x00_probe_sie).
+ * Depending on the platform configuration, the SIE's are created and
+ * the corresponding subdriver is initialized (c67x00_probe_sie).
*/
#include <linux/device.h>
@@ -41,36 +41,17 @@
#include <asm/io.h>
#include "c67x00.h"
+#include "c67x00-hcd.h"
-static struct platform_driver c67x00_driver;
-
-static void
-c67x00_setup_sie(struct c67x00_sie *sie, struct c67x00_device *dev, int sie_num)
+static void c67x00_probe_sie(struct c67x00_sie *sie,
+ struct c67x00_device *dev, int sie_num)
{
- static unsigned int id = 0;
-
- /* Fill in needed attributes */
- sie->pdev = platform_device_register_simple("c67x00_sie",
- id++, NULL, 0);
- /* driver used in hub.c: hub_port_init */
- sie->pdev->dev.driver = &c67x00_driver.driver;
spin_lock_init(&sie->lock);
sie->dev = dev;
sie->sie_num = sie_num;
sie->mode = c67x00_sie_config(dev->pdata->sie_config, sie_num);
-}
-static void c67x00_teardown_sie(struct c67x00_sie *sie)
-{
- sie->pdev->dev.driver = NULL;
- platform_device_unregister(sie->pdev);
-}
-
-/* ------------------------------------------------------------------ */
-
-static void c67x00_probe_sie(struct c67x00_sie *sie)
-{
- switch (c67x00_sie_config(sie->dev->pdata->sie_config, sie->sie_num)) {
+ switch (sie->mode) {
case C67X00_SIE_HOST:
c67x00_hcd_probe(sie);
break;
@@ -83,15 +64,14 @@ static void c67x00_probe_sie(struct c67x00_sie *sie)
default:
dev_err(sie_dev(sie),
"Unsupported configuration: 0x%x for SIE %d\n",
- c67x00_sie_config(sie->dev->pdata->sie_config,
- sie->sie_num), sie->sie_num);
+ sie->mode, sie->sie_num);
break;
}
}
static void c67x00_remove_sie(struct c67x00_sie *sie)
{
- switch (c67x00_sie_config(sie->dev->pdata->sie_config, sie->sie_num)) {
+ switch (sie->mode) {
case C67X00_SIE_HOST:
c67x00_hcd_remove(sie);
break;
@@ -101,44 +81,42 @@ static void c67x00_remove_sie(struct c67x00_sie *sie)
}
}
-/* ------------------------------------------------------------------ */
static irqreturn_t c67x00_irq(int irq, void *__dev)
{
struct c67x00_device *c67x00 = __dev;
struct c67x00_sie *sie;
- u16 msg;
+ u16 msg, int_status;
int i, count = 8;
- c67x00->int_status = c67x00_ll_hpi_status(c67x00);
- if (!c67x00->int_status)
+ int_status = c67x00_ll_hpi_status(c67x00);
+ if (!int_status)
return IRQ_NONE;
- while (c67x00->int_status != 0 && (count-- >= 0)) {
- c67x00_ll_irq(c67x00);
+ while (int_status != 0 && (count-- >= 0)) {
+ c67x00_ll_irq(c67x00, int_status);
for (i = 0; i < C67X00_SIES; i++) {
sie = &c67x00->sie[i];
msg = 0;
- spin_lock(&sie->lock);
- if (c67x00->int_status & SIEMSG_FLAG(sie->sie_num))
- msg = c67x00_ll_get_siemsg(c67x00,sie->sie_num);
+ if (int_status & SIEMSG_FLG(i)) {
+ msg = c67x00_ll_get_siemsg(sie);
+ /* clear register to allow next message */
+ c67x00_ll_set_siemsg(sie, 0);
+ }
if (sie->irq)
- sie->irq(sie, msg);
- spin_unlock(&sie->lock);
+ sie->irq(sie, int_status, msg);
}
- c67x00->int_status = c67x00_ll_hpi_status(c67x00);
+ int_status = c67x00_ll_hpi_status(c67x00);
}
- if (c67x00->int_status)
+ if (int_status)
dev_warn(&c67x00->pdev->dev, "Not all interrupts handled! "
- "status = 0x%04x\n", c67x00->int_status);
+ "status = 0x%04x\n", int_status);
return IRQ_HANDLED;
}
-/* ---------------------------------------------------------------------
- * Platform bus binding
- */
+/* ------------------------------------------------------------------------- */
static int __devinit c67x00_drv_probe(struct platform_device *pdev)
{
@@ -176,20 +154,14 @@ static int __devinit c67x00_drv_probe(struct platform_device *pdev)
goto map_failed;
}
- spin_lock_init(&c67x00->hw_lock);
+ spin_lock_init(&c67x00->hpi.lock);
c67x00->hpi.regstep = pdata->hpi_regstep;
c67x00->pdata = pdev->dev.platform_data;
c67x00->pdev = pdev;
- for (i = 0; i < C67X00_SIES; i++)
- c67x00_setup_sie(&c67x00->sie[i], c67x00, i);
-
c67x00_ll_init(c67x00);
c67x00_ll_hpi_reg_init(c67x00);
- dev_info(&pdev->dev, "USB OTG controller, p:0x%x, v:0x%p, irq:%i\n",
- res->start, c67x00->hpi.base, res2->start);
-
ret = request_irq(res2->start, c67x00_irq, 0, pdev->name, c67x00);
if (ret) {
dev_err(&pdev->dev, "Cannot claim IRQ\n");
@@ -203,19 +175,19 @@ static int __devinit c67x00_drv_probe(struct platform_device *pdev)
}
for (i = 0; i < C67X00_SIES; i++)
- c67x00_probe_sie(&c67x00->sie[i]);
+ c67x00_probe_sie(&c67x00->sie[i], c67x00, i);
platform_set_drvdata(pdev, c67x00);
return 0;
- reset_failed:
+reset_failed:
free_irq(res2->start, c67x00);
- request_irq_failed:
+request_irq_failed:
iounmap(c67x00->hpi.base);
- map_failed:
+map_failed:
release_mem_region(res->start, res->end - res->start + 1);
- request_mem_failed:
+request_mem_failed:
kfree(c67x00);
return ret;
@@ -227,10 +199,8 @@ static int __devexit c67x00_drv_remove(struct platform_device *pdev)
struct resource *res;
int i;
- for (i = 0; i < C67X00_SIES; i++) {
+ for (i = 0; i < C67X00_SIES; i++)
c67x00_remove_sie(&c67x00->sie[i]);
- c67x00_teardown_sie(&c67x00->sie[i]);
- }
c67x00_ll_release(c67x00);
@@ -250,9 +220,9 @@ static int __devexit c67x00_drv_remove(struct platform_device *pdev)
}
static struct platform_driver c67x00_driver = {
- .probe = c67x00_drv_probe,
- .remove = __devexit_p(c67x00_drv_remove),
- .driver = {
+ .probe = c67x00_drv_probe,
+ .remove = __devexit_p(c67x00_drv_remove),
+ .driver = {
.owner = THIS_MODULE,
.name = "c67x00",
},
@@ -265,12 +235,13 @@ static int __init c67x00_init(void)
return platform_driver_register(&c67x00_driver);
}
-module_init(c67x00_init);
static void __exit c67x00_exit(void)
{
platform_driver_unregister(&c67x00_driver);
}
+
+module_init(c67x00_init);
module_exit(c67x00_exit);
MODULE_AUTHOR("Peter Korsgaard, Jan Veldeman, Grant Likely");
diff --git a/drivers/usb/c67x00/c67x00-hcd.c b/drivers/usb/c67x00/c67x00-hcd.c
index 3d0b77e..4afb291 100644
--- a/drivers/usb/c67x00/c67x00-hcd.c
+++ b/drivers/usb/c67x00/c67x00-hcd.c
@@ -1,7 +1,7 @@
/*
* c67x00-hcd.c: Cypress C67X00 USB Host Controller Driver
*
- * Copyright (C) 2006-2007 Barco N.V.
+ * Copyright (C) 2006-2008 Barco N.V.
* Derived from the Cypress cy7c67200/300 ezusb linux driver and
* based on multiple host controller drivers inside the linux kernel.
*
@@ -66,7 +66,7 @@ static int c67x00_hub_status_data(struct usb_hcd *hcd, char *buf)
int i;
*buf = 0;
- status = c67x00_ll_husb_get_status(sie);
+ status = c67x00_ll_usb_get_status(sie);
for (i = 0; i < C67X00_PORTS; i++)
if (status & PORT_CONNECT_CHANGE(i))
*buf |= (1 << i);
@@ -91,13 +91,14 @@ static int c67x00_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
case GetHubStatus:
*(__le32 *) buf = cpu_to_le32(0);
- len = 4; /* hub power */
+ len = 4; /* hub power */
break;
+
case GetPortStatus:
if (wIndex > C67X00_PORTS)
return -EPIPE;
- status = c67x00_ll_husb_get_status(sie);
+ status = c67x00_ll_usb_get_status(sie);
usb_status = c67x00_ll_get_usb_ctl(sie);
wPortChange = 0;
@@ -120,6 +121,7 @@ static int c67x00_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
*(__le16 *) (buf + 2) = cpu_to_le16(wPortChange);
len = 4;
break;
+
case SetHubFeature: /* We don't implement these */
case ClearHubFeature:
switch (wValue) {
@@ -127,35 +129,41 @@ static int c67x00_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
case C_HUB_LOCAL_POWER:
len = 0;
break;
+
default:
return -EPIPE;
}
break;
+
case SetPortFeature:
if (wIndex > C67X00_PORTS)
return -EPIPE;
switch (wValue) {
case USB_PORT_FEAT_SUSPEND:
- dev_dbg(c67x00_hcd_dev(c67x00),
+ dev_dbg(c67x00_dev(c67x00),
"SetPortFeature %d (SUSPEND)\n", port);
len = 0;
break;
+
case USB_PORT_FEAT_RESET:
c67x00_hub_reset_host_port(sie, port);
len = 0;
break;
+
case USB_PORT_FEAT_POWER:
/* Power always enabled */
len = 0;
break;
+
default:
- dev_dbg(c67x00_hcd_dev(c67x00),
+ dev_dbg(c67x00_dev(c67x00),
"%s: SetPortFeature %d (0x%04x) Error!\n",
__FUNCTION__, port, wValue);
return -EPIPE;
}
break;
+
case ClearPortFeature:
if (wIndex > C67X00_PORTS)
return -EPIPE;
@@ -167,53 +175,64 @@ static int c67x00_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
c67x00_hub_reset_host_port(sie, port);
len = 0;
break;
+
case USB_PORT_FEAT_C_ENABLE:
- dev_dbg(c67x00_hcd_dev(c67x00),
+ dev_dbg(c67x00_dev(c67x00),
"ClearPortFeature (%d): C_ENABLE\n", port);
len = 0;
break;
+
case USB_PORT_FEAT_SUSPEND:
- dev_dbg(c67x00_hcd_dev(c67x00),
+ dev_dbg(c67x00_dev(c67x00),
"ClearPortFeature (%d): SUSPEND\n", port);
len = 0;
break;
+
case USB_PORT_FEAT_C_SUSPEND:
- dev_dbg(c67x00_hcd_dev(c67x00),
+ dev_dbg(c67x00_dev(c67x00),
"ClearPortFeature (%d): C_SUSPEND\n", port);
len = 0;
break;
+
case USB_PORT_FEAT_POWER:
- dev_dbg(c67x00_hcd_dev(c67x00),
+ dev_dbg(c67x00_dev(c67x00),
"ClearPortFeature (%d): POWER\n", port);
return -EPIPE;
+
case USB_PORT_FEAT_C_CONNECTION:
- c67x00_ll_husb_clear_status(sie,
- PORT_CONNECT_CHANGE(port));
+ c67x00_ll_usb_clear_status(sie,
+ PORT_CONNECT_CHANGE(port));
len = 0;
break;
+
case USB_PORT_FEAT_C_OVER_CURRENT:
- dev_dbg(c67x00_hcd_dev(c67x00),
+ dev_dbg(c67x00_dev(c67x00),
"ClearPortFeature (%d): OVER_CURRENT\n", port);
len = 0;
break;
+
case USB_PORT_FEAT_C_RESET:
- dev_dbg(c67x00_hcd_dev(c67x00),
+ dev_dbg(c67x00_dev(c67x00),
"ClearPortFeature (%d): C_RESET\n", port);
len = 0;
break;
+
default:
- dev_dbg(c67x00_hcd_dev(c67x00),
+ dev_dbg(c67x00_dev(c67x00),
"%s: ClearPortFeature %d (0x%04x) Error!\n",
__FUNCTION__, port, wValue);
return -EPIPE;
}
break;
+
case GetHubDescriptor:
len = min_t(unsigned int, sizeof(c67x00_hub_des), wLength);
memcpy(buf, c67x00_hub_des, len);
break;
+
default:
- dev_dbg(c67x00_hcd_dev(c67x00), "%s: unknown\n", __FUNCTION__);
+ dev_dbg(c67x00_dev(c67x00), "%s: unknown\n", __FUNCTION__);
+ return -EPIPE;
}
return 0;
@@ -228,18 +247,17 @@ static int c67x00_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
*
* This function is called from the interrupt handler in c67x00-drv.c
*/
-static void c67x00_hcd_irq(struct c67x00_sie *sie, u16 msg)
+static void c67x00_hcd_irq(struct c67x00_sie *sie, u16 int_status, u16 msg)
{
- struct c67x00_device *c67x00 = sie->dev;
- struct c67x00_hcd *c67x00_hcd = sie->private_data;
- struct usb_hcd *hcd = c67x00_hcd_to_hcd(c67x00_hcd);
+ struct c67x00_hcd *c67x00 = sie->private_data;
+ struct usb_hcd *hcd = c67x00_hcd_to_hcd(c67x00);
/* Handle sie message flags */
if (msg) {
if (msg & HUSB_TDListDone)
- c67x00_sched_kick(c67x00_hcd);
+ c67x00_sched_kick(c67x00);
else
- dev_warn(c67x00_hcd_dev(c67x00_hcd),
+ dev_warn(c67x00_dev(c67x00),
"Unknown SIE msg flag(s): 0x%04x\n", msg);
}
@@ -250,30 +268,31 @@ static void c67x00_hcd_irq(struct c67x00_sie *sie, u16 msg)
return;
/* Handle Start of frame events */
- if (sie->dev->int_status & SOFEOP_FLG(sie->sie_num)) {
- c67x00_ll_husb_clear_status(sie, SOF_EOP_IRQ_FLG);
- c67x00_sched_kick(c67x00_hcd);
+ if (int_status & SOFEOP_FLG(sie->sie_num)) {
+ c67x00_ll_usb_clear_status(sie, SOF_EOP_IRQ_FLG);
+ c67x00_sched_kick(c67x00);
set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
}
}
/**
- * c67x00_hcd_start: Host Controller start hook
+ * c67x00_hcd_start: Host controller start hook
*/
static int c67x00_hcd_start(struct usb_hcd *hcd)
{
hcd->uses_new_polling = 1;
hcd->state = HC_STATE_RUNNING;
hcd->poll_rh = 1;
+
return 0;
}
/**
- * c67x00_hcd_start: Host Controller stop hook
+ * c67x00_hcd_stop: Host controller stop hook
*/
static void c67x00_hcd_stop(struct usb_hcd *hcd)
{
- /* Nothing todo */
+ /* Nothing to do */
}
static int c67x00_hcd_get_frame(struct usb_hcd *hcd)
@@ -281,29 +300,29 @@ static int c67x00_hcd_get_frame(struct usb_hcd *hcd)
struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd);
u16 temp_val;
- dev_dbg(c67x00_hcd_dev(c67x00), "%s\n", __FUNCTION__);
+ dev_dbg(c67x00_dev(c67x00), "%s\n", __FUNCTION__);
temp_val = c67x00_ll_husb_get_frame(c67x00->sie);
temp_val &= HOST_FRAME_MASK;
return temp_val ? (temp_val - 1) : HOST_FRAME_MASK;
}
static struct hc_driver c67x00_hc_driver = {
- .description = "c67x00-hcd",
- .product_desc = "Cypress C67X00 Host Controller",
- .hcd_priv_size = sizeof(struct c67x00_hcd),
- .flags = HCD_USB11 | HCD_MEMORY,
+ .description = "c67x00-hcd",
+ .product_desc = "Cypress C67X00 Host Controller",
+ .hcd_priv_size = sizeof(struct c67x00_hcd),
+ .flags = HCD_USB11 | HCD_MEMORY,
/*
* basic lifecycle operations
*/
- .start = c67x00_hcd_start,
- .stop = c67x00_hcd_stop,
+ .start = c67x00_hcd_start,
+ .stop = c67x00_hcd_stop,
/*
* managing i/o requests and associated device resources
*/
- .urb_enqueue = c67x00_urb_enqueue,
- .urb_dequeue = c67x00_urb_dequeue,
+ .urb_enqueue = c67x00_urb_enqueue,
+ .urb_dequeue = c67x00_urb_dequeue,
.endpoint_disable = c67x00_endpoint_disable,
/*
@@ -315,7 +334,7 @@ static struct hc_driver c67x00_hc_driver = {
* root hub support
*/
.hub_status_data = c67x00_hub_status_data,
- .hub_control = c67x00_hub_control,
+ .hub_control = c67x00_hub_control,
};
/* ---------------------------------------------------------------------
@@ -324,9 +343,10 @@ static struct hc_driver c67x00_hc_driver = {
int c67x00_hcd_probe(struct c67x00_sie *sie)
{
- int retval;
- struct usb_hcd *hcd = NULL;
struct c67x00_hcd *c67x00;
+ struct usb_hcd *hcd;
+ unsigned long flags;
+ int retval;
hcd = usb_create_hcd(&c67x00_hc_driver, sie_dev(sie), "c67x00_sie");
if (!hcd) {
@@ -349,11 +369,6 @@ int c67x00_hcd_probe(struct c67x00_sie *sie)
c67x00->buf_base_addr = CY_HCD_BUF_ADDR + SIE_BUF_OFFSET(sie->sie_num);
c67x00->max_frame_bw = MAX_FRAME_BW_STD;
- spin_lock(&sie->lock);
- sie->private_data = c67x00;
- sie->irq = c67x00_hcd_irq;
- spin_unlock(&sie->lock);
-
c67x00_ll_husb_init_host_port(sie);
init_completion(&c67x00->endpoint_disable);
@@ -368,23 +383,26 @@ int c67x00_hcd_probe(struct c67x00_sie *sie)
goto err2;
}
+ spin_lock_irqsave(&sie->lock, flags);
+ sie->private_data = c67x00;
+ sie->irq = c67x00_hcd_irq;
+ spin_unlock_irqrestore(&sie->lock, flags);
+
return retval;
- err2:
+err2:
c67x00_sched_stop_scheduler(c67x00);
- err1:
+err1:
usb_put_hcd(hcd);
- err0:
+err0:
return retval;
}
/* may be called with controller, bus, and devices active */
void c67x00_hcd_remove(struct c67x00_sie *sie)
{
- struct usb_hcd *hcd;
- struct c67x00_hcd *c67x00;
+ struct c67x00_hcd *c67x00 = sie->private_data;
+ struct usb_hcd *hcd = c67x00_hcd_to_hcd(c67x00);
- c67x00 = sie->private_data;
- hcd = c67x00_hcd_to_hcd(c67x00);
c67x00_sched_stop_scheduler(c67x00);
usb_remove_hcd(hcd);
usb_put_hcd(hcd);
diff --git a/drivers/usb/c67x00/c67x00-hcd.h b/drivers/usb/c67x00/c67x00-hcd.h
index 5b35f01..daee4cd 100644
--- a/drivers/usb/c67x00/c67x00-hcd.h
+++ b/drivers/usb/c67x00/c67x00-hcd.h
@@ -1,7 +1,7 @@
/*
* c67x00-hcd.h: Cypress C67X00 USB HCD
*
- * Copyright (C) 2006-2007 Barco N.V.
+ * Copyright (C) 2006-2008 Barco N.V.
* Derived from the Cypress cy7c67200/300 ezusb linux driver and
* based on multiple host controller drivers inside the linux kernel.
*
@@ -69,15 +69,6 @@
struct c67x00_hcd {
spinlock_t lock;
struct c67x00_sie *sie;
- /* Requirement:
- * All enabled bits in ports must have a position <= MAX_NB_HCD_PORTS
- * (position starts counting from 1!)
- * ( ports & ~((1<<MAX_NB_HCD_PORTS)-1) ) == 0
- *
- * This might be relaxed if needed by using an other indexing scheme
- * for port[] (e.g. use wIndex instead of real port number)
- * */
-#define MAX_NB_HCD_PORTS 2
unsigned int low_speed_ports; /* bitmask of low speed ports */
unsigned int urb_count;
unsigned int urb_iso_count;
@@ -119,6 +110,30 @@ static inline struct usb_hcd *c67x00_hcd_to_hcd(struct c67x00_hcd *c67x00)
return container_of((void *)c67x00, struct usb_hcd, hcd_priv);
}
+/* -------------------------------------------------------------------------- */
+
+#ifdef CONFIG_USB_C67X00_HCD
+/* Functions used by drv */
+int c67x00_hcd_probe(struct c67x00_sie *sie);
+void c67x00_hcd_remove(struct c67x00_sie *sie);
+#else
+static inline int c67x00_hcd_probe(struct c67x00_sie *sie)
+{
+ printk(KERN_ERR "hcd requested but CONFIG_USB_C67X00_HCD "
+ "not enabled!\n");
+ return -ENODEV;
+}
+
+static inline void c67x00_hcd_remove(struct c67x00_sie *sie)
+{
+}
+
+static int usb_disabled(void)
+{
+ return 0;
+}
+#endif /* CONFIG_USB_C67X00_HCD */
+
/* ---------------------------------------------------------------------
* Transfer Descriptor scheduling functions
*/
@@ -132,6 +147,6 @@ void c67x00_sched_kick(struct c67x00_hcd *c67x00);
int c67x00_sched_start_scheduler(struct c67x00_hcd *c67x00);
void c67x00_sched_stop_scheduler(struct c67x00_hcd *c67x00);
-#define c67x00_hcd_dev(x) (c67x00_hcd_to_hcd(x)->self.controller)
+#define c67x00_dev(x) (c67x00_hcd_to_hcd(x)->self.controller)
#endif /* _USB_C67X00_HCD_H */
diff --git a/drivers/usb/c67x00/c67x00-ll-hpi.c b/drivers/usb/c67x00/c67x00-ll-hpi.c
index d6a95d6..ebf58e3 100644
--- a/drivers/usb/c67x00/c67x00-ll-hpi.c
+++ b/drivers/usb/c67x00/c67x00-ll-hpi.c
@@ -1,7 +1,7 @@
/*
* c67x00-ll-hpi.c: Cypress C67X00 USB Low level interface using HPI
*
- * Copyright (C) 2006-2007 Barco N.V.
+ * Copyright (C) 2006-2008 Barco N.V.
* Derived from the Cypress cy7c67200/300 ezusb linux driver and
* based on multiple host controller drivers inside the linux kernel.
*
@@ -23,37 +23,41 @@
#include <asm/io.h>
#include <asm/byteorder.h>
+#include <linux/usb/c67x00.h>
#include "c67x00.h"
+#define COMM_REGS 14
+
+struct lcp_int_data {
+ u16 regs[COMM_REGS];
+};
+
/* -------------------------------------------------------------------------- */
/* Interface definitions */
#define COMM_ACK 0x0FED
#define COMM_NAK 0xDEAD
-#define COMM_CTRL_REG_ADDR 0x01BC
-#define COMM_CTRL_REG_DATA 0x01BE
-#define COMM_CTRL_REG_LOGIC 0x01C0
-#define COMM_WRITE_CTRL_REG 0xCE03
-#define COMM_READ_CTRL_REG 0xCE02
-
#define COMM_RESET 0xFA50
#define COMM_EXEC_INT 0xCE01
#define COMM_INT_NUM 0x01C2
+
/* Registers 0 to COMM_REGS-1 */
#define COMM_R(x) (0x01C4 + 2 * (x))
-#define HUSB_SIE_pCurrentTDPtr(x) ( (x) ? 0x01B2 : 0x01B0 )
-#define HUSB_SIE_pTDListDone_Sem(x) ( (x) ? 0x01B8 : 0x01B6 )
+#define HUSB_SIE_pCurrentTDPtr(x) ((x) ? 0x01B2 : 0x01B0)
+#define HUSB_SIE_pTDListDone_Sem(x) ((x) ? 0x01B8 : 0x01B6)
#define HUSB_pEOT 0x01B4
/* Software interrupts */
/* 114, 115: */
-#define HUSB_SIE_INIT_INT(x) ( (x) ? 0x0073 : 0x0072 )
-#define HUSB_RESET_INT 0x0074 /* 116 */
+#define HUSB_SIE_INIT_INT(x) ((x) ? 0x0073 : 0x0072)
+#define HUSB_RESET_INT 0x0074
#define SUSB_INIT_INT 0x0071
-/* ---------------------------------------------------------------------
+#define SUSB_INIT_INT_LOC (SUSB_INIT_INT * 2)
+
+/* -----------------------------------------------------------------------
* HPI implementation
*
* The c67x00 chip also support control via SPI or HSS serial
@@ -89,9 +93,9 @@ static inline u16 hpi_read_word(struct c67x00_device *dev, u16 reg)
u16 value;
unsigned long flags;
- spin_lock_irqsave(&dev->hw_lock, flags);
+ spin_lock_irqsave(&dev->hpi.lock, flags);
value = hpi_read_word_nolock(dev, reg);
- spin_unlock_irqrestore(&dev->hw_lock, flags);
+ spin_unlock_irqrestore(&dev->hpi.lock, flags);
return value;
}
@@ -107,43 +111,43 @@ static inline void hpi_write_word(struct c67x00_device *dev, u16 reg, u16 value)
{
unsigned long flags;
- spin_lock_irqsave(&dev->hw_lock, flags);
+ spin_lock_irqsave(&dev->hpi.lock, flags);
hpi_write_word_nolock(dev, reg, value);
- spin_unlock_irqrestore(&dev->hw_lock, flags);
+ spin_unlock_irqrestore(&dev->hpi.lock, flags);
}
/*
* Only data is little endian, addr has cpu endianess
*/
static inline void hpi_write_words_le16(struct c67x00_device *dev, u16 addr,
- u16 * data, u16 count)
+ u16 *data, u16 count)
{
unsigned long flags;
int i;
- spin_lock_irqsave(&dev->hw_lock, flags);
+ spin_lock_irqsave(&dev->hpi.lock, flags);
hpi_write_reg(dev, HPI_ADDR, addr);
for (i = 0; i < count; i++)
hpi_write_reg(dev, HPI_DATA, cpu_to_le16(*data++));
- spin_unlock_irqrestore(&dev->hw_lock, flags);
+ spin_unlock_irqrestore(&dev->hpi.lock, flags);
}
/*
* Only data is little endian, addr has cpu endianess
*/
static inline void hpi_read_words_le16(struct c67x00_device *dev, u16 addr,
- u16 * data, u16 count)
+ u16 *data, u16 count)
{
unsigned long flags;
int i;
- spin_lock_irqsave(&dev->hw_lock, flags);
+ spin_lock_irqsave(&dev->hpi.lock, flags);
hpi_write_reg(dev, HPI_ADDR, addr);
for (i = 0; i < count; i++)
*data++ = le16_to_cpu(hpi_read_reg(dev, HPI_DATA));
- spin_unlock_irqrestore(&dev->hw_lock, flags);
+ spin_unlock_irqrestore(&dev->hpi.lock, flags);
}
static inline void hpi_set_bits(struct c67x00_device *dev, u16 reg, u16 mask)
@@ -151,10 +155,10 @@ static inline void hpi_set_bits(struct c67x00_device *dev, u16 reg, u16 mask)
u16 value;
unsigned long flags;
- spin_lock_irqsave(&dev->hw_lock, flags);
+ spin_lock_irqsave(&dev->hpi.lock, flags);
value = hpi_read_word_nolock(dev, reg);
hpi_write_word_nolock(dev, reg, value | mask);
- spin_unlock_irqrestore(&dev->hw_lock, flags);
+ spin_unlock_irqrestore(&dev->hpi.lock, flags);
}
static inline void hpi_clear_bits(struct c67x00_device *dev, u16 reg, u16 mask)
@@ -162,10 +166,10 @@ static inline void hpi_clear_bits(struct c67x00_device *dev, u16 reg, u16 mask)
u16 value;
unsigned long flags;
- spin_lock_irqsave(&dev->hw_lock, flags);
+ spin_lock_irqsave(&dev->hpi.lock, flags);
value = hpi_read_word_nolock(dev, reg);
hpi_write_word_nolock(dev, reg, value & ~mask);
- spin_unlock_irqrestore(&dev->hw_lock, flags);
+ spin_unlock_irqrestore(&dev->hpi.lock, flags);
}
static inline u16 hpi_recv_mbox(struct c67x00_device *dev)
@@ -173,9 +177,9 @@ static inline u16 hpi_recv_mbox(struct c67x00_device *dev)
u16 value;
unsigned long flags;
- spin_lock_irqsave(&dev->hw_lock, flags);
+ spin_lock_irqsave(&dev->hpi.lock, flags);
value = hpi_read_reg(dev, HPI_MAILBOX);
- spin_unlock_irqrestore(&dev->hw_lock, flags);
+ spin_unlock_irqrestore(&dev->hpi.lock, flags);
return value;
}
@@ -184,21 +188,21 @@ static inline u16 hpi_send_mbox(struct c67x00_device *dev, u16 value)
{
unsigned long flags;
- spin_lock_irqsave(&dev->hw_lock, flags);
+ spin_lock_irqsave(&dev->hpi.lock, flags);
hpi_write_reg(dev, HPI_MAILBOX, value);
- spin_unlock_irqrestore(&dev->hw_lock, flags);
+ spin_unlock_irqrestore(&dev->hpi.lock, flags);
return value;
}
-u16 c67x00_ll_hpi_status(struct c67x00_device * dev)
+u16 c67x00_ll_hpi_status(struct c67x00_device *dev)
{
u16 value;
unsigned long flags;
- spin_lock_irqsave(&dev->hw_lock, flags);
+ spin_lock_irqsave(&dev->hpi.lock, flags);
value = hpi_read_reg(dev, HPI_STATUS);
- spin_unlock_irqrestore(&dev->hw_lock, flags);
+ spin_unlock_irqrestore(&dev->hpi.lock, flags);
return value;
}
@@ -211,7 +215,7 @@ void c67x00_ll_hpi_reg_init(struct c67x00_device *dev)
c67x00_ll_hpi_status(dev);
hpi_write_word(dev, HPI_IRQ_ROUTING_REG, 0);
- for (i=0; i<C67X00_SIES; i++) {
+ for (i = 0; i < C67X00_SIES; i++) {
hpi_write_word(dev, SIEMSG_REG(i), 0);
hpi_read_word(dev, SIEMSG_REG(i));
}
@@ -236,69 +240,81 @@ static inline u16 ll_recv_msg(struct c67x00_device *dev)
{
u16 res;
- res = wait_for_completion_timeout(&dev->lcp.msg_received, 5 * HZ);
+ res = wait_for_completion_timeout(&dev->hpi.lcp.msg_received, 5 * HZ);
WARN_ON(!res);
return (res == 0) ? -EIO : 0;
}
/* -------------------------------------------------------------------------- */
+/* General functions */
-u16 c67x00_comm_read_ctrl_reg(struct c67x00_device * dev, u16 addr)
+u16 c67x00_ll_get_siemsg(struct c67x00_sie *sie)
{
- unsigned long msg, res;
- int rc;
+ return hpi_read_word(sie->dev, SIEMSG_REG(sie->sie_num));
+}
- mutex_lock(&dev->lcp.mutex);
- hpi_write_word(dev, COMM_CTRL_REG_ADDR, addr);
- hpi_send_mbox(dev, COMM_READ_CTRL_REG);
- rc = ll_recv_msg(dev);
+void c67x00_ll_set_siemsg(struct c67x00_sie *sie, u16 val)
+{
+ hpi_write_word(sie->dev, SIEMSG_REG(sie->sie_num), val);
+}
- BUG_ON(rc); /* No return path for error code; crash spectacularly */
+u16 c67x00_ll_get_usb_ctl(struct c67x00_sie *sie)
+{
+ return hpi_read_word(sie->dev, USB_CTL_REG(sie->sie_num));
+}
- msg = dev->lcp.last_msg;
- if (msg != COMM_ACK) {
- dev_warn(&dev->pdev->dev, "COMM_READ_CTRL_REG didn't ACK!\n");
- res = 0;
- } else {
- res = hpi_read_word(dev, COMM_CTRL_REG_DATA);
- }
- mutex_unlock(&dev->lcp.mutex);
- return res;
+void c67x00_ll_set_ep_ctrl_reg(struct c67x00_sie *sie, int ep_num, u16 val)
+{
+ hpi_write_word(sie->dev,
+ DEVICE_N_ENDPOINT_N_CTL_REG(sie->sie_num, ep_num), val);
+}
+
+void c67x00_ll_set_ep_packet_size_reg(struct c67x00_sie *sie, int ep_num,
+ u16 val)
+{
+ /* This undocumented register needs to be set to the packet size
+ Normally the BIOS sets this correctly when it is able to parse
+ the configuration descriptor correctly */
+ hpi_write_word(sie->dev,
+ (DEVICE_N_ENDPOINT_N_CTL_REG(sie->sie_num, ep_num)
+ + 0x0A), val);
+}
+
+/**
+ * c67x00_ll_usb_clear_status - clear the USB status bits
+ */
+void c67x00_ll_usb_clear_status(struct c67x00_sie *sie, u16 bits)
+{
+ hpi_write_word(sie->dev, USB_STAT_REG(sie->sie_num), bits);
}
-int c67x00_comm_exec_int(struct c67x00_device *dev, u16 nr,
- struct c67x00_lcp_int_data *data)
+u16 c67x00_ll_usb_get_status(struct c67x00_sie *sie)
+{
+ return hpi_read_word(sie->dev, USB_STAT_REG(sie->sie_num));
+}
+
+/* -------------------------------------------------------------------------- */
+
+static int c67x00_comm_exec_int(struct c67x00_device *dev, u16 nr,
+ struct lcp_int_data *data)
{
int i, rc;
- mutex_lock(&dev->lcp.mutex);
+ mutex_lock(&dev->hpi.lcp.mutex);
hpi_write_word(dev, COMM_INT_NUM, nr);
for (i = 0; i < COMM_REGS; i++)
hpi_write_word(dev, COMM_R(i), data->regs[i]);
hpi_send_mbox(dev, COMM_EXEC_INT);
rc = ll_recv_msg(dev);
- mutex_unlock(&dev->lcp.mutex);
+ mutex_unlock(&dev->hpi.lcp.mutex);
return rc;
}
-/* -------------------------------------------------------------------------- */
-/* General functions */
-
-u16 c67x00_ll_get_siemsg(struct c67x00_device *dev, int sie)
+static u16 c67x00_get_comm_reg(struct c67x00_device *dev, u16 nr)
{
- return hpi_read_word(dev, SIEMSG_REG(sie));
-}
-
-void c67x00_ll_set_siemsg(struct c67x00_device *dev, int sie, u16 val)
-{
- hpi_write_word(dev, SIEMSG_REG(sie), val);
-}
-
-u16 c67x00_ll_get_usb_ctl(struct c67x00_sie *sie)
-{
- return hpi_read_word(sie->dev, USB_CTL_REG(sie->sie_num));
+ return hpi_read_word(dev, COMM_R(nr));
}
/* -------------------------------------------------------------------------- */
@@ -306,15 +322,15 @@ u16 c67x00_ll_get_usb_ctl(struct c67x00_sie *sie)
void c67x00_ll_set_husb_eot(struct c67x00_device *dev, u16 value)
{
- mutex_lock(&dev->lcp.mutex);
+ mutex_lock(&dev->hpi.lcp.mutex);
hpi_write_word(dev, HUSB_pEOT, value);
- mutex_unlock(&dev->lcp.mutex);
+ mutex_unlock(&dev->hpi.lcp.mutex);
}
static inline void c67x00_ll_husb_sie_init(struct c67x00_sie *sie)
{
struct c67x00_device *dev = sie->dev;
- struct c67x00_lcp_int_data data;
+ struct lcp_int_data data;
int rc;
rc = c67x00_comm_exec_int(dev, HUSB_SIE_INIT_INT(sie->sie_num), &data);
@@ -324,7 +340,7 @@ static inline void c67x00_ll_husb_sie_init(struct c67x00_sie *sie)
void c67x00_ll_husb_reset(struct c67x00_sie *sie, int port)
{
struct c67x00_device *dev = sie->dev;
- struct c67x00_lcp_int_data data;
+ struct lcp_int_data data;
int rc;
data.regs[0] = 50; /* Reset USB port for 50ms */
@@ -343,20 +359,7 @@ u16 c67x00_ll_husb_get_current_td(struct c67x00_sie *sie)
return hpi_read_word(sie->dev, HUSB_SIE_pCurrentTDPtr(sie->sie_num));
}
-/**
- * c67x00_ll_husb_clear_status - clear the host status bits
- */
-void c67x00_ll_husb_clear_status(struct c67x00_sie *sie, u16 bits)
-{
- hpi_write_word(sie->dev, HOST_STAT_REG(sie->sie_num), bits);
-}
-
-u16 c67x00_ll_husb_get_status(struct c67x00_sie *sie)
-{
- return hpi_read_word(sie->dev, HOST_STAT_REG(sie->sie_num));
-}
-
-u16 c67x00_ll_husb_get_frame(struct c67x00_sie * sie)
+u16 c67x00_ll_husb_get_frame(struct c67x00_sie *sie)
{
return hpi_read_word(sie->dev, HOST_FRAME_REG(sie->sie_num));
}
@@ -367,7 +370,7 @@ void c67x00_ll_husb_init_host_port(struct c67x00_sie *sie)
hpi_set_bits(sie->dev, USB_CTL_REG(sie->sie_num), HOST_MODE);
c67x00_ll_husb_sie_init(sie);
/* Clear interrupts */
- c67x00_ll_husb_clear_status(sie, HOST_STAT_MASK);
+ c67x00_ll_usb_clear_status(sie, HOST_STAT_MASK);
/* Check */
if (!(hpi_read_word(sie->dev, USB_CTL_REG(sie->sie_num)) & HOST_MODE))
dev_warn(sie_dev(sie),
@@ -377,7 +380,7 @@ void c67x00_ll_husb_init_host_port(struct c67x00_sie *sie)
void c67x00_ll_husb_reset_port(struct c67x00_sie *sie, int port)
{
/* Clear connect change */
- c67x00_ll_husb_clear_status(sie, PORT_CONNECT_CHANGE(port));
+ c67x00_ll_usb_clear_status(sie, PORT_CONNECT_CHANGE(port));
/* Enable interrupts */
hpi_set_bits(sie->dev, HPI_IRQ_ROUTING_REG,
@@ -390,31 +393,14 @@ void c67x00_ll_husb_reset_port(struct c67x00_sie *sie, int port)
}
/* -------------------------------------------------------------------------- */
-void c67x00_ll_susb_init(struct c67x00_sie *sie)
-{
- struct c67x00_device *dev = sie->dev;
- struct c67x00_lcp_int_data data;
- int rc;
-
- data.regs[1] = 1; /* full speed */
- data.regs[2] = sie->sie_num + 1;
- rc = c67x00_comm_exec_int(dev, SUSB_INIT_INT, &data);
- BUG_ON(rc); /* No return path for error code; crash spectacularly */
-
- hpi_clear_bits(dev, HPI_IRQ_ROUTING_REG,
- SOFEOP_TO_HPI_EN(sie->sie_num));
- hpi_set_bits(dev, HPI_IRQ_ROUTING_REG, SOFEOP_TO_CPU_EN(sie->sie_num));
-}
-
-/* -------------------------------------------------------------------------- */
-void c67x00_ll_irq(struct c67x00_device *dev)
+void c67x00_ll_irq(struct c67x00_device *dev, u16 int_status)
{
- if ((dev->int_status & MBX_OUT_FLG) == 0)
+ if ((int_status & MBX_OUT_FLG) == 0)
return;
- dev->lcp.last_msg = hpi_recv_mbox(dev);
- complete(&dev->lcp.msg_received);
+ dev->hpi.lcp.last_msg = hpi_recv_mbox(dev);
+ complete(&dev->hpi.lcp.msg_received);
}
/* -------------------------------------------------------------------------- */
@@ -423,10 +409,10 @@ int c67x00_ll_reset(struct c67x00_device *dev)
{
int rc;
- mutex_lock(&dev->lcp.mutex);
+ mutex_lock(&dev->hpi.lcp.mutex);
hpi_send_mbox(dev, COMM_RESET);
rc = ll_recv_msg(dev);
- mutex_unlock(&dev->lcp.mutex);
+ mutex_unlock(&dev->hpi.lcp.mutex);
return rc;
}
@@ -434,12 +420,14 @@ int c67x00_ll_reset(struct c67x00_device *dev)
/* -------------------------------------------------------------------------- */
/**
- * c67x00_write_mem_le16 - write into c67x00 memory
+ * c67x00_ll_write_mem_le16 - write into c67x00 memory
* Only data is little endian, addr has cpu endianess.
*/
-void c67x00_ll_hpi_write_mem_le16(struct c67x00_device *dev, u16 addr, int len,
- char *data)
+void c67x00_ll_write_mem_le16(struct c67x00_device *dev, u16 addr,
+ void *data, int len)
{
+ u8 *buf = data;
+
/* Sanity check */
if (addr + len > 0xffff) {
dev_err(&dev->pdev->dev,
@@ -451,55 +439,52 @@ void c67x00_ll_hpi_write_mem_le16(struct c67x00_device *dev, u16 addr, int len,
/* unaligned access */
u16 tmp;
tmp = hpi_read_word(dev, addr - 1);
- tmp = (tmp & 0x00ff) | (*data++ << 8);
+ tmp = (tmp & 0x00ff) | (*buf++ << 8);
hpi_write_word(dev, addr - 1, tmp);
addr++;
len--;
}
- hpi_write_words_le16(dev, addr, (u16 *) data, len / 2);
- data += len & ~0x01;
+ hpi_write_words_le16(dev, addr, (u16 *)buf, len / 2);
+ buf += len & ~0x01;
addr += len & ~0x01;
len &= 0x01;
if (len) {
u16 tmp;
tmp = hpi_read_word(dev, addr);
- tmp = (tmp & 0xff00) | (*data++);
+ tmp = (tmp & 0xff00) | *buf;
hpi_write_word(dev, addr, tmp);
- addr++;
- len--;
}
-
}
/**
- * c67x00_ll_hpi_read_mem_le16 - read from c67x00 memory
+ * c67x00_ll_read_mem_le16 - read from c67x00 memory
* Only data is little endian, addr has cpu endianess.
*/
-void c67x00_ll_hpi_read_mem_le16(struct c67x00_device *dev, u16 addr, int len,
- char *data)
+void c67x00_ll_read_mem_le16(struct c67x00_device *dev, u16 addr,
+ void *data, int len)
{
+ u8 *buf = data;
+
if (addr & 0x01) {
/* unaligned access */
u16 tmp;
tmp = hpi_read_word(dev, addr - 1);
- *data++ = (tmp >> 8) & 0x00ff;
+ *buf++ = (tmp >> 8) & 0x00ff;
addr++;
len--;
}
- hpi_read_words_le16(dev, addr, (u16 *) data, len / 2);
- data += len & ~0x01;
+ hpi_read_words_le16(dev, addr, (u16 *)buf, len / 2);
+ buf += len & ~0x01;
addr += len & ~0x01;
len &= 0x01;
if (len) {
u16 tmp;
tmp = hpi_read_word(dev, addr);
- *data++ = tmp & 0x00ff;
- addr++;
- len--;
+ *buf = tmp & 0x00ff;
}
}
@@ -507,8 +492,8 @@ void c67x00_ll_hpi_read_mem_le16(struct c67x00_device *dev, u16 addr, int len,
void c67x00_ll_init(struct c67x00_device *dev)
{
- mutex_init(&dev->lcp.mutex);
- init_completion(&dev->lcp.msg_received);
+ mutex_init(&dev->hpi.lcp.mutex);
+ init_completion(&dev->hpi.lcp.msg_received);
}
void c67x00_ll_release(struct c67x00_device *dev)
diff --git a/drivers/usb/c67x00/c67x00-sched.c b/drivers/usb/c67x00/c67x00-sched.c
index 35d7318..3140d89 100644
--- a/drivers/usb/c67x00/c67x00-sched.c
+++ b/drivers/usb/c67x00/c67x00-sched.c
@@ -1,7 +1,7 @@
/*
* c67x00-sched.c: Cypress C67X00 USB Host Controller Driver - TD scheduling
*
- * Copyright (C) 2006-2007 Barco N.V.
+ * Copyright (C) 2006-2008 Barco N.V.
* Derived from the Cypress cy7c67200/300 ezusb linux driver and
* based on multiple host controller drivers inside the linux kernel.
*
@@ -71,7 +71,7 @@ struct c67x00_td {
/* SW part */
struct list_head td_list;
u16 td_addr;
- char *data;
+ void *data;
struct urb *urb;
unsigned long privdata;
@@ -113,7 +113,7 @@ struct c67x00_urb_priv {
#define TD_STATUSMASK_STALL 0x80
#define TD_ERROR_MASK (TD_STATUSMASK_ERR | TD_STATUSMASK_TMOUT | \
- TD_STATUSMASK_STALL )
+ TD_STATUSMASK_STALL)
#define TD_RETRYCNT_OFFSET 0x08
#define TD_RETRYCNTMASK_ACT_FLG 0x10
@@ -134,8 +134,8 @@ struct c67x00_urb_priv {
#define td_length(td) (td_port_length(td) & TD_PORTLENMASK_DL)
#define td_sequence_ok(td) (!td->status || \
- ( !(td->status & TD_STATUSMASK_SEQ) == \
- !(td->ctrl_reg & SEQ_SEL) ))
+ (!(td->status & TD_STATUSMASK_SEQ) == \
+ !(td->ctrl_reg & SEQ_SEL)))
#define td_acked(td) (!td->status || \
(td->status & TD_STATUSMASK_ACK))
@@ -144,21 +144,14 @@ struct c67x00_urb_priv {
/* -------------------------------------------------------------------------- */
#ifdef DEBUG
-/*
- * These patterns are written into the c67x00 internal memory and the
- * urb->transfer_buffer respectively in order to simplify debugging.
- */
-#define NON_RECEIVED_PATTERN 0xac
-#define UNREAD_PATTERN 0x0c
-/* #define DEBUG_PATTERN */
/**
* dbg_td - Dump the contents of the TD
*/
static void dbg_td(struct c67x00_hcd *c67x00, struct c67x00_td *td, char *msg)
{
- struct device *dev = c67x00_hcd_dev(c67x00);
- int i, len = td_length(td);
+ struct device *dev = c67x00_dev(c67x00);
+
dev_dbg(dev, "### %s at 0x%04x\n", msg, td->td_addr);
dev_dbg(dev, "urb: 0x%p\n", td->urb);
dev_dbg(dev, "endpoint: %4d\n", usb_pipeendpoint(td->pipe));
@@ -173,12 +166,8 @@ static void dbg_td(struct c67x00_hcd *c67x00, struct c67x00_td *td, char *msg)
dev_dbg(dev, "residue: 0x%02x\n", td->residue);
dev_dbg(dev, "next_td_addr: 0x%04x\n", td_next_td_addr(td));
dev_dbg(dev, "data:");
- for (i = 0; i < len; i++) {
- if (!(i % 8))
- printk("\n ");
- printk(" 0x%02x", td->data[i]);
- }
- printk("\n");
+ print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1,
+ td->data, td_length(td), 1);
}
#else /* DEBUG */
@@ -190,8 +179,6 @@ dbg_td(struct c67x00_hcd *c67x00, struct c67x00_td *td, char *msg) { }
/* -------------------------------------------------------------------------- */
/* Helper functions */
-/* -------------------------------------------------------------------------- */
-
static inline u16 c67x00_get_current_frame_number(struct c67x00_hcd *c67x00)
{
u16 temp_val;
@@ -254,12 +241,10 @@ static void c67x00_release_urb(struct c67x00_hcd *c67x00, struct urb *urb)
* * only clear when needed
* * keep a list of tds with earch urbp
*/
- list_for_each_entry(td, &c67x00->td_list, td_list) {
+ list_for_each_entry(td, &c67x00->td_list, td_list)
if (urb == td->urb)
td->urb = NULL;
- }
- /* Discard the urb private data */
urbp = urb->hcpriv;
urb->hcpriv = NULL;
list_del(&urbp->hep_node);
@@ -271,10 +256,8 @@ static void c67x00_release_urb(struct c67x00_hcd *c67x00, struct urb *urb)
static struct c67x00_ep_data *
c67x00_ep_data_alloc(struct c67x00_hcd *c67x00, struct urb *urb)
{
- //struct usb_device *udev = urb->dev;
struct usb_host_endpoint *hep = urb->ep;
struct c67x00_ep_data *ep_data;
- struct c67x00_ep_data *prev;
int type;
c67x00->current_frame = c67x00_get_current_frame_number(c67x00);
@@ -306,11 +289,13 @@ c67x00_ep_data_alloc(struct c67x00_hcd *c67x00, struct urb *urb)
ep_data->next_frame = frame_add(c67x00->current_frame, 1);
/* Add the endpoint data to one of the pipe lists; must be added
- * in order of endpoint address */
+ in order of endpoint address */
type = usb_pipetype(urb->pipe);
if (list_empty(&ep_data->node)) {
list_add(&ep_data->node, &c67x00->list[type]);
} else {
+ struct c67x00_ep_data *prev;
+
list_for_each_entry(prev, &c67x00->list[type], node) {
if (prev->hep->desc.bEndpointAddress >
hep->desc.bEndpointAddress) {
@@ -326,6 +311,7 @@ c67x00_ep_data_alloc(struct c67x00_hcd *c67x00, struct urb *urb)
static int c67x00_ep_data_free(struct usb_host_endpoint *hep)
{
struct c67x00_ep_data *ep_data = hep->hcpriv;
+
if (!ep_data)
return 0;
@@ -348,11 +334,11 @@ void c67x00_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
unsigned long flags;
if (!list_empty(&ep->urb_list))
- dev_warn(c67x00_hcd_dev(c67x00), "error: urb list not empty\n");
+ dev_warn(c67x00_dev(c67x00), "error: urb list not empty\n");
spin_lock_irqsave(&c67x00->lock, flags);
- /* Loop waiting for all transfers in the endpoint queue to complete */
+ /* loop waiting for all transfers in the endpoint queue to complete */
while (c67x00_ep_data_free(ep)) {
/* Drop the lock so we can sleep waiting for the hardware */
spin_unlock_irqrestore(&c67x00->lock, flags);
@@ -384,7 +370,7 @@ int c67x00_urb_enqueue(struct usb_hcd *hcd,
{
int ret;
unsigned long flags;
- struct c67x00_urb_priv *urbp = NULL;
+ struct c67x00_urb_priv *urbp;
struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd);
int port = get_root_port(urb->dev)-1;
@@ -406,11 +392,13 @@ int c67x00_urb_enqueue(struct usb_hcd *hcd,
ret = -ENOMEM;
goto err_urbp;
}
+
INIT_LIST_HEAD(&urbp->hep_node);
urbp->urb = urb;
urbp->port = port;
urbp->ep_data = c67x00_ep_data_alloc(c67x00, urb);
+
if (!urbp->ep_data) {
ret = -ENOMEM;
goto err_epdata;
@@ -443,7 +431,8 @@ int c67x00_urb_enqueue(struct usb_hcd *hcd,
struct urb *last_urb;
last_urb = list_entry(urbp->ep_data->queue.prev,
- struct c67x00_urb_priv, hep_node)->urb;
+ struct c67x00_urb_priv,
+ hep_node)->urb;
urb->start_frame =
frame_add(last_urb->start_frame,
last_urb->number_of_packets *
@@ -456,22 +445,22 @@ int c67x00_urb_enqueue(struct usb_hcd *hcd,
/* Add the URB to the endpoint queue */
list_add_tail(&urbp->hep_node, &urbp->ep_data->queue);
- /* If this is the only urb, kick start the controller */
+ /* If this is the only URB, kick start the controller */
if (!c67x00->urb_count++)
c67x00_ll_hpi_enable_sofeop(c67x00->sie);
c67x00_sched_kick(c67x00);
-
spin_unlock_irqrestore(&c67x00->lock, flags);
+
return 0;
- /* Something went wrong; unwind the allocations */
- err_epdata:
+err_epdata:
kfree(urbp);
- err_urbp:
+err_urbp:
usb_hcd_unlink_urb_from_ep(hcd, urb);
- err_not_linked:
+err_not_linked:
spin_unlock_irqrestore(&c67x00->lock, flags);
+
return ret;
}
@@ -487,6 +476,12 @@ int c67x00_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
goto done;
c67x00_release_urb(c67x00, urb);
+ usb_hcd_unlink_urb_from_ep(hcd, urb);
+ spin_unlock_irqrestore(&c67x00->lock, flags);
+
+ usb_hcd_giveback_urb(hcd, urb, status);
+
+ return 0;
done:
spin_unlock_irqrestore(&c67x00->lock, flags);
@@ -502,6 +497,7 @@ static inline void
c67x00_giveback_urb(struct c67x00_hcd *c67x00, struct urb *urb, int status)
{
struct c67x00_urb_priv *urbp;
+
if (!urb)
return;
@@ -515,8 +511,8 @@ c67x00_giveback_urb(struct c67x00_hcd *c67x00, struct urb *urb, int status)
/* -------------------------------------------------------------------------- */
-static int claim_frame_bw(struct c67x00_hcd *c67x00, struct urb *urb,
- int len, int periodic)
+static int c67x00_claim_frame_bw(struct c67x00_hcd *c67x00, struct urb *urb,
+ int len, int periodic)
{
struct c67x00_urb_priv *urbp = urb->hcpriv;
int bit_time;
@@ -583,10 +579,9 @@ static int claim_frame_bw(struct c67x00_hcd *c67x00, struct urb *urb,
/**
* td_addr and buf_addr must be word aligned
*/
-static int create_td(struct c67x00_hcd *c67x00,
- struct urb *urb,
- char *data,
- int len, int pid, int toggle, unsigned long privdata)
+static int c67x00_create_td(struct c67x00_hcd *c67x00, struct urb *urb,
+ void *data, int len, int pid, int toggle,
+ unsigned long privdata)
{
struct c67x00_td *td;
struct c67x00_urb_priv *urbp = urb->hcpriv;
@@ -594,8 +589,8 @@ static int create_td(struct c67x00_hcd *c67x00,
__u8 cmd = 0;
int tt = 0;
- if (claim_frame_bw(c67x00, urb, len,
- usb_pipeisoc(urb->pipe) || usb_pipeint(urb->pipe)))
+ if (c67x00_claim_frame_bw(c67x00, urb, len, usb_pipeisoc(urb->pipe)
+ || usb_pipeint(urb->pipe)))
return -EMSGSIZE; /* Not really an error, but expected */
td = kzalloc(sizeof(*td), GFP_ATOMIC);
@@ -658,7 +653,7 @@ static int create_td(struct c67x00_hcd *c67x00,
return 0;
}
-static inline void release_td(struct c67x00_td *td)
+static inline void c67x00_release_td(struct c67x00_td *td)
{
list_del_init(&td->td_list);
kfree(td);
@@ -666,7 +661,7 @@ static inline void release_td(struct c67x00_td *td)
/* -------------------------------------------------------------------------- */
-static int add_data_urb(struct c67x00_hcd *c67x00, struct urb *urb)
+static int c67x00_add_data_urb(struct c67x00_hcd *c67x00, struct urb *urb)
{
int remaining;
int toggle;
@@ -695,8 +690,8 @@ static int add_data_urb(struct c67x00_hcd *c67x00, struct urb *urb)
pid = usb_pipeout(urb->pipe) ? USB_PID_OUT : USB_PID_IN;
td_buf = urb->transfer_buffer + urb->transfer_buffer_length -
remaining;
- ret = create_td(c67x00, urb, td_buf, len, pid, toggle,
- DATA_STAGE);
+ ret = c67x00_create_td(c67x00, urb, td_buf, len, pid, toggle,
+ DATA_STAGE);
if (ret)
goto out; /* td wasn't created */
toggle ^= 1;
@@ -704,15 +699,14 @@ static int add_data_urb(struct c67x00_hcd *c67x00, struct urb *urb)
if (usb_pipecontrol(urb->pipe))
break;
}
- out:
+out:
return ret;
}
/**
- *
* return 0 in case more bandwidth is available, else errorcode
*/
-static int add_ctrl_urb(struct c67x00_hcd *c67x00, struct urb *urb)
+static int c67x00_add_ctrl_urb(struct c67x00_hcd *c67x00, struct urb *urb)
{
int ret;
int pid;
@@ -720,9 +714,8 @@ static int add_ctrl_urb(struct c67x00_hcd *c67x00, struct urb *urb)
switch (urb->interval) {
default:
case SETUP_STAGE:
- ret = create_td(c67x00, urb,
- urb->setup_packet,
- 8, USB_PID_SETUP, 0, SETUP_STAGE);
+ ret = c67x00_create_td(c67x00, urb, urb->setup_packet,
+ 8, USB_PID_SETUP, 0, SETUP_STAGE);
if (ret)
return ret;
urb->interval = SETUP_STAGE;
@@ -731,14 +724,15 @@ static int add_ctrl_urb(struct c67x00_hcd *c67x00, struct urb *urb)
break;
case DATA_STAGE:
if (urb->transfer_buffer_length) {
- ret = add_data_urb(c67x00, urb);
+ ret = c67x00_add_data_urb(c67x00, urb);
if (ret)
return ret;
break;
} /* else fallthrough */
case STATUS_STAGE:
pid = !usb_pipeout(urb->pipe) ? USB_PID_OUT : USB_PID_IN;
- ret = create_td(c67x00, urb, NULL, 0, pid, 1, STATUS_STAGE);
+ ret = c67x00_create_td(c67x00, urb, NULL, 0, pid, 1,
+ STATUS_STAGE);
if (ret)
return ret;
break;
@@ -750,19 +744,19 @@ static int add_ctrl_urb(struct c67x00_hcd *c67x00, struct urb *urb)
/*
* return 0 in case more bandwidth is available, else errorcode
*/
-static int add_int_urb(struct c67x00_hcd *c67x00, struct urb *urb)
+static int c67x00_add_int_urb(struct c67x00_hcd *c67x00, struct urb *urb)
{
struct c67x00_urb_priv *urbp = urb->hcpriv;
if (frame_after_eq(c67x00->current_frame, urbp->ep_data->next_frame)) {
urbp->ep_data->next_frame =
frame_add(urbp->ep_data->next_frame, urb->interval);
- return add_data_urb(c67x00, urb);
+ return c67x00_add_data_urb(c67x00, urb);
}
return 0;
}
-static int add_iso_urb(struct c67x00_hcd *c67x00, struct urb *urb)
+static int c67x00_add_iso_urb(struct c67x00_hcd *c67x00, struct urb *urb)
{
struct c67x00_urb_priv *urbp = urb->hcpriv;
@@ -777,7 +771,8 @@ static int add_iso_urb(struct c67x00_hcd *c67x00, struct urb *urb)
len = urb->iso_frame_desc[urbp->cnt].length;
pid = usb_pipeout(urb->pipe) ? USB_PID_OUT : USB_PID_IN;
- ret = create_td(c67x00, urb, td_buf, len, pid, 0, urbp->cnt);
+ ret = c67x00_create_td(c67x00, urb, td_buf, len, pid, 0,
+ urbp->cnt);
if (ret) {
printk(KERN_DEBUG "create failed: %d\n", ret);
urb->iso_frame_desc[urbp->cnt].actual_length = 0;
@@ -806,7 +801,8 @@ static void c67x00_fill_from_list(struct c67x00_hcd *c67x00, int type,
if (!list_empty(&ep_data->queue)) {
/* and add the first urb */
/* isochronous transfer rely on this */
- urb = list_entry(ep_data->queue.next, struct c67x00_urb_priv,
+ urb = list_entry(ep_data->queue.next,
+ struct c67x00_urb_priv,
hep_node)->urb;
add(c67x00, urb);
}
@@ -819,11 +815,11 @@ static void c67x00_fill_frame(struct c67x00_hcd *c67x00)
/* Check if we can proceed */
if (!list_empty(&c67x00->td_list)) {
- dev_warn(c67x00_hcd_dev(c67x00),
+ dev_warn(c67x00_dev(c67x00),
"TD list not empty! This should not happen!\n");
list_for_each_entry_safe(td, ttd, &c67x00->td_list, td_list) {
dbg_td(c67x00, td, "Unprocessed td");
- release_td(td);
+ c67x00_release_td(td);
}
}
@@ -835,10 +831,10 @@ static void c67x00_fill_frame(struct c67x00_hcd *c67x00)
c67x00->next_buf_addr = c67x00->buf_base_addr;
/* Fill the list */
- c67x00_fill_from_list(c67x00, PIPE_ISOCHRONOUS, add_iso_urb);
- c67x00_fill_from_list(c67x00, PIPE_INTERRUPT, add_int_urb);
- c67x00_fill_from_list(c67x00, PIPE_CONTROL, add_ctrl_urb);
- c67x00_fill_from_list(c67x00, PIPE_BULK, add_data_urb);
+ c67x00_fill_from_list(c67x00, PIPE_ISOCHRONOUS, c67x00_add_iso_urb);
+ c67x00_fill_from_list(c67x00, PIPE_INTERRUPT, c67x00_add_int_urb);
+ c67x00_fill_from_list(c67x00, PIPE_CONTROL, c67x00_add_ctrl_urb);
+ c67x00_fill_from_list(c67x00, PIPE_BULK, c67x00_add_data_urb);
}
/* -------------------------------------------------------------------------- */
@@ -849,19 +845,15 @@ static void c67x00_fill_frame(struct c67x00_hcd *c67x00)
static inline void
c67x00_parse_td(struct c67x00_hcd *c67x00, struct c67x00_td *td)
{
- c67x00_ll_hpi_read_mem_le16(c67x00->sie->dev, td->td_addr, CY_TD_SIZE,
- (char *)td);
+ c67x00_ll_read_mem_le16(c67x00->sie->dev,
+ td->td_addr, td, CY_TD_SIZE);
if (usb_pipein(td->pipe) && td_actual_bytes(td))
- c67x00_ll_hpi_read_mem_le16(c67x00->sie->dev,
- td_ly_base_addr(td),
- td_actual_bytes(td), td->data);
+ c67x00_ll_read_mem_le16(c67x00->sie->dev, td_ly_base_addr(td),
+ td->data, td_actual_bytes(td));
}
-/* -------------------------------------------------------------------------- */
-
-static int
-c67x00_td_to_error(struct c67x00_hcd *c67x00, struct c67x00_td *td)
+static int c67x00_td_to_error(struct c67x00_hcd *c67x00, struct c67x00_td *td)
{
if (td->status & TD_STATUSMASK_ERR) {
dbg_td(c67x00, td, "ERROR_FLAG");
@@ -910,8 +902,8 @@ static inline int c67x00_end_of_data(struct c67x00_td *td)
/* Remove all td's from the list which come
* after last_td and are meant for the same pipe.
* This is used when a short packet has occured */
-static inline void
-c67x00_clear_pipe(struct c67x00_hcd *c67x00, struct c67x00_td *last_td)
+static inline void c67x00_clear_pipe(struct c67x00_hcd *c67x00,
+ struct c67x00_td *last_td)
{
struct c67x00_td *td, *tmp;
td = last_td;
@@ -919,7 +911,7 @@ c67x00_clear_pipe(struct c67x00_hcd *c67x00, struct c67x00_td *last_td)
while (td->td_list.next != &c67x00->td_list) {
td = list_entry(td->td_list.next, struct c67x00_td, td_list);
if (td->pipe == last_td->pipe) {
- release_td(td);
+ c67x00_release_td(td);
td = tmp;
}
tmp = td;
@@ -929,7 +921,7 @@ c67x00_clear_pipe(struct c67x00_hcd *c67x00, struct c67x00_td *last_td)
/* -------------------------------------------------------------------------- */
static void c67x00_handle_successful_td(struct c67x00_hcd *c67x00,
- struct c67x00_td *td)
+ struct c67x00_td *td)
{
struct urb *urb = td->urb;
@@ -949,18 +941,21 @@ static void c67x00_handle_successful_td(struct c67x00_hcd *c67x00,
/* Don't count setup_packet with normal data: */
urb->actual_length = 0;
break;
+
case DATA_STAGE:
if (c67x00_end_of_data(td)) {
urb->interval = STATUS_STAGE;
c67x00_clear_pipe(c67x00, td);
}
break;
+
case STATUS_STAGE:
urb->interval = 0;
c67x00_giveback_urb(c67x00, urb, 0);
break;
}
break;
+
case PIPE_INTERRUPT:
case PIPE_BULK:
if (unlikely(c67x00_end_of_data(td))) {
@@ -1023,7 +1018,8 @@ static inline void c67x00_check_td_list(struct c67x00_hcd *c67x00)
* inactive state. This state matches successful transfers so
* we must make sure not to service them. */
if (td->status & TD_ERROR_MASK) {
- c67x00_giveback_urb(c67x00, urb, c67x00_td_to_error(c67x00, td));
+ c67x00_giveback_urb(c67x00, urb,
+ c67x00_td_to_error(c67x00, td));
goto cont;
}
@@ -1045,7 +1041,7 @@ static inline void c67x00_check_td_list(struct c67x00_hcd *c67x00)
clear_endpoint = 0;
c67x00_handle_successful_td(c67x00, td);
- cont:
+ cont:
if (clear_endpoint)
c67x00_clear_pipe(c67x00, td);
if (ack_ok)
@@ -1054,7 +1050,7 @@ static inline void c67x00_check_td_list(struct c67x00_hcd *c67x00)
!(td->ctrl_reg & SEQ_SEL));
/* next in list could have been removed, due to clear_pipe! */
tmp = list_entry(td->td_list.next, typeof(*td), td_list);
- release_td(td);
+ c67x00_release_td(td);
}
}
@@ -1076,12 +1072,11 @@ static void c67x00_send_td(struct c67x00_hcd *c67x00, struct c67x00_td *td)
int len = td_length(td);
if (len && ((td->pid_ep & TD_PIDEPMASK_PID) != TD_PID_IN))
- c67x00_ll_hpi_write_mem_le16(c67x00->sie->dev,
- td_ly_base_addr(td),
- len, td->data);
+ c67x00_ll_write_mem_le16(c67x00->sie->dev, td_ly_base_addr(td),
+ td->data, len);
- c67x00_ll_hpi_write_mem_le16(c67x00->sie->dev, td->td_addr,
- CY_TD_SIZE, (char *)td);
+ c67x00_ll_write_mem_le16(c67x00->sie->dev,
+ td->td_addr, td, CY_TD_SIZE);
}
static void c67x00_send_frame(struct c67x00_hcd *c67x00)
@@ -1089,7 +1084,7 @@ static void c67x00_send_frame(struct c67x00_hcd *c67x00)
struct c67x00_td *td;
if (list_empty(&c67x00->td_list))
- dev_warn(c67x00_hcd_dev(c67x00),
+ dev_warn(c67x00_dev(c67x00),
"%s: td list should not be empty here!\n",
__FUNCTION__);
@@ -1136,15 +1131,11 @@ static void c67x00_do_work(struct c67x00_hcd *c67x00)
}
c67x00_fill_frame(c67x00);
- if (list_empty(&c67x00->td_list))
- /* URBs aren't for this frame */
- goto out;
- else {
+ if (!list_empty(&c67x00->td_list))
/* TD's have been added to the frame */
c67x00_send_frame(c67x00);
- goto out;
- }
- out:
+
+out:
spin_unlock(&c67x00->lock);
}
@@ -1160,24 +1151,23 @@ static void c67x00_sched_done(unsigned long __c67x00)
{
struct c67x00_hcd *c67x00 = (struct c67x00_hcd *)__c67x00;
struct c67x00_urb_priv *urbp, *tmp;
- struct usb_hcd *hcd = c67x00_hcd_to_hcd(c67x00);
struct urb *urb;
- int status;
spin_lock(&c67x00->lock);
/* Loop over the done list and give back all the urbs */
list_for_each_entry_safe(urbp, tmp, &c67x00->done_list, hep_node) {
urb = urbp->urb;
- status = urbp->status;
-
c67x00_release_urb(c67x00, urb);
-
- usb_hcd_unlink_urb_from_ep(hcd, urb);
-
- spin_unlock(&c67x00->lock);
- usb_hcd_giveback_urb(hcd, urb, status);
- spin_lock(&c67x00->lock);
+ if (!usb_hcd_check_unlink_urb(c67x00_hcd_to_hcd(c67x00),
+ urb, urbp->status)) {
+ usb_hcd_unlink_urb_from_ep(c67x00_hcd_to_hcd(c67x00),
+ urb);
+ spin_unlock(&c67x00->lock);
+ usb_hcd_giveback_urb(c67x00_hcd_to_hcd(c67x00), urb,
+ urbp->status);
+ spin_lock(&c67x00->lock);
+ }
}
spin_unlock(&c67x00->lock);
}
diff --git a/drivers/usb/c67x00/c67x00.h b/drivers/usb/c67x00/c67x00.h
index 00a38df..35f81d7 100644
--- a/drivers/usb/c67x00/c67x00.h
+++ b/drivers/usb/c67x00/c67x00.h
@@ -1,7 +1,7 @@
/*
* c67x00.h: Cypress C67X00 USB register and field definitions
*
- * Copyright (C) 2006-2007 Barco N.V.
+ * Copyright (C) 2006-2008 Barco N.V.
* Derived from the Cypress cy7c67200/300 ezusb linux driver and
* based on multiple host controller drivers inside the linux kernel.
*
@@ -24,8 +24,7 @@
#ifndef _USB_C67X00_H
#define _USB_C67X00_H
-#include <linux/interrupt.h>
-#include <linux/list.h>
+#include <linux/spinlock.h>
#include <linux/platform_device.h>
#include <linux/completion.h>
#include <linux/mutex.h>
@@ -34,9 +33,6 @@
* Cypress C67x00 register definitions
*/
-/* Processor control registers */
-/* =========================== */
-
/* Hardware Revision Register */
#define HW_REV_REG 0xC004
@@ -44,12 +40,28 @@
/* ===================== */
/* USB Control Register */
-#define USB_CTL_REG(x) ( (x) ? 0xC0AA : 0xC08A )
+#define USB_CTL_REG(x) ((x) ? 0xC0AA : 0xC08A)
-#define LOW_SPEED_PORT(x) ( (x) ? 0x0800 : 0x0400 )
+#define LOW_SPEED_PORT(x) ((x) ? 0x0800 : 0x0400)
#define HOST_MODE 0x0200
-#define PORT_RES_EN(x) ( (x) ? 0x0100 : 0x0080 )
-#define SOF_EOP_EN(x) ( (x) ? 0x0002 : 0x0001 )
+#define PORT_RES_EN(x) ((x) ? 0x0100 : 0x0080)
+#define SOF_EOP_EN(x) ((x) ? 0x0002 : 0x0001)
+
+/* USB status register - Notice it has different content in hcd/udc mode */
+#define USB_STAT_REG(x) ((x) ? 0xC0B0 : 0xC090)
+
+#define EP0_IRQ_FLG 0x0001
+#define EP1_IRQ_FLG 0x0002
+#define EP2_IRQ_FLG 0x0004
+#define EP3_IRQ_FLG 0x0008
+#define EP4_IRQ_FLG 0x0010
+#define EP5_IRQ_FLG 0x0020
+#define EP6_IRQ_FLG 0x0040
+#define EP7_IRQ_FLG 0x0080
+#define RESET_IRQ_FLG 0x0100
+#define SOF_EOP_IRQ_FLG 0x0200
+#define ID_IRQ_FLG 0x4000
+#define VBUS_IRQ_FLG 0x8000
/* USB Host only registers */
/* ======================= */
@@ -63,50 +75,119 @@
#define ARM_EN 0x0001 /* Arm operation */
/* Host n Interrupt Enable Register */
-#define HOST_IRQ_EN_REG(x) ( (x) ? 0xC0AC : 0xC08C)
+#define HOST_IRQ_EN_REG(x) ((x) ? 0xC0AC : 0xC08C)
#define SOF_EOP_IRQ_EN 0x0200 /* SOF/EOP Interrupt Enable */
+#define SOF_EOP_TMOUT_IRQ_EN 0x0800 /* SOF/EOP Timeout Interrupt Enable */
+#define ID_IRQ_EN 0x4000 /* ID interrupt enable */
+#define VBUS_IRQ_EN 0x8000 /* VBUS interrupt enable */
#define DONE_IRQ_EN 0x0001 /* Done Interrupt Enable */
-/* Host n status register */
-#define HOST_STAT_REG(x) ( (x) ? 0xC0B0 : 0xC090 )
-
+/* USB status register */
#define HOST_STAT_MASK 0x02FD
-#define SOF_EOP_IRQ_FLG 0x0200
-#define PORT_CONNECT_CHANGE(x) ( (x) ? 0x0020 : 0x0010 )
-#define PORT_SE0_STATUS(x) ( (x) ? 0x0008 : 0x0004 )
+#define PORT_CONNECT_CHANGE(x) ((x) ? 0x0020 : 0x0010)
+#define PORT_SE0_STATUS(x) ((x) ? 0x0008 : 0x0004)
/* Host Frame Register */
-#define HOST_FRAME_REG(x) ( (x) ? 0xC0B6 : 0xC096 )
+#define HOST_FRAME_REG(x) ((x) ? 0xC0B6 : 0xC096)
#define HOST_FRAME_MASK 0x07FF
+/* USB Peripheral only registers */
+/* ============================= */
+
+/* Device n Port Sel reg */
+#define DEVICE_N_PORT_SEL(x) ((x) ? 0xC0A4 : 0xC084)
+
+/* Device n Interrupt Enable Register */
+#define DEVICE_N_IRQ_EN_REG(x) ((x) ? 0xC0AC : 0xC08C)
+
+#define DEVICE_N_ENDPOINT_N_CTL_REG(dev, ep) ((dev) \
+ ? (0x0280 + (ep << 4)) \
+ : (0x0200 + (ep << 4)))
+#define DEVICE_N_ENDPOINT_N_STAT_REG(dev, ep) ((dev) \
+ ? (0x0286 + (ep << 4)) \
+ : (0x0206 + (ep << 4)))
+
+#define DEVICE_N_ADDRESS(dev) ((dev) ? (0xC0AE) : (0xC08E))
+
/* HPI registers */
/* ============= */
/* HPI Status register */
-#define SOFEOP_FLG(x) (1 << ( (x) ? 12 : 10 ))
-#define SIEMSG_FLAG(x) (1 << (4 + (x)))
+#define SOFEOP_FLG(x) (1 << ((x) ? 12 : 10))
+#define SIEMSG_FLG(x) (1 << (4 + (x)))
+#define RESET_FLG(x) ((x) ? 0x0200 : 0x0002)
+#define DONE_FLG(x) (1 << (2 + (x)))
+#define RESUME_FLG(x) (1 << (6 + (x)))
#define MBX_OUT_FLG 0x0001 /* Message out available */
+#define MBX_IN_FLG 0x0100
+#define ID_FLG 0x4000
+#define VBUS_FLG 0x8000
/* Interrupt routing register */
#define HPI_IRQ_ROUTING_REG 0x0142
-#define SOFEOP_TO_HPI_EN(x) ( (x) ? 0x2000 : 0x0800 )
-#define SOFEOP_TO_CPU_EN(x) ( (x) ? 0x1000 : 0x0400 )
+#define HPI_SWAP_ENABLE(x) ((x) ? 0x0100 : 0x0001)
+#define RESET_TO_HPI_ENABLE(x) ((x) ? 0x0200 : 0x0002)
+#define DONE_TO_HPI_ENABLE(x) ((x) ? 0x0008 : 0x0004)
+#define RESUME_TO_HPI_ENABLE(x) ((x) ? 0x0080 : 0x0040)
+#define SOFEOP_TO_HPI_EN(x) ((x) ? 0x2000 : 0x0800)
+#define SOFEOP_TO_CPU_EN(x) ((x) ? 0x1000 : 0x0400)
+#define ID_TO_HPI_ENABLE 0x4000
+#define VBUS_TO_HPI_ENABLE 0x8000
/* SIE msg registers */
-#define SIEMSG_REG(x) ( (x) ? 0x0148 : 0x0144 )
+#define SIEMSG_REG(x) ((x) ? 0x0148 : 0x0144)
#define HUSB_TDListDone 0x1000
+#define SUSB_EP0_MSG 0x0001
+#define SUSB_EP1_MSG 0x0002
+#define SUSB_EP2_MSG 0x0004
+#define SUSB_EP3_MSG 0x0008
+#define SUSB_EP4_MSG 0x0010
+#define SUSB_EP5_MSG 0x0020
+#define SUSB_EP6_MSG 0x0040
+#define SUSB_EP7_MSG 0x0080
+#define SUSB_RST_MSG 0x0100
+#define SUSB_SOF_MSG 0x0200
+#define SUSB_CFG_MSG 0x0400
+#define SUSB_SUS_MSG 0x0800
+#define SUSB_ID_MSG 0x4000
+#define SUSB_VBUS_MSG 0x8000
+
+/* BIOS interrupt routines */
+
+#define SUSBx_RECEIVE_INT(x) ((x) ? 97 : 81)
+#define SUSBx_SEND_INT(x) ((x) ? 96 : 80)
+
+#define SUSBx_DEV_DESC_VEC(x) ((x) ? 0x00D4 : 0x00B4)
+#define SUSBx_CONF_DESC_VEC(x) ((x) ? 0x00D6 : 0x00B6)
+#define SUSBx_STRING_DESC_VEC(x) ((x) ? 0x00D8 : 0x00B8)
+
#define CY_HCD_BUF_ADDR 0x500 /* Base address for host */
#define SIE_TD_SIZE 0x200 /* size of the td list */
#define SIE_TD_BUF_SIZE 0x400 /* size of the data buffer */
-#define SIE_TD_OFFSET(host) ( (host) ? (SIE_TD_SIZE+SIE_TD_BUF_SIZE) : 0 )
+#define SIE_TD_OFFSET(host) ((host) ? (SIE_TD_SIZE+SIE_TD_BUF_SIZE) : 0)
#define SIE_BUF_OFFSET(host) (SIE_TD_OFFSET(host) + SIE_TD_SIZE)
+/* Base address of HCD + 2 x TD_SIZE + 2 x TD_BUF_SIZE */
+#define CY_UDC_REQ_HEADER_BASE 0x1100
+/* 8- byte request headers for IN/OUT transfers */
+#define CY_UDC_REQ_HEADER_SIZE 8
+
+#define CY_UDC_REQ_HEADER_ADDR(ep_num) (CY_UDC_REQ_HEADER_BASE + \
+ ((ep_num) * CY_UDC_REQ_HEADER_SIZE))
+#define CY_UDC_DESC_BASE_ADDRESS (CY_UDC_REQ_HEADER_ADDR(8))
+
+#define CY_UDC_BIOS_REPLACE_BASE 0x1800
+#define CY_UDC_REQ_BUFFER_BASE 0x2000
+#define CY_UDC_REQ_BUFFER_SIZE 0x0400
+#define CY_UDC_REQ_BUFFER_ADDR(ep_num) (CY_UDC_REQ_BUFFER_BASE + \
+ ((ep_num) * CY_UDC_REQ_BUFFER_SIZE))
+
/* ---------------------------------------------------------------------
* Driver data structures
*/
@@ -114,44 +195,19 @@
struct c67x00_device;
/**
- * struct c67x00_lcp
- */
-struct c67x00_lcp {
- /* Internal use only */
- struct mutex mutex;
- struct completion msg_received;
- u16 last_msg;
-};
-
-/**
- * struct c67x00_lcp_data
- */
-#define COMM_REGS 14
-struct c67x00_lcp_int_data {
- u16 regs[COMM_REGS];
-};
-
-/**
- * struct c67x00_sie - Common data associated with an SIE
+ * struct c67x00_sie - Common data associated with a SIE
* @lock: lock to protect this struct
* @private_data: subdriver dependent data
- * @pdev: platform device associated with this SIE, created in c67x00-drv.c
- * @irq: subdriver depenent irq handler, set NULL when not used
- * @msg_received: called when an SIEmsg has been received
+ * @irq: subdriver dependent irq handler, set NULL when not used
* @dev: link to common driver structure
* @sie_num: SIE number on chip, starting from 0
* @mode: SIE mode (host/peripheral/otg/not used)
- *
- * Each SIE has a separate platform_device associated with it, because the
- * hcd needs such a device for itself (TODO: use a struct device instead
- * of a new platform device).
*/
struct c67x00_sie {
/* Entries to be used by the subdrivers */
spinlock_t lock; /* protect this structure */
void *private_data;
- struct platform_device *pdev;
- void (*irq) (struct c67x00_sie * sie, u16 msg);
+ void (*irq) (struct c67x00_sie *sie, u16 int_status, u16 msg);
/* Read only: */
struct c67x00_device *dev;
@@ -159,80 +215,80 @@ struct c67x00_sie {
int mode;
};
-#define sie_dev(s) (&(s)->pdev->dev)
+#define sie_dev(s) (&(s)->dev->pdev->dev)
+
+/**
+ * struct c67x00_lcp
+ */
+struct c67x00_lcp {
+ /* Internal use only */
+ struct mutex mutex;
+ struct completion msg_received;
+ u16 last_msg;
+};
+/*
+ * struct c67x00_hpi
+ */
struct c67x00_hpi {
void __iomem *base;
int regstep;
+ spinlock_t lock;
+ struct c67x00_lcp lcp;
};
#define C67X00_SIES 2
#define C67X00_PORTS 2
/**
- * struct c67x00_device - Common data structure for a c67x00 instance
+ * struct c67x00_device - Common data associated with a c67x00 instance
* @hpi: hpi addresses
* @sie: array of sie's on this chip
+ * @pdev: platform device of instance
* @pdata: configuration provided by the platform
- * @hw_lock: hardware lock
- * @int_status: interrupt status register, only valid in_interrupt()
- * @lcp: link control protocol dependent data
*/
struct c67x00_device {
struct c67x00_hpi hpi;
struct c67x00_sie sie[C67X00_SIES];
struct platform_device *pdev;
struct c67x00_platform_data *pdata;
- spinlock_t hw_lock;
-
- u16 int_status;
- struct c67x00_lcp lcp;
};
/* ---------------------------------------------------------------------
- * HCD setup and teardown hooks; defined here because these are the
- * only routines which are called directly by the core driver.
- */
-extern int c67x00_hcd_probe(struct c67x00_sie *sie);
-extern void c67x00_hcd_remove(struct c67x00_sie *sie);
-
-/* ---------------------------------------------------------------------
* Low level interface functions
*/
-/* Host Port Interface (hpi) functions */
+/* Host Port Interface (HPI) functions */
u16 c67x00_ll_hpi_status(struct c67x00_device *dev);
void c67x00_ll_hpi_reg_init(struct c67x00_device *dev);
void c67x00_ll_hpi_enable_sofeop(struct c67x00_sie *sie);
void c67x00_ll_hpi_disable_sofeop(struct c67x00_sie *sie);
/* General functions */
-u16 c67x00_ll_get_siemsg(struct c67x00_device *dev, int sie);
-void c67x00_ll_set_siemsg(struct c67x00_device *dev, int sie, u16 val);
+u16 c67x00_ll_get_siemsg(struct c67x00_sie *sie);
+void c67x00_ll_set_siemsg(struct c67x00_sie *sie, u16 val);
u16 c67x00_ll_get_usb_ctl(struct c67x00_sie *sie);
+void c67x00_ll_set_ep_ctrl_reg(struct c67x00_sie *sie, int ep_num, u16 val);
+void c67x00_ll_set_ep_packet_size_reg(struct c67x00_sie *sie, int ep_num,
+ u16 val);
+void c67x00_ll_usb_clear_status(struct c67x00_sie *sie, u16 bits);
+u16 c67x00_ll_usb_get_status(struct c67x00_sie *sie);
+void c67x00_ll_write_mem_le16(struct c67x00_device *dev, u16 addr,
+ void *data, int len);
+void c67x00_ll_read_mem_le16(struct c67x00_device *dev, u16 addr,
+ void *data, int len);
/* Host specific functions */
void c67x00_ll_set_husb_eot(struct c67x00_device *dev, u16 value);
void c67x00_ll_husb_reset(struct c67x00_sie *sie, int port);
void c67x00_ll_husb_set_current_td(struct c67x00_sie *sie, u16 addr);
u16 c67x00_ll_husb_get_current_td(struct c67x00_sie *sie);
-void c67x00_ll_husb_clear_status(struct c67x00_sie *sie, u16 bits);
-u16 c67x00_ll_husb_get_status(struct c67x00_sie *sie);
u16 c67x00_ll_husb_get_frame(struct c67x00_sie *sie);
void c67x00_ll_husb_init_host_port(struct c67x00_sie *sie);
void c67x00_ll_husb_reset_port(struct c67x00_sie *sie, int port);
-/* Slave specific functions */
-void c67x00_ll_susb_init(struct c67x00_sie *sie);
-
-/* Read and write to memory */
-void c67x00_ll_hpi_write_mem_le16(struct c67x00_device *dev, u16 addr,
- int len, char *data);
-void c67x00_ll_hpi_read_mem_le16(struct c67x00_device *dev, u16 addr,
- int len, char *data);
-
/* Called by c67x00_irq to handle lcp interrupts */
-void c67x00_ll_irq(struct c67x00_device *dev);
+void c67x00_ll_irq(struct c67x00_device *dev, u16 int_status);
/* Setup and teardown */
void c67x00_ll_init(struct c67x00_device *dev);
diff --git a/include/linux/usb/c67x00.h b/include/linux/usb/c67x00.h
index 80b1a87..3a4b9ce 100644
--- a/include/linux/usb/c67x00.h
+++ b/include/linux/usb/c67x00.h
@@ -25,17 +25,20 @@
/* SIE configuration */
#define C67X00_SIE_UNUSED 0
#define C67X00_SIE_HOST 1
-#define C67X00_SIE_PERIPHERAL 2
+#define C67X00_SIE_PERIPHERAL_A 2 /* peripheral on A port */
+#define C67X00_SIE_PERIPHERAL_B 3 /* peripheral on B port */
#define c67x00_sie_config(config, n) (((config)>>(4*(n)))&0x3)
-#define C67X00_SIE1_UNUSED (C67X00_SIE_UNUSED << 0)
-#define C67X00_SIE1_HOST (C67X00_SIE_HOST << 0)
-#define C67X00_SIE1_PERIPHERAL (C67X00_SIE_PERIPHERAL << 0)
+#define C67X00_SIE1_UNUSED (C67X00_SIE_UNUSED << 0)
+#define C67X00_SIE1_HOST (C67X00_SIE_HOST << 0)
+#define C67X00_SIE1_PERIPHERAL_A (C67X00_SIE_PERIPHERAL_A << 0)
+#define C67X00_SIE1_PERIPHERAL_B (C67X00_SIE_PERIPHERAL_B << 0)
-#define C67X00_SIE2_UNUSED (C67X00_SIE_UNUSED << 4)
-#define C67X00_SIE2_HOST (C67X00_SIE_HOST << 4)
-#define C67X00_SIE2_PERIPHERAL (C67X00_SIE_PERIPHERAL << 4)
+#define C67X00_SIE2_UNUSED (C67X00_SIE_UNUSED << 4)
+#define C67X00_SIE2_HOST (C67X00_SIE_HOST << 4)
+#define C67X00_SIE2_PERIPHERAL_A (C67X00_SIE_PERIPHERAL_A << 4)
+#define C67X00_SIE2_PERIPHERAL_B (C67X00_SIE_PERIPHERAL_B << 4)
struct c67x00_platform_data {
int sie_config; /* SIEs config (C67X00_SIEx_*) */
--
Bye, Peter Korsgaard
^ permalink raw reply related
* Re: [patch v4 0/4] Cypress c67x00 (EZ-Host/EZ-OTG) support
From: Peter Korsgaard @ 2008-01-21 21:13 UTC (permalink / raw)
To: Grant Likely; +Cc: David Brownell, linuxppc-dev, linux-usb
In-Reply-To: <fa686aa40801211214u31581036m2ea2cf11d82c3f75@mail.gmail.com>
>>>>> "Grant" == Grant Likely <grant.likely@secretlab.ca> writes:
Hi,
Grant> My v1, v2 and v3 postings were based on Peter's work from about a year
Grant> ago. I picked up the driver because Peter didn't have any time to
Grant> work on it.
Ack.
Grant> Peter told me last week that this series merges the v3 patches with
Grant> work that he's done recently now that he has some time to do so again.
Grant> However, I don't know what the diff is between v3 and this new
Grant> series. I've also not done a full review, so I cannot make any
Grant> comment at this time.
I would be grateful if you would find a bit of time to skim over it -
I'll post a diff between v3 and v4-without-the-gadget-part in a
moment.
Grant> Personally, I'd prefer to see the v3 series picked up now (as I
Grant> believe all outstanding comments from the list have been addressed)
Grant> and have new patches build on top of that, but that's just my
Grant> preference.
That's understandable; I would ofcause prefer to see v4 selected instead
to get the cleanups and fixes and because the in-progress gadget work
is based on it.
But anyway, that's details - Most of all I would like to see c67x00
support in mainline, one way or another. Most of the work has been
sitting on my hard drive gathering dust since spring 2006.
--
Bye, Peter Korsgaard
^ 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