* Re: Freescale combined ethernet driver
From: Andy Fleming @ 2006-11-09 20:47 UTC (permalink / raw)
To: robin.gilks; +Cc: ppc embedded list
In-Reply-To: <45538F14.5020205@tait.co.nz>
On Nov 9, 2006, at 14:27, Robin Gilks wrote:
>
> Is there a howto that explains in simple terms (i.e. not "do like
> board
> X but I'm not going to tell which bits of the code are crap" but an
> actual interface spec) on how to create this (as far as I can see
> totally undocumented) platform device.
>
> BTW: the code is NOT the documentation - that is the 'how' not the
> 'why'!
Documentation/driver-model/*
^ permalink raw reply
* [PATCH] Optimize qe_brg struct to use an array
From: timur @ 2006-11-09 21:42 UTC (permalink / raw)
To: linuxppc-dev
From: Timur Tabi <timur@freescale.com>
The qe_brg structure manually defined each of the 16 BRG registers, which
made any code that used them cumbersome. This patch replaces the fields
with a single 16-element array.
Signed-off-by: Timur Tabi <timur@freescale.com>
---
arch/powerpc/sysdev/qe_lib/qe.c | 3 +--
include/asm-powerpc/immap_qe.h | 17 +----------------
2 files changed, 2 insertions(+), 18 deletions(-)
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index e422322..e3d71e0 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -174,8 +174,7 @@ void qe_setbrg(u32 brg, u32 rate)
u32 divisor, tempval;
int div16 = 0;
- bp = &qe_immr->brg.brgc1;
- bp += brg;
+ bp = &qe_immr->brg.brgc[brg];
divisor = (get_brg_clk() / rate);
if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
diff --git a/include/asm-powerpc/immap_qe.h b/include/asm-powerpc/immap_qe.h
index ce12f85..9fdd049 100644
--- a/include/asm-powerpc/immap_qe.h
+++ b/include/asm-powerpc/immap_qe.h
@@ -136,22 +136,7 @@ struct qe_timers {
/* BRG */
struct qe_brg {
- __be32 brgc1; /* BRG1 configuration register */
- __be32 brgc2; /* BRG2 configuration register */
- __be32 brgc3; /* BRG3 configuration register */
- __be32 brgc4; /* BRG4 configuration register */
- __be32 brgc5; /* BRG5 configuration register */
- __be32 brgc6; /* BRG6 configuration register */
- __be32 brgc7; /* BRG7 configuration register */
- __be32 brgc8; /* BRG8 configuration register */
- __be32 brgc9; /* BRG9 configuration register */
- __be32 brgc10; /* BRG10 configuration register */
- __be32 brgc11; /* BRG11 configuration register */
- __be32 brgc12; /* BRG12 configuration register */
- __be32 brgc13; /* BRG13 configuration register */
- __be32 brgc14; /* BRG14 configuration register */
- __be32 brgc15; /* BRG15 configuration register */
- __be32 brgc16; /* BRG16 configuration register */
+ __be32 brgc[16]; /* BRG configuration registers */
u8 res0[0x40];
} __attribute__ ((packed));
--
1.4.2.1
^ permalink raw reply related
* Re: [PATCH 2.6.19 2/4] ehca: hcp_phyp.c: correct page mapping in 64k page mode
From: Roland Dreier @ 2006-11-09 21:58 UTC (permalink / raw)
To: Paul Mackerras
Cc: linuxppc-dev, Christoph Raisch, linux-kernel, openib-general
In-Reply-To: <17746.52343.815568.368590@cargo.ozlabs.ibm.com>
> So Roland is correct in his comment about how ioremap is called.
Umm, so is this patch really needed? Where did the patch come from --
is it needed to fix something actually seen, or was it written just
based on some theoretical understanding?
I'm confused...
- R.
^ permalink raw reply
* Re: [PATCH] Optimize qe_brg struct to use an array
From: Kumar Gala @ 2006-11-09 22:32 UTC (permalink / raw)
To: timur; +Cc: linuxppc-dev
In-Reply-To: <11631085643554-git-send-email-timur@freescale.com>
On Nov 9, 2006, at 3:42 PM, timur@freescale.com wrote:
> From: Timur Tabi <timur@freescale.com>
>
> The qe_brg structure manually defined each of the 16 BRG registers,
> which
> made any code that used them cumbersome. This patch replaces the
> fields
> with a single 16-element array.
>
> Signed-off-by: Timur Tabi <timur@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
^ permalink raw reply
* Re: 2.6.19-rc5-mm1 -- ppc64 ohci-hdc.c compile failure
From: Benjamin Herrenschmidt @ 2006-11-09 22:43 UTC (permalink / raw)
To: Andy Whitcroft
Cc: Andrew Morton, Steve Fox, linux-kernel, linuxppc-dev,
Paul Mackerras
In-Reply-To: <4553436D.30601@shadowen.org>
> Seems that the patch below has introduced USB_OHCI_HCD_PPC_OF enabled by
> default. When it and CONFIG_USB_OHCI_HCD_PPC_SOC are enabled which
> occured by default on my config then we end up with two module_init()
> calls, which is illegal.
>
> powerpc-add-of_platform-support-for-ohci-bigendian-hc
>
> I am guessing that we are only meant to be able to have one of these
> defined at a time? I changed the default to n for this and I could at
> least compile the kernel, but I am sure thats not the right fix.
Paul, which patch did you merge ? I rejected the initial one that was
doing 2 drivers/probe routines and Nicolas did a new one.. You may have
taken the wrong one.
Cheers.
Ben.
^ permalink raw reply
* Re: APUS and IOs question
From: Benjamin Herrenschmidt @ 2006-11-09 22:48 UTC (permalink / raw)
To: Simon Richter; +Cc: linuxppc-dev
In-Reply-To: <45533C79.70404@hogyros.de>
> My plan for moving APUS to arch/powerpc involves writing a new
> bootloader (I'm currently hacking binutils to support AmigaOS binaries)
> that builds a proper flattened device tree and calls the kernel, but I'm
> not sure where the kernel virtual mapping that allows the kernel to run
> from a fixed address should be set up -- if in the bootloader, the
> kernel needs to be aware that changing the MMU settings will yield
> interesting results, and if in the kernel, we need some platform
> specific init code to handle that.
Well, the problem is that you basially have to hack the linear mapping,
thus hitting anything that relies on __pa/__va or operating in real mode
indeed.
How do you do for exception vectors ? Since those have to be either at 0
or at ff* ? You stick branches at 0 to jump to where the kernel
resides ?
Ben.
^ permalink raw reply
* Git trees for MPC52xx development
From: Grant Likely @ 2006-11-10 0:13 UTC (permalink / raw)
To: linuxppc-dev list, Nicolas DET, Sylvain Munaut
For those who are interested;
Sylvain and I are both maintaining git trees for the port of mpc52xx
support into arch/powerpc. Once things are more mature, we'll break
up the changes into patches and post them for comment.
You can view the trees at:
http://git.secretlab.ca/
http://gitbits.246tnt.com/
Comments and patches are, of course, welcome.
--
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
^ permalink raw reply
* Re: APUS and IOs question
From: Geert Uytterhoeven @ 2006-11-10 1:39 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Roman Zippel; +Cc: Linux/PPC Development
In-Reply-To: <1163112519.4982.50.camel@localhost.localdomain>
On Fri, 10 Nov 2006, Benjamin Herrenschmidt wrote:
> > My plan for moving APUS to arch/powerpc involves writing a new
> > bootloader (I'm currently hacking binutils to support AmigaOS binaries)
> > that builds a proper flattened device tree and calls the kernel, but I'm
> > not sure where the kernel virtual mapping that allows the kernel to run
> > from a fixed address should be set up -- if in the bootloader, the
> > kernel needs to be aware that changing the MMU settings will yield
> > interesting results, and if in the kernel, we need some platform
> > specific init code to handle that.
>
> Well, the problem is that you basially have to hack the linear mapping,
> thus hitting anything that relies on __pa/__va or operating in real mode
> indeed.
>
> How do you do for exception vectors ? Since those have to be either at 0
> or at ff* ? You stick branches at 0 to jump to where the kernel
> resides ?
IIRC (Roman please correct me if I'm wrong), APUS has them at ff* because the
memory at adress 0 is slower.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: APUS and IOs question
From: Roman Zippel @ 2006-11-10 2:02 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: Linux/PPC Development
In-Reply-To: <Pine.LNX.4.62.0611100238050.28657@pademelon.sonytel.be>
Hi,
On Fri, 10 Nov 2006, Geert Uytterhoeven wrote:
> On Fri, 10 Nov 2006, Benjamin Herrenschmidt wrote:
> > > My plan for moving APUS to arch/powerpc involves writing a new
> > > bootloader (I'm currently hacking binutils to support AmigaOS binaries)
> > > that builds a proper flattened device tree and calls the kernel, but I'm
> > > not sure where the kernel virtual mapping that allows the kernel to run
> > > from a fixed address should be set up -- if in the bootloader, the
> > > kernel needs to be aware that changing the MMU settings will yield
> > > interesting results, and if in the kernel, we need some platform
> > > specific init code to handle that.
> >
> > Well, the problem is that you basially have to hack the linear mapping,
> > thus hitting anything that relies on __pa/__va or operating in real mode
> > indeed.
> >
> > How do you do for exception vectors ? Since those have to be either at 0
> > or at ff* ? You stick branches at 0 to jump to where the kernel
> > resides ?
>
> IIRC (Roman please correct me if I'm wrong), APUS has them at ff* because the
> memory at adress 0 is slower.
Earlier APUS did put the exception vectors at 0, which is slow of course.
The hardware maps part of the local memory to ff, so the exception vectors
are copied there and the transfer handler jump to the mapped location.
bye, Roman
^ permalink raw reply
* Re: minor progress with plb_temac v3.00a, EDK 8.2, & 2.6.18.1
From: rimas @ 2006-11-10 1:55 UTC (permalink / raw)
To: linuxppc-embedded; +Cc: robert corley
i had problems getting the plb_temac driver to work at speeds higher
than 10 mbps until i modified the adapter.c
file to have the correct PHY address for my setup (i am using the
avnet V4FX12 mini-module board and the correct value was 4).
the phy address is usually determined by pullup/pulldowns on certain
pins on the gig phy chip.
this was under 2.4, but i looked at the adapter.c for the 2.6
xilinx_temac driver and it appears to just set this value to 0
look at line 2905 of adapter.c:
/* Assume the PHY to be at address 0x00 */
lp->gmii_addr = 0;
you should change that to reflect the address of your hardware setup.
hope this helps
-rimas
> Pradeep;
>
> I found the process of "uprading" the xapp902 reference design to
> be troublesome when I removed the GMII loop-back; as
> such, I aborted the process and just started from scratch.
>
> I am currently debugging my design and have a functional plb_temac
> but only at 10Mbps speeds.
>
> -R. Corley
>
>
^ permalink raw reply
* [PATCH] powerpc: Fix cell "new style" mapping and add debug
From: Benjamin Herrenschmidt @ 2006-11-10 4:11 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev list
This patch fixes a typo in the "new style" code for mapping SPE
resources, which causes it to try to map 4 times the same resource.
It also adds some pr_debug's that are useful to track down issues with
the firmware when bringinh up new machines.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
The bug is in 2.6.19 so we should merge that asap.
Index: linux-cell/arch/powerpc/platforms/cell/spu_base.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/cell/spu_base.c 2006-10-23 14:41:37.000000000 +1000
+++ linux-cell/arch/powerpc/platforms/cell/spu_base.c 2006-11-10 15:08:40.000000000 +1100
@@ -655,14 +655,19 @@ static int __init spu_map_interrupts(str
for (i=0; i < 3; i++) {
ret = of_irq_map_one(np, i, &oirq);
- if (ret)
+ if (ret) {
+ pr_debug("spu_new: failed to get irq %d\n", i);
goto err;
-
+ }
ret = -EINVAL;
+ pr_debug(" irq %d no 0x%x on %s\n", i, oirq.specifier[0],
+ oirq.controller->full_name);
spu->irqs[i] = irq_create_of_mapping(oirq.controller,
oirq.specifier, oirq.size);
- if (spu->irqs[i] == NO_IRQ)
+ if (spu->irqs[i] == NO_IRQ) {
+ pr_debug("spu_new: failed to map it !\n");
goto err;
+ }
}
return 0;
@@ -681,7 +686,7 @@ static int spu_map_resource(struct devic
struct resource resource = { };
int ret;
- ret = of_address_to_resource(node, 0, &resource);
+ ret = of_address_to_resource(node, nr, &resource);
if (ret)
goto out;
@@ -704,22 +709,42 @@ static int __init spu_map_device(struct
ret = spu_map_resource(node, 0, (void __iomem**)&spu->local_store,
&spu->local_store_phys);
- if (ret)
+ if (ret) {
+ pr_debug("spu_new: failed to map %s resource 0\n",
+ node->full_name);
goto out;
+ }
ret = spu_map_resource(node, 1, (void __iomem**)&spu->problem,
&spu->problem_phys);
- if (ret)
+ if (ret) {
+ pr_debug("spu_new: failed to map %s resource 1\n",
+ node->full_name);
goto out_unmap;
+ }
ret = spu_map_resource(node, 2, (void __iomem**)&spu->priv2,
NULL);
- if (ret)
+ if (ret) {
+ pr_debug("spu_new: failed to map %s resource 2\n",
+ node->full_name);
goto out_unmap;
+ }
if (!firmware_has_feature(FW_FEATURE_LPAR))
ret = spu_map_resource(node, 3, (void __iomem**)&spu->priv1,
NULL);
- if (ret)
+ if (ret) {
+ pr_debug("spu_new: failed to map %s resource 3\n",
+ node->full_name);
goto out_unmap;
+ }
+ pr_debug("spu_new: %s maps:\n", node->full_name);
+ pr_debug(" local store : 0x%016lx -> 0x%p\n",
+ spu->local_store_phys, spu->local_store);
+ pr_debug(" problem state : 0x%016lx -> 0x%p\n",
+ spu->problem_phys, spu->problem);
+ pr_debug(" priv2 : 0x%p\n", spu->priv2);
+ pr_debug(" priv1 : 0x%p\n", spu->priv1);
+
return 0;
out_unmap:
^ permalink raw reply
* [PATCH 0/32] My current serie of patches for 2.6.20 for review
From: Benjamin Herrenschmidt @ 2006-11-10 7:44 UTC (permalink / raw)
To: linuxppc-dev
This should be ready for merge in powerpc tree
This is the whole of my current patch set that I intend to merge
as soon as 2.6.20 merge window opens. I'm posting them here for
review, some of them already had a few iterations on the list by
their own, some didn't show up publically at all yet.
Note that the first 5 ones require specific comments:
* ibmveth: Remove ibmveth "liobn" field
is already queued with Jeff Garzik and will get in 2.6.20
via his merge tree
* Call platform_notify_remove later
is queued in -mm and Andrew sent it to Greg, I expect greg to
merge it in 2.6.20
* Driver core: add notification of bus events
is queued in Greg's tree and scheduled for merge in 2.6.20
* arch provides generic iomap missing accessors
was written by Linus but is not merged yet. He asked me to
resend it when needed, so I'll include it with the other patches
when the merge window opens.
* Add arch specific dev_sysdata to struct device
this is under discussion. I haven't had much comment yet, a few
postitives though. I hope it will make 2.6.20 without problem,
but we'll know in the upcoming couple of days.
* Change ACPI to use dev_sysdata instead of firmware_data
this is a patch that goes along the previous one (though not actually
necessary). It doesn't actually need to go in powerpc.git nor 2.6.20,
I included it in this serie for completeness
This patch set started its life as the support for the new "Axon"
southbridge for cell (which includes such things as MMIO mapped DCR
and 4xx-type devices). However, as things evolved, I ended up doing
a lot more than just the basic support. Among other highlights of
this patch serie are:
- Generic DCR support for both 4xx-type DCRs and MMIO mapped DCR and
MPIC & EMAC changes to work with that
- Souped up of_platform_driver to make it easier to register entire
trees of devices at once, along with PCI host bridge detection support
for 64 bits architectures. Note that some name changes might break
compile of some platforms. I hope to have fixed everything before I
merge but don't forget to tell me if I missed something.
- Completely reworked 64 bits DMA operations
- Possibility to "hook" on PCI MMIO and PCI operations from the platform
code for use by iSeries, Cell and possibly others who have to deal with
weird hypervisor or PCI host bridge erratas. Currently supported only on
64 bits but would be easy to make it work on 32 bits if ever needed.
- Merged 32 and 64 bits io.h. ARCH=powerpc now uses asm-powerpc/io.h
for both. ARCH=ppc still uses the old one in asm-ppc as I really don't
feel like dealing with some of the cruft in there.
- As a consequence of the 2 above, new accessors are available that match
what is done by other architectures: {read,write}{w,l,q}_be for big endian
PCI MMIO accesses, {read,write}s{b,w,l} for MMIO "repeat" operations, and
a significant cleanup of the EEH stuff.
- Cell IOMMU support (mostly written by Jeremy Kerr)
And more ...
^ permalink raw reply
* [PATCH 1/32] ibmveth: Remove ibmveth "liobn" field
From: Benjamin Herrenschmidt @ 2006-11-10 7:44 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1163144683.554182.685908332811.qpush@grosgo>
Remove the now unused "liobn" field in ibmveth which also avoids
having insider knowledge of the iommu table in that driver.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Santiago Leon <santil@us.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
Already in Jeff's queue.
drivers/net/ibmveth.c | 4 ----
drivers/net/ibmveth.h | 1 -
2 files changed, 5 deletions(-)
Index: linux-cell/drivers/net/ibmveth.c
===================================================================
--- linux-cell.orig/drivers/net/ibmveth.c 2006-10-23 14:41:38.000000000 +1000
+++ linux-cell/drivers/net/ibmveth.c 2006-10-25 14:12:05.000000000 +1000
@@ -50,7 +50,6 @@
#include <asm/semaphore.h>
#include <asm/hvcall.h>
#include <asm/atomic.h>
-#include <asm/iommu.h>
#include <asm/vio.h>
#include <asm/uaccess.h>
#include <linux/seq_file.h>
@@ -1000,8 +999,6 @@ static int __devinit ibmveth_probe(struc
adapter->mac_addr = 0;
memcpy(&adapter->mac_addr, mac_addr_p, 6);
- adapter->liobn = dev->iommu_table->it_index;
-
netdev->irq = dev->irq;
netdev->open = ibmveth_open;
netdev->poll = ibmveth_poll;
@@ -1115,7 +1112,6 @@ static int ibmveth_seq_show(struct seq_f
seq_printf(seq, "%s %s\n\n", ibmveth_driver_string, ibmveth_driver_version);
seq_printf(seq, "Unit Address: 0x%x\n", adapter->vdev->unit_address);
- seq_printf(seq, "LIOBN: 0x%lx\n", adapter->liobn);
seq_printf(seq, "Current MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
current_mac[0], current_mac[1], current_mac[2],
current_mac[3], current_mac[4], current_mac[5]);
Index: linux-cell/drivers/net/ibmveth.h
===================================================================
--- linux-cell.orig/drivers/net/ibmveth.h 2006-10-06 13:48:09.000000000 +1000
+++ linux-cell/drivers/net/ibmveth.h 2006-10-25 14:10:39.000000000 +1000
@@ -118,7 +118,6 @@ struct ibmveth_adapter {
struct net_device_stats stats;
unsigned int mcastFilterSize;
unsigned long mac_addr;
- unsigned long liobn;
void * buffer_list_addr;
void * filter_list_addr;
dma_addr_t buffer_list_dma;
^ permalink raw reply
* [PATCH 2/32] Call platform_notify_remove later
From: Benjamin Herrenschmidt @ 2006-11-10 7:44 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1163144683.554182.685908332811.qpush@grosgo>
Move the call to platform_notify_remove() to after the call to
bus_remove_device(), where it belongs. It's bogus to notify the platform
of removal while drivers are still attached to the device and possibly
still operating since the platform might use this callback to tear down
some resources used by the driver (ACPI bits, iommu table, ...)
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: "Brown, Len" <len.brown@intel.com>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---
This patch is already in -mm under the name
call-platform_notify_remove-later.patch
drivers/base/core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
Index: linux-cell/drivers/base/core.c
===================================================================
--- linux-cell.orig/drivers/base/core.c 2006-10-25 13:04:40.000000000 +1000
+++ linux-cell/drivers/base/core.c 2006-10-25 13:04:56.000000000 +1000
@@ -615,12 +615,13 @@ void device_del(struct device * dev)
device_remove_groups(dev);
device_remove_attrs(dev);
+ bus_remove_device(dev);
+
/* Notify the platform of the removal, in case they
* need to do anything...
*/
if (platform_notify_remove)
platform_notify_remove(dev);
- bus_remove_device(dev);
device_pm_remove(dev);
kobject_uevent(&dev->kobj, KOBJ_REMOVE);
kobject_del(&dev->kobj);
^ permalink raw reply
* [PATCH 3/32] Driver core: add notification of bus events
From: Benjamin Herrenschmidt @ 2006-11-10 7:44 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1163144683.554182.685908332811.qpush@grosgo>
I finally did as you suggested and added the notifier to the struct
bus_type itself. There are still problems to be expected is something
attaches to a bus type where the code can hook in different struct
device sub-classes (which is imho a big bogosity but I won't even try to
argue that case now) but it will solve nicely a number of issues I've
had so far.
That also means that clients interested in registering for such
notifications have to do it before devices are added and after bus types
are registered. Fortunately, most bus types that matter for the various
usage scenarios I have in mind are registerd at postcore_initcall time,
which means I have a really nice spot at arch_initcall time to add my
notifiers.
There are 4 notifications provided. Device being added (before hooked to
the bus) and removed (failure of previous case or after being unhooked
from the bus), along with driver being bound to a device and about to be
unbound.
The usage I have for these are:
- The 2 first ones are used to maintain the DMA operations for various
bus types via the new dev_sysdata addition to struct device (added by
a separate patch).
- The other two ones have a completely different usage scenario. I have
cases where multiple devices and their drivers depend on each other. For
example, the IBM EMAC network driver needs to attach to a MAL DMA engine
which is a separate device, and a PHY interface which is also a separate
device. They are all of_platform_device's (well, about to be with my
upcoming patches) but there is no say in what precise order the core
will "probe" them and instanciate the various modules. The solution I
found for that is to have the drivers for emac to use multithread_probe,
and wait for a driver to be bound to the target MAL and PHY control
devices (the device-tree contains reference to the MAL and PHY interface
nodes, which I can then match to of_platform_devices). Right now, I've
been polling, but with that notifier, I can more cleanly wait (with a
timeout of course).
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
This patch is already in Greg KH tree under the name
driver-core-add-notification-of-bus-events.patch
drivers/base/bus.c | 15 +++++++++++++++
drivers/base/core.c | 12 ++++++++++++
drivers/base/dd.c | 10 ++++++++++
include/linux/device.h | 25 ++++++++++++++++++++++++-
4 files changed, 61 insertions(+), 1 deletion(-)
Index: linux-cell/drivers/base/core.c
===================================================================
--- linux-cell.orig/drivers/base/core.c 2006-11-02 13:20:21.000000000 +1100
+++ linux-cell/drivers/base/core.c 2006-11-02 13:20:24.000000000 +1100
@@ -17,6 +17,7 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/kdev_t.h>
+#include <linux/notifier.h>
#include <asm/semaphore.h>
@@ -428,6 +429,11 @@ int device_add(struct device *dev)
if (platform_notify)
platform_notify(dev);
+ /* notify clients of device entry (new way) */
+ if (dev->bus)
+ blocking_notifier_call_chain(&dev->bus->bus_notifier,
+ BUS_NOTIFY_ADD_DEVICE, dev);
+
dev->uevent_attr.attr.name = "uevent";
dev->uevent_attr.attr.mode = S_IWUSR;
if (dev->driver)
@@ -504,6 +510,9 @@ int device_add(struct device *dev)
BusError:
device_pm_remove(dev);
PMError:
+ if (dev->bus)
+ blocking_notifier_call_chain(&dev->bus->bus_notifier,
+ BUS_NOTIFY_DEL_DEVICE, dev);
device_remove_groups(dev);
GroupError:
device_remove_attrs(dev);
@@ -622,6 +631,9 @@ void device_del(struct device * dev)
*/
if (platform_notify_remove)
platform_notify_remove(dev);
+ if (dev->bus)
+ blocking_notifier_call_chain(&dev->bus->bus_notifier,
+ BUS_NOTIFY_DEL_DEVICE, dev);
device_pm_remove(dev);
kobject_uevent(&dev->kobj, KOBJ_REMOVE);
kobject_del(&dev->kobj);
Index: linux-cell/include/linux/device.h
===================================================================
--- linux-cell.orig/include/linux/device.h 2006-10-25 12:50:17.000000000 +1000
+++ linux-cell/include/linux/device.h 2006-11-02 13:20:24.000000000 +1100
@@ -42,6 +42,8 @@ struct bus_type {
struct klist klist_devices;
struct klist klist_drivers;
+ struct blocking_notifier_head bus_notifier;
+
struct bus_attribute * bus_attrs;
struct device_attribute * dev_attrs;
struct driver_attribute * drv_attrs;
@@ -75,6 +77,28 @@ int __must_check bus_for_each_drv(struct
struct device_driver *start, void *data,
int (*fn)(struct device_driver *, void *));
+/* Bus notifiers: Get notified of addition/removal of devices
+ * and binding/unbinding of drivers to devices.
+ * In the long run, it should be a replacement for the platform
+ * notify hooks.
+ */
+struct notifier_block;
+
+extern int register_bus_notifier(struct bus_type *bus,
+ struct notifier_block *nb);
+extern int unregister_bus_notifier(struct bus_type *bus,
+ struct notifier_block *nb);
+
+/* All 4 notifers below get called with the target struct device *
+ * as an argument. Note that those functions are likely to be called
+ * with the device semaphore held in the core, so be careful.
+ */
+#define BUS_NOTIFY_ADD_DEVICE 0x00000001 /* device added */
+#define BUS_NOTIFY_DEL_DEVICE 0x00000002 /* device removed */
+#define BUS_NOTIFY_BOUND_DRIVER 0x00000003 /* driver bound to device */
+#define BUS_NOTIFY_UNBIND_DRIVER 0x00000004 /* driver about to be
+ unbound */
+
/* driverfs interface for exporting bus attributes */
struct bus_attribute {
@@ -427,7 +451,6 @@ extern int (*platform_notify)(struct dev
extern int (*platform_notify_remove)(struct device * dev);
-
/**
* get_device - atomically increment the reference count for the device.
*
Index: linux-cell/drivers/base/bus.c
===================================================================
--- linux-cell.orig/drivers/base/bus.c 2006-10-23 14:41:37.000000000 +1000
+++ linux-cell/drivers/base/bus.c 2006-11-02 13:20:24.000000000 +1100
@@ -724,6 +724,8 @@ int bus_register(struct bus_type * bus)
{
int retval;
+ BLOCKING_INIT_NOTIFIER_HEAD(&bus->bus_notifier);
+
retval = kobject_set_name(&bus->subsys.kset.kobj, "%s", bus->name);
if (retval)
goto out;
@@ -782,6 +784,16 @@ void bus_unregister(struct bus_type * bu
subsystem_unregister(&bus->subsys);
}
+int register_bus_notifier(struct bus_type *bus, struct notifier_block *nb)
+{
+ return blocking_notifier_chain_register(&bus->bus_notifier, nb);
+}
+
+int unregister_bus_notifier(struct bus_type *bus, struct notifier_block *nb)
+{
+ return blocking_notifier_chain_unregister(&bus->bus_notifier, nb);
+}
+
int __init buses_init(void)
{
return subsystem_register(&bus_subsys);
@@ -798,3 +810,6 @@ EXPORT_SYMBOL_GPL(bus_rescan_devices);
EXPORT_SYMBOL_GPL(bus_create_file);
EXPORT_SYMBOL_GPL(bus_remove_file);
+
+EXPORT_SYMBOL_GPL(register_bus_notifier);
+EXPORT_SYMBOL_GPL(unregister_bus_notifier);
Index: linux-cell/drivers/base/dd.c
===================================================================
--- linux-cell.orig/drivers/base/dd.c 2006-10-30 08:00:39.000000000 +1100
+++ linux-cell/drivers/base/dd.c 2006-11-02 13:20:24.000000000 +1100
@@ -52,6 +52,11 @@ int device_bind_driver(struct device *de
pr_debug("bound device '%s' to driver '%s'\n",
dev->bus_id, dev->driver->name);
+
+ if (dev->bus)
+ blocking_notifier_call_chain(&dev->bus->bus_notifier,
+ BUS_NOTIFY_BOUND_DRIVER, dev);
+
klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices);
ret = sysfs_create_link(&dev->driver->kobj, &dev->kobj,
kobject_name(&dev->kobj));
@@ -288,6 +293,11 @@ static void __device_release_driver(stru
sysfs_remove_link(&dev->kobj, "driver");
klist_remove(&dev->knode_driver);
+ if (dev->bus)
+ blocking_notifier_call_chain(&dev->bus->bus_notifier,
+ BUS_NOTIFY_UNBIND_DRIVER,
+ dev);
+
if (dev->bus && dev->bus->remove)
dev->bus->remove(dev);
else if (drv->remove)
^ permalink raw reply
* [PATCH 4/32] arch provides generic iomap missing accessors
From: Benjamin Herrenschmidt @ 2006-11-10 7:44 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1163144683.554182.685908332811.qpush@grosgo>
From: Linus Torvalds <torvalds@osdl.org>
Allow architectures to provide their own implementation of the big endian MMIO
accessors and "repeat" MMIO accessors for use by the generic iomap.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
More-or-less-tested-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
lib/iomap.c | 32 ++++++++++++++++++++++++++++----
1 file changed, 28 insertions(+), 4 deletions(-)
Index: linux-cell/lib/iomap.c
===================================================================
--- linux-cell.orig/lib/iomap.c 2006-11-05 16:19:32.000000000 +1100
+++ linux-cell/lib/iomap.c 2006-11-05 16:19:40.000000000 +1100
@@ -50,6 +50,16 @@
} \
} while (0)
+#ifndef pio_read16be
+#define pio_read16be(port) swab16(inw(port))
+#define pio_read32be(port) swab32(inl(port))
+#endif
+
+#ifndef mmio_read16be
+#define mmio_read16be(addr) be16_to_cpu(__raw_readw(addr))
+#define mmio_read32be(addr) be32_to_cpu(__raw_readl(addr))
+#endif
+
unsigned int fastcall ioread8(void __iomem *addr)
{
IO_COND(addr, return inb(port), return readb(addr));
@@ -60,7 +70,7 @@
}
unsigned int fastcall ioread16be(void __iomem *addr)
{
- IO_COND(addr, return inw(port), return be16_to_cpu(__raw_readw(addr)));
+ IO_COND(addr, return pio_read16be(port), return mmio_read16be(addr));
}
unsigned int fastcall ioread32(void __iomem *addr)
{
@@ -68,7 +78,7 @@
}
unsigned int fastcall ioread32be(void __iomem *addr)
{
- IO_COND(addr, return inl(port), return be32_to_cpu(__raw_readl(addr)));
+ IO_COND(addr, return pio_read32be(port), return mmio_read32be(addr));
}
EXPORT_SYMBOL(ioread8);
EXPORT_SYMBOL(ioread16);
@@ -76,6 +86,16 @@
EXPORT_SYMBOL(ioread32);
EXPORT_SYMBOL(ioread32be);
+#ifndef pio_write16be
+#define pio_write16be(val,port) outw(swab16(val),port)
+#define pio_write32be(val,port) outl(swab32(val),port)
+#endif
+
+#ifndef mmio_write16be
+#define mmio_write16be(val,port) __raw_writew(be16_to_cpu(val),port)
+#define mmio_write32be(val,port) __raw_writel(be32_to_cpu(val),port)
+#endif
+
void fastcall iowrite8(u8 val, void __iomem *addr)
{
IO_COND(addr, outb(val,port), writeb(val, addr));
@@ -86,7 +106,7 @@
}
void fastcall iowrite16be(u16 val, void __iomem *addr)
{
- IO_COND(addr, outw(val,port), __raw_writew(cpu_to_be16(val), addr));
+ IO_COND(addr, pio_write16be(val,port), mmio_write16be(val, addr));
}
void fastcall iowrite32(u32 val, void __iomem *addr)
{
@@ -94,7 +114,7 @@
}
void fastcall iowrite32be(u32 val, void __iomem *addr)
{
- IO_COND(addr, outl(val,port), __raw_writel(cpu_to_be32(val), addr));
+ IO_COND(addr, pio_write32be(val,port), mmio_write32be(val, addr));
}
EXPORT_SYMBOL(iowrite8);
EXPORT_SYMBOL(iowrite16);
@@ -108,6 +128,7 @@
* convert to CPU byte order. We write in "IO byte
* order" (we also don't have IO barriers).
*/
+#ifndef mmio_insb
static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
{
while (--count >= 0) {
@@ -132,7 +153,9 @@
dst++;
}
}
+#endif
+#ifndef mmio_outsb
static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
{
while (--count >= 0) {
@@ -154,6 +177,7 @@
src++;
}
}
+#endif
void fastcall ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
{
^ permalink raw reply
* [PATCH 5/32] Add arch specific dev_sysdata to struct device
From: Benjamin Herrenschmidt @ 2006-11-10 7:44 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1163144683.554182.685908332811.qpush@grosgo>
Adds an arch specific struct dev_sysdata to struct device. This enables
architecture to add specific fields to every device in the system, like
DMA operation pointers, NUMA node ID, firmware specific data, etc...
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
include/asm-alpha/device.h | 14 ++++++++++++++
include/asm-arm/device.h | 14 ++++++++++++++
include/asm-arm26/device.h | 14 ++++++++++++++
include/asm-avr32/device.h | 14 ++++++++++++++
include/asm-cris/device.h | 14 ++++++++++++++
include/asm-frv/device.h | 14 ++++++++++++++
include/asm-generic/device.h | 14 ++++++++++++++
include/asm-h8300/device.h | 14 ++++++++++++++
include/asm-i386/device.h | 14 ++++++++++++++
include/asm-ia64/device.h | 14 ++++++++++++++
include/asm-m32r/device.h | 14 ++++++++++++++
include/asm-m68k/device.h | 14 ++++++++++++++
include/asm-m68knommu/device.h | 14 ++++++++++++++
include/asm-mips/device.h | 14 ++++++++++++++
include/asm-parisc/device.h | 14 ++++++++++++++
include/asm-powerpc/device.h | 14 ++++++++++++++
include/asm-ppc/device.h | 14 ++++++++++++++
include/asm-s390/device.h | 14 ++++++++++++++
include/asm-sh/device.h | 14 ++++++++++++++
include/asm-sh64/device.h | 14 ++++++++++++++
include/asm-sparc/device.h | 14 ++++++++++++++
include/asm-sparc64/device.h | 14 ++++++++++++++
include/asm-um/device.h | 14 ++++++++++++++
include/asm-v850/device.h | 14 ++++++++++++++
include/asm-x86_64/device.h | 14 ++++++++++++++
include/asm-xtensa/device.h | 14 ++++++++++++++
include/linux/device.h | 3 +++
27 files changed, 367 insertions(+)
Index: linux-cell/include/asm-alpha/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-alpha/device.h 2006-11-09 11:20:28.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-arm/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-arm/device.h 2006-11-09 11:20:28.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-arm26/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-arm26/device.h 2006-11-09 11:20:28.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-avr32/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-avr32/device.h 2006-11-09 11:20:28.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-cris/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-cris/device.h 2006-11-09 11:20:28.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-frv/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-frv/device.h 2006-11-09 11:20:28.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-generic/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-generic/device.h 2006-11-09 11:20:28.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-h8300/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-h8300/device.h 2006-11-09 11:20:28.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-i386/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-i386/device.h 2006-11-09 11:20:28.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-ia64/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-ia64/device.h 2006-11-09 11:20:28.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-m32r/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-m32r/device.h 2006-11-09 11:20:28.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-m68k/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-m68k/device.h 2006-11-09 11:20:28.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-m68knommu/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-m68knommu/device.h 2006-11-09 11:20:29.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-mips/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-mips/device.h 2006-11-09 11:20:29.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-parisc/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-parisc/device.h 2006-11-09 11:20:29.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-powerpc/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-powerpc/device.h 2006-11-09 11:20:29.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-ppc/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-ppc/device.h 2006-11-09 11:20:29.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-s390/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-s390/device.h 2006-11-09 11:20:29.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-sh/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-sh/device.h 2006-11-09 11:20:29.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-sh64/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-sh64/device.h 2006-11-09 11:20:29.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-sparc/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-sparc/device.h 2006-11-09 11:20:29.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-sparc64/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-sparc64/device.h 2006-11-09 11:20:29.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-um/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-um/device.h 2006-11-09 11:20:29.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-v850/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-v850/device.h 2006-11-09 11:20:29.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-x86_64/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-x86_64/device.h 2006-11-09 11:20:29.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-xtensa/device.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-xtensa/device.h 2006-11-09 11:20:29.000000000 +1100
@@ -0,0 +1,14 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ *
+ * See Documentation/driver-model/ for more information.
+ */
+#ifndef _ASM_DEVICE_H
+#define _ASM_DEVICE_H
+
+struct dev_sysdata {
+};
+
+#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/linux/device.h
===================================================================
--- linux-cell.orig/include/linux/device.h 2006-11-08 15:09:35.000000000 +1100
+++ linux-cell/include/linux/device.h 2006-11-09 11:17:36.000000000 +1100
@@ -21,6 +21,7 @@
#include <linux/pm.h>
#include <asm/semaphore.h>
#include <asm/atomic.h>
+#include <asm/device.h>
#define DEVICE_NAME_SIZE 50
#define DEVICE_NAME_HALF __stringify(20) /* Less than half to accommodate slop */
@@ -382,6 +383,8 @@ struct device {
struct dma_coherent_mem *dma_mem; /* internal for coherent mem
override */
+ /* arch specific additions */
+ struct dev_sysdata sysdata;
/* class_device migration path */
struct list_head node;
^ permalink raw reply
* [PATCH 6/32] Change ACPI to use dev_sysdata instead of firmware_data
From: Benjamin Herrenschmidt @ 2006-11-10 7:44 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1163144683.554182.685908332811.qpush@grosgo>
This patch changes ACPI to use the new dev_sysdata on i386, x86_64
and amd64 (is there any other arch using ACPI ?) to store it's
acpi_handle.
It also removes the firmware_data field from struct device as this
was the only user.
Only build-tested on x86
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
drivers/acpi/glue.c | 20 +++++++++++---------
include/acpi/acpi_bus.h | 2 +-
include/asm-i386/device.h | 3 +++
include/asm-ia64/device.h | 3 +++
include/asm-x86_64/device.h | 3 +++
include/linux/device.h | 2 --
6 files changed, 21 insertions(+), 12 deletions(-)
Index: linux-cell/drivers/acpi/glue.c
===================================================================
--- linux-cell.orig/drivers/acpi/glue.c 2006-10-06 13:48:00.000000000 +1000
+++ linux-cell/drivers/acpi/glue.c 2006-11-10 16:24:31.000000000 +1100
@@ -267,9 +267,9 @@ static int acpi_bind_one(struct device *
{
acpi_status status;
- if (dev->firmware_data) {
+ if (dev->sysdata.acpi_handle) {
printk(KERN_WARNING PREFIX
- "Drivers changed 'firmware_data' for %s\n", dev->bus_id);
+ "Drivers changed 'acpi_handle' for %s\n", dev->bus_id);
return -EINVAL;
}
get_device(dev);
@@ -278,25 +278,26 @@ static int acpi_bind_one(struct device *
put_device(dev);
return -EINVAL;
}
- dev->firmware_data = handle;
+ dev->sysdata.acpi_handle = handle;
return 0;
}
static int acpi_unbind_one(struct device *dev)
{
- if (!dev->firmware_data)
+ if (!dev->sysdata.acpi_handle)
return 0;
- if (dev == acpi_get_physical_device(dev->firmware_data)) {
+ if (dev == acpi_get_physical_device(dev->sysdata.acpi_handle)) {
/* acpi_get_physical_device increase refcnt by one */
put_device(dev);
- acpi_detach_data(dev->firmware_data, acpi_glue_data_handler);
- dev->firmware_data = NULL;
+ acpi_detach_data(dev->sysdata.acpi_handle,
+ acpi_glue_data_handler);
+ dev->sysdata.acpi_handle = NULL;
/* acpi_bind_one increase refcnt by one */
put_device(dev);
} else {
printk(KERN_ERR PREFIX
- "Oops, 'firmware_data' corrupt for %s\n", dev->bus_id);
+ "Oops, 'acpi_handle' corrupt for %s\n", dev->bus_id);
}
return 0;
}
@@ -328,7 +329,8 @@ static int acpi_platform_notify(struct d
if (!ret) {
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- acpi_get_name(dev->firmware_data, ACPI_FULL_PATHNAME, &buffer);
+ acpi_get_name(dev->sysdata.acpi_handle,
+ ACPI_FULL_PATHNAME, &buffer);
DBG("Device %s -> %s\n", dev->bus_id, (char *)buffer.pointer);
kfree(buffer.pointer);
} else
Index: linux-cell/include/acpi/acpi_bus.h
===================================================================
--- linux-cell.orig/include/acpi/acpi_bus.h 2006-10-06 13:48:20.000000000 +1000
+++ linux-cell/include/acpi/acpi_bus.h 2006-11-10 16:24:31.000000000 +1100
@@ -357,7 +357,7 @@ struct device *acpi_get_physical_device(
/* helper */
acpi_handle acpi_get_child(acpi_handle, acpi_integer);
acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
-#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->firmware_data))
+#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->sysdata.acpi_handle))
#endif /* CONFIG_ACPI */
Index: linux-cell/include/asm-i386/device.h
===================================================================
--- linux-cell.orig/include/asm-i386/device.h 2006-11-10 16:24:31.000000000 +1100
+++ linux-cell/include/asm-i386/device.h 2006-11-10 16:24:31.000000000 +1100
@@ -9,6 +9,9 @@
#define _ASM_DEVICE_H
struct dev_sysdata {
+#ifdef CONFIG_ACPI
+ void *acpi_handle;
+#endif
};
#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/linux/device.h
===================================================================
--- linux-cell.orig/include/linux/device.h 2006-11-10 16:24:31.000000000 +1100
+++ linux-cell/include/linux/device.h 2006-11-10 16:24:31.000000000 +1100
@@ -368,8 +368,6 @@ struct device {
void *driver_data; /* data private to the driver */
void *platform_data; /* Platform specific data, device
core doesn't touch it */
- void *firmware_data; /* Firmware specific data (e.g. ACPI,
- BIOS data),reserved for device core*/
struct dev_pm_info power;
u64 *dma_mask; /* dma mask (if dma'able device) */
Index: linux-cell/include/asm-x86_64/device.h
===================================================================
--- linux-cell.orig/include/asm-x86_64/device.h 2006-11-10 16:24:31.000000000 +1100
+++ linux-cell/include/asm-x86_64/device.h 2006-11-10 16:24:31.000000000 +1100
@@ -9,6 +9,9 @@
#define _ASM_DEVICE_H
struct dev_sysdata {
+#ifdef CONFIG_ACPI
+ void *acpi_handle;
+#endif
};
#endif /* _ASM_DEVICE_H */
Index: linux-cell/include/asm-ia64/device.h
===================================================================
--- linux-cell.orig/include/asm-ia64/device.h 2006-11-10 16:24:31.000000000 +1100
+++ linux-cell/include/asm-ia64/device.h 2006-11-10 17:51:50.000000000 +1100
@@ -9,6 +9,9 @@
#define _ASM_DEVICE_H
struct dev_sysdata {
+#ifdef CONFIG_ACPI
+ void *acpi_handle;
+#endif
};
#endif /* _ASM_DEVICE_H */
^ permalink raw reply
* [PATCH 7/32] powerpc: Make pci_read_irq_line the default
From: Benjamin Herrenschmidt @ 2006-11-10 7:44 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1163144683.554182.685908332811.qpush@grosgo>
This patch reworks the way IRQs are fixed up on PCI for arch powerpc.
It makes pci_read_irq_line() called by default in the PCI code for
devices that are probed, and add an optional per-device fixup in
ppc_md for platforms that really need to correct what they obtain
from pci_read_irq_line().
It also removes ppc_md.irq_bus_setup which was only used by pSeries
and should not be needed anymore.
I've also removed the pSeries s7a workaround as it can't work with
the current interrupt code anyway. I'm trying to get one of these
machines working so I can test a proper fix for that problem.
I also haven't updated the old-style fixup code from 85xx_cds.c
because it's actually buggy :) It assigns pci_dev->irq hard coded
numbers which is no good with the new IRQ mapping code. It should
at least use irq_create_mapping(NULL, hard_coded_number); and possibly
also set_irq_type() to set them as level low.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/kernel/pci_32.c | 10 ++++
arch/powerpc/kernel/pci_64.c | 8 ++-
arch/powerpc/platforms/82xx/mpc82xx_ads.c | 13 ------
arch/powerpc/platforms/83xx/mpc834x_itx.c | 3 -
arch/powerpc/platforms/83xx/mpc834x_sys.c | 3 -
arch/powerpc/platforms/83xx/mpc83xx.h | 1
arch/powerpc/platforms/83xx/pci.c | 9 ----
arch/powerpc/platforms/85xx/mpc85xx_ads.c | 11 -----
arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | 10 ----
arch/powerpc/platforms/cell/setup.c | 9 ----
arch/powerpc/platforms/chrp/chrp.h | 1
arch/powerpc/platforms/chrp/pci.c | 9 ----
arch/powerpc/platforms/chrp/setup.c | 1
arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c | 16 ++-----
arch/powerpc/platforms/maple/maple.h | 2
arch/powerpc/platforms/maple/pci.c | 45 ++++++++--------------
arch/powerpc/platforms/maple/setup.c | 2
arch/powerpc/platforms/pasemi/pasemi.h | 1
arch/powerpc/platforms/pasemi/pci.c | 8 ---
arch/powerpc/platforms/pasemi/setup.c | 1
arch/powerpc/platforms/powermac/pci.c | 35 ++++++-----------
arch/powerpc/platforms/powermac/pmac.h | 2
arch/powerpc/platforms/powermac/setup.c | 2
arch/powerpc/platforms/pseries/pci.c | 35 -----------------
arch/powerpc/platforms/pseries/setup.c | 1
include/asm-powerpc/machdep.h | 2
include/asm-powerpc/ppc-pci.h | 1
27 files changed, 58 insertions(+), 183 deletions(-)
Index: linux-cell/arch/powerpc/kernel/pci_32.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/pci_32.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/kernel/pci_32.c 2006-11-06 15:04:50.000000000 +1100
@@ -12,6 +12,7 @@
#include <linux/errno.h>
#include <linux/bootmem.h>
#include <linux/irq.h>
+#include <linux/list.h>
#include <asm/processor.h>
#include <asm/io.h>
@@ -1338,6 +1339,7 @@ void __init pcibios_fixup_bus(struct pci
struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
unsigned long io_offset;
struct resource *res;
+ struct pci_dev *dev;
int i;
io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
@@ -1390,8 +1392,16 @@ void __init pcibios_fixup_bus(struct pci
}
}
+ /* Platform specific bus fixups */
if (ppc_md.pcibios_fixup_bus)
ppc_md.pcibios_fixup_bus(bus);
+
+ /* Read default IRQs and fixup if necessary */
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ pci_read_irq_line(dev);
+ if (ppc_md.pci_irq_fixup)
+ ppc_md.pci_irq_fixup(dev);
+ }
}
char __init *pcibios_setup(char *str)
Index: linux-cell/arch/powerpc/kernel/pci_64.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/pci_64.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/kernel/pci_64.c 2006-11-06 15:02:21.000000000 +1100
@@ -1223,8 +1223,12 @@ static void __devinit do_bus_setup(struc
list_for_each_entry(dev, &bus->devices, bus_list)
ppc_md.iommu_dev_setup(dev);
- if (ppc_md.irq_bus_setup)
- ppc_md.irq_bus_setup(bus);
+ /* Read default IRQs and fixup if necessary */
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ pci_read_irq_line(dev);
+ if (ppc_md.pci_irq_fixup)
+ ppc_md.pci_irq_fixup(dev);
+ }
}
void __devinit pcibios_fixup_bus(struct pci_bus *bus)
Index: linux-cell/arch/powerpc/platforms/pseries/pci.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/pseries/pci.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/pseries/pci.c 2006-11-06 15:02:21.000000000 +1100
@@ -29,8 +29,6 @@
#include <asm/prom.h>
#include <asm/ppc-pci.h>
-static int __devinitdata s7a_workaround = -1;
-
#if 0
void pcibios_name_device(struct pci_dev *dev)
{
@@ -57,39 +55,6 @@ void pcibios_name_device(struct pci_dev
DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device);
#endif
-static void __devinit check_s7a(void)
-{
- struct device_node *root;
- const char *model;
-
- s7a_workaround = 0;
- root = of_find_node_by_path("/");
- if (root) {
- model = get_property(root, "model", NULL);
- if (model && !strcmp(model, "IBM,7013-S7A"))
- s7a_workaround = 1;
- of_node_put(root);
- }
-}
-
-void __devinit pSeries_irq_bus_setup(struct pci_bus *bus)
-{
- struct pci_dev *dev;
-
- if (s7a_workaround < 0)
- check_s7a();
- list_for_each_entry(dev, &bus->devices, bus_list) {
- pci_read_irq_line(dev);
- if (s7a_workaround) {
- if (dev->irq > 16) {
- dev->irq -= 3;
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
- dev->irq);
- }
- }
- }
-}
-
static void __init pSeries_request_regions(void)
{
if (!isa_io_base)
Index: linux-cell/arch/powerpc/platforms/pseries/setup.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/pseries/setup.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/pseries/setup.c 2006-11-06 15:02:21.000000000 +1100
@@ -553,7 +553,6 @@ define_machine(pseries) {
.log_error = pSeries_log_error,
.pcibios_fixup = pSeries_final_fixup,
.pci_probe_mode = pSeries_pci_probe_mode,
- .irq_bus_setup = pSeries_irq_bus_setup,
.restart = rtas_restart,
.power_off = rtas_power_off,
.halt = rtas_halt,
Index: linux-cell/include/asm-powerpc/machdep.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/machdep.h 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/include/asm-powerpc/machdep.h 2006-11-06 15:02:21.000000000 +1100
@@ -86,7 +86,6 @@ struct machdep_calls {
void (*tce_flush)(struct iommu_table *tbl);
void (*iommu_dev_setup)(struct pci_dev *dev);
void (*iommu_bus_setup)(struct pci_bus *bus);
- void (*irq_bus_setup)(struct pci_bus *bus);
#endif /* CONFIG_PPC64 */
int (*probe)(void);
@@ -106,6 +105,7 @@ struct machdep_calls {
/* Called after scanning the bus, before allocating resources */
void (*pcibios_fixup)(void);
int (*pci_probe_mode)(struct pci_bus *);
+ void (*pci_irq_fixup)(struct pci_dev *dev);
void (*restart)(char *cmd);
void (*power_off)(void);
Index: linux-cell/include/asm-powerpc/ppc-pci.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/ppc-pci.h 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/include/asm-powerpc/ppc-pci.h 2006-11-06 15:02:21.000000000 +1100
@@ -47,7 +47,6 @@ unsigned long get_phb_buid (struct devic
/* From pSeries_pci.h */
extern void pSeries_final_fixup(void);
-extern void pSeries_irq_bus_setup(struct pci_bus *bus);
extern unsigned long pci_probe_only;
Index: linux-cell/arch/powerpc/platforms/cell/setup.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/cell/setup.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/cell/setup.c 2006-11-06 15:02:21.000000000 +1100
@@ -80,14 +80,6 @@ static void cell_progress(char *s, unsig
printk("*** %04x : %s\n", hex, s ? s : "");
}
-static void __init cell_pcibios_fixup(void)
-{
- struct pci_dev *dev = NULL;
-
- for_each_pci_dev(dev)
- pci_read_irq_line(dev);
-}
-
static void __init cell_init_irq(void)
{
iic_init_IRQ();
@@ -180,7 +172,6 @@ define_machine(cell) {
.check_legacy_ioport = cell_check_legacy_ioport,
.progress = cell_progress,
.init_IRQ = cell_init_irq,
- .pcibios_fixup = cell_pcibios_fixup,
#ifdef CONFIG_KEXEC
.machine_kexec = default_machine_kexec,
.machine_kexec_prepare = default_machine_kexec_prepare,
Index: linux-cell/arch/powerpc/platforms/maple/maple.h
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/maple/maple.h 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/maple/maple.h 2006-11-06 15:02:21.000000000 +1100
@@ -8,5 +8,5 @@ extern void maple_get_rtc_time(struct rt
extern unsigned long maple_get_boot_time(void);
extern void maple_calibrate_decr(void);
extern void maple_pci_init(void);
-extern void maple_pcibios_fixup(void);
+extern void maple_pci_irq_fixup(struct pci_dev *dev);
extern int maple_pci_get_legacy_ide_irq(struct pci_dev *dev, int channel);
Index: linux-cell/arch/powerpc/platforms/maple/pci.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/maple/pci.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/maple/pci.c 2006-11-06 15:02:21.000000000 +1100
@@ -502,38 +502,29 @@ static int __init add_bridge(struct devi
}
-void __init maple_pcibios_fixup(void)
+void __devinit maple_pci_irq_fixup(struct pci_dev *dev)
{
- struct pci_dev *dev = NULL;
+ DBG(" -> maple_pci_irq_fixup\n");
- DBG(" -> maple_pcibios_fixup\n");
-
- for_each_pci_dev(dev) {
- /* Fixup IRQ for PCIe host */
- if (u4_pcie != NULL && dev->bus->number == 0 &&
- pci_bus_to_host(dev->bus) == u4_pcie) {
- printk(KERN_DEBUG "Fixup U4 PCIe IRQ\n");
- dev->irq = irq_create_mapping(NULL, 1);
- if (dev->irq != NO_IRQ)
- set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
- continue;
- }
-
- /* Hide AMD8111 IDE interrupt when in legacy mode so
- * the driver calls pci_get_legacy_ide_irq()
- */
- if (dev->vendor == PCI_VENDOR_ID_AMD &&
- dev->device == PCI_DEVICE_ID_AMD_8111_IDE &&
- (dev->class & 5) != 5) {
- dev->irq = NO_IRQ;
- continue;
- }
+ /* Fixup IRQ for PCIe host */
+ if (u4_pcie != NULL && dev->bus->number == 0 &&
+ pci_bus_to_host(dev->bus) == u4_pcie) {
+ printk(KERN_DEBUG "Fixup U4 PCIe IRQ\n");
+ dev->irq = irq_create_mapping(NULL, 1);
+ if (dev->irq != NO_IRQ)
+ set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
+ }
- /* For all others, map the interrupt from the device-tree */
- pci_read_irq_line(dev);
+ /* Hide AMD8111 IDE interrupt when in legacy mode so
+ * the driver calls pci_get_legacy_ide_irq()
+ */
+ if (dev->vendor == PCI_VENDOR_ID_AMD &&
+ dev->device == PCI_DEVICE_ID_AMD_8111_IDE &&
+ (dev->class & 5) != 5) {
+ dev->irq = NO_IRQ;
}
- DBG(" <- maple_pcibios_fixup\n");
+ DBG(" <- maple_pci_irq_fixup\n");
}
static void __init maple_fixup_phb_resources(void)
Index: linux-cell/arch/powerpc/platforms/maple/setup.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/maple/setup.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/maple/setup.c 2006-11-06 15:02:21.000000000 +1100
@@ -312,7 +312,7 @@ define_machine(maple_md) {
.setup_arch = maple_setup_arch,
.init_early = maple_init_early,
.init_IRQ = maple_init_IRQ,
- .pcibios_fixup = maple_pcibios_fixup,
+ .pci_irq_fixup = maple_pci_irq_fixup,
.pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq,
.restart = maple_restart,
.power_off = maple_power_off,
Index: linux-cell/arch/powerpc/platforms/powermac/pci.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/powermac/pci.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/powermac/pci.c 2006-11-06 15:02:21.000000000 +1100
@@ -985,30 +985,23 @@ static int __init add_bridge(struct devi
return 0;
}
-void __init pmac_pcibios_fixup(void)
+void __devinit pmac_pci_irq_fixup(struct pci_dev *dev)
{
- struct pci_dev* dev = NULL;
-
- for_each_pci_dev(dev) {
- /* Read interrupt from the device-tree */
- pci_read_irq_line(dev);
-
#ifdef CONFIG_PPC32
- /* Fixup interrupt for the modem/ethernet combo controller.
- * on machines with a second ohare chip.
- * The number in the device tree (27) is bogus (correct for
- * the ethernet-only board but not the combo ethernet/modem
- * board). The real interrupt is 28 on the second controller
- * -> 28+32 = 60.
- */
- if (has_second_ohare &&
- dev->vendor == PCI_VENDOR_ID_DEC &&
- dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS) {
- dev->irq = irq_create_mapping(NULL, 60);
- set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
- }
-#endif /* CONFIG_PPC32 */
+ /* Fixup interrupt for the modem/ethernet combo controller.
+ * on machines with a second ohare chip.
+ * The number in the device tree (27) is bogus (correct for
+ * the ethernet-only board but not the combo ethernet/modem
+ * board). The real interrupt is 28 on the second controller
+ * -> 28+32 = 60.
+ */
+ if (has_second_ohare &&
+ dev->vendor == PCI_VENDOR_ID_DEC &&
+ dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS) {
+ dev->irq = irq_create_mapping(NULL, 60);
+ set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
}
+#endif /* CONFIG_PPC32 */
}
#ifdef CONFIG_PPC64
Index: linux-cell/arch/powerpc/platforms/powermac/pmac.h
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/powermac/pmac.h 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/powermac/pmac.h 2006-11-06 15:02:21.000000000 +1100
@@ -20,7 +20,7 @@ extern void pmac_get_rtc_time(struct rtc
extern int pmac_set_rtc_time(struct rtc_time *);
extern void pmac_read_rtc_time(void);
extern void pmac_calibrate_decr(void);
-extern void pmac_pcibios_fixup(void);
+extern void pmac_pci_irq_fixup(struct pci_dev *);
extern void pmac_pci_init(void);
extern unsigned long pmac_ide_get_base(int index);
extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
Index: linux-cell/arch/powerpc/platforms/powermac/setup.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/powermac/setup.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/powermac/setup.c 2006-11-06 15:02:21.000000000 +1100
@@ -727,7 +727,7 @@ define_machine(powermac) {
.show_cpuinfo = pmac_show_cpuinfo,
.init_IRQ = pmac_pic_init,
.get_irq = NULL, /* changed later */
- .pcibios_fixup = pmac_pcibios_fixup,
+ .pci_irq_fixup = pmac_pci_irq_fixup,
.restart = pmac_restart,
.power_off = pmac_power_off,
.halt = pmac_halt,
Index: linux-cell/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c 2006-11-06 15:02:21.000000000 +1100
@@ -89,7 +89,7 @@ u8 find_slot_by_devfn(unsigned int *inte
/*
* Scans the interrupt map for pci device
*/
-void mpc7448_hpc2_fixup_irq(struct pci_dev *dev)
+void __devinit mpc7448_hpc2_fixup_irq(struct pci_dev *dev)
{
struct pci_controller *hose;
struct device_node *node;
@@ -117,19 +117,13 @@ void mpc7448_hpc2_fixup_irq(struct pci_d
pin = 1;
pin--;
dev->irq = interrupt[slot*4*7 + pin*7 + 5];
+
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+
DBG("TSI_PCI: dev->irq = 0x%x\n", dev->irq);
}
/* temporary pci irq map fixup*/
-void __init mpc7448_hpc2_pcibios_fixup(void)
-{
- struct pci_dev *dev = NULL;
- for_each_pci_dev(dev) {
- mpc7448_hpc2_fixup_irq(dev);
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
- }
-}
-
static void __init mpc7448_hpc2_setup_arch(void)
{
struct device_node *cpu;
@@ -300,7 +294,7 @@ define_machine(mpc7448_hpc2){
.init_IRQ = mpc7448_hpc2_init_IRQ,
.show_cpuinfo = mpc7448_hpc2_show_cpuinfo,
.get_irq = mpic_get_irq,
- .pcibios_fixup = mpc7448_hpc2_pcibios_fixup,
+ .pci_irq_fixup = mpc7448_hpc2_fixup_irq,
.restart = mpc7448_hpc2_restart,
.calibrate_decr = generic_calibrate_decr,
.machine_check_exception= mpc7448_machine_check_exception,
Index: linux-cell/arch/powerpc/platforms/pasemi/pasemi.h
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/pasemi/pasemi.h 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/pasemi/pasemi.h 2006-11-06 15:02:21.000000000 +1100
@@ -3,6 +3,5 @@
extern unsigned long pas_get_boot_time(void);
extern void pas_pci_init(void);
-extern void pas_pcibios_fixup(void);
#endif /* _PASEMI_PASEMI_H */
Index: linux-cell/arch/powerpc/platforms/pasemi/pci.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/pasemi/pci.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/pasemi/pci.c 2006-11-06 15:02:21.000000000 +1100
@@ -148,14 +148,6 @@ static int __init add_bridge(struct devi
}
-void __init pas_pcibios_fixup(void)
-{
- struct pci_dev *dev = NULL;
-
- for_each_pci_dev(dev)
- pci_read_irq_line(dev);
-}
-
static void __init pas_fixup_phb_resources(void)
{
struct pci_controller *hose, *tmp;
Index: linux-cell/arch/powerpc/platforms/pasemi/setup.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/pasemi/setup.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/pasemi/setup.c 2006-11-06 15:02:21.000000000 +1100
@@ -176,7 +176,6 @@ define_machine(pas) {
.init_early = pas_init_early,
.init_IRQ = pas_init_IRQ,
.get_irq = mpic_get_irq,
- .pcibios_fixup = pas_pcibios_fixup,
.restart = pas_restart,
.power_off = pas_power_off,
.halt = pas_halt,
Index: linux-cell/arch/powerpc/platforms/82xx/mpc82xx_ads.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/82xx/mpc82xx_ads.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/82xx/mpc82xx_ads.c 2006-11-06 15:02:21.000000000 +1100
@@ -515,16 +515,6 @@ static int m82xx_pci_exclude_device(u_ch
return PCIBIOS_SUCCESSFUL;
}
-static void
-__init mpc82xx_pcibios_fixup(void)
-{
- struct pci_dev *dev = NULL;
-
- for_each_pci_dev(dev) {
- pci_read_irq_line(dev);
- }
-}
-
void __init add_bridge(struct device_node *np)
{
int len;
@@ -597,9 +587,6 @@ static void __init mpc82xx_ads_setup_arc
add_bridge(np);
of_node_put(np);
- ppc_md.pci_map_irq = NULL;
- ppc_md.pcibios_fixup = mpc82xx_pcibios_fixup;
- ppc_md.pcibios_fixup_bus = NULL;
#endif
#ifdef CONFIG_ROOT_NFS
Index: linux-cell/arch/powerpc/platforms/83xx/mpc834x_itx.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/83xx/mpc834x_itx.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/83xx/mpc834x_itx.c 2006-11-06 15:02:21.000000000 +1100
@@ -122,7 +122,4 @@ define_machine(mpc834x_itx) {
.time_init = mpc83xx_time_init,
.calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
-#ifdef CONFIG_PCI
- .pcibios_fixup = mpc83xx_pcibios_fixup,
-#endif
};
Index: linux-cell/arch/powerpc/platforms/83xx/mpc834x_sys.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/83xx/mpc834x_sys.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/83xx/mpc834x_sys.c 2006-11-06 15:02:21.000000000 +1100
@@ -137,7 +137,4 @@ define_machine(mpc834x_sys) {
.time_init = mpc83xx_time_init,
.calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
-#ifdef CONFIG_PCI
- .pcibios_fixup = mpc83xx_pcibios_fixup,
-#endif
};
Index: linux-cell/arch/powerpc/platforms/83xx/mpc83xx.h
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/83xx/mpc83xx.h 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/83xx/mpc83xx.h 2006-11-06 15:02:21.000000000 +1100
@@ -11,7 +11,6 @@
extern int add_bridge(struct device_node *dev);
extern int mpc83xx_exclude_device(u_char bus, u_char devfn);
-extern void mpc83xx_pcibios_fixup(void);
extern void mpc83xx_restart(char *cmd);
extern long mpc83xx_time_init(void);
Index: linux-cell/arch/powerpc/platforms/83xx/pci.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/83xx/pci.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/83xx/pci.c 2006-11-06 15:02:21.000000000 +1100
@@ -45,15 +45,6 @@ int mpc83xx_exclude_device(u_char bus, u
return PCIBIOS_SUCCESSFUL;
}
-void __init mpc83xx_pcibios_fixup(void)
-{
- struct pci_dev *dev = NULL;
-
- /* map all the PCI irqs */
- for_each_pci_dev(dev)
- pci_read_irq_line(dev);
-}
-
int __init add_bridge(struct device_node *dev)
{
int len;
Index: linux-cell/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c 2006-11-06 15:02:21.000000000 +1100
@@ -398,15 +398,6 @@ mpc86xx_hpcn_show_cpuinfo(struct seq_fil
}
-void __init mpc86xx_hpcn_pcibios_fixup(void)
-{
- struct pci_dev *dev = NULL;
-
- for_each_pci_dev(dev)
- pci_read_irq_line(dev);
-}
-
-
/*
* Called very early, device-tree isn't unflattened
*/
@@ -461,7 +452,6 @@ define_machine(mpc86xx_hpcn) {
.setup_arch = mpc86xx_hpcn_setup_arch,
.init_IRQ = mpc86xx_hpcn_init_irq,
.show_cpuinfo = mpc86xx_hpcn_show_cpuinfo,
- .pcibios_fixup = mpc86xx_hpcn_pcibios_fixup,
.get_irq = mpic_get_irq,
.restart = mpc86xx_restart,
.time_init = mpc86xx_time_init,
Index: linux-cell/arch/powerpc/platforms/chrp/chrp.h
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/chrp/chrp.h 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/chrp/chrp.h 2006-11-06 15:02:21.000000000 +1100
@@ -9,4 +9,3 @@ extern long chrp_time_init(void);
extern void chrp_find_bridges(void);
extern void chrp_event_scan(unsigned long);
-extern void chrp_pcibios_fixup(void);
Index: linux-cell/arch/powerpc/platforms/chrp/setup.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/chrp/setup.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/chrp/setup.c 2006-11-06 15:02:21.000000000 +1100
@@ -600,7 +600,6 @@ define_machine(chrp) {
.init = chrp_init2,
.show_cpuinfo = chrp_show_cpuinfo,
.init_IRQ = chrp_init_IRQ,
- .pcibios_fixup = chrp_pcibios_fixup,
.restart = rtas_restart,
.power_off = rtas_power_off,
.halt = rtas_halt,
Index: linux-cell/arch/powerpc/platforms/85xx/mpc85xx_ads.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/85xx/mpc85xx_ads.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/85xx/mpc85xx_ads.c 2006-11-06 15:02:21.000000000 +1100
@@ -53,15 +53,6 @@ mpc85xx_exclude_device(u_char bus, u_cha
else
return PCIBIOS_SUCCESSFUL;
}
-
-void __init
-mpc85xx_pcibios_fixup(void)
-{
- struct pci_dev *dev = NULL;
-
- for_each_pci_dev(dev)
- pci_read_irq_line(dev);
-}
#endif /* CONFIG_PCI */
#ifdef CONFIG_CPM2
@@ -253,8 +244,6 @@ static void __init mpc85xx_ads_setup_arc
#ifdef CONFIG_PCI
for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
add_bridge(np);
-
- ppc_md.pcibios_fixup = mpc85xx_pcibios_fixup;
ppc_md.pci_exclude_device = mpc85xx_exclude_device;
#endif
Index: linux-cell/arch/powerpc/platforms/chrp/pci.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/chrp/pci.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/chrp/pci.c 2006-11-06 15:02:21.000000000 +1100
@@ -156,15 +156,6 @@ hydra_init(void)
return 1;
}
-void __init
-chrp_pcibios_fixup(void)
-{
- struct pci_dev *dev = NULL;
-
- for_each_pci_dev(dev)
- pci_read_irq_line(dev);
-}
-
#define PRG_CL_RESET_VALID 0x00010000
static void __init
^ permalink raw reply
* [PATCH 8/32] powerpc: Remove ppc_md.pci_map_irq & ppc_swizzle for ARCH=powerpc
From: Benjamin Herrenschmidt @ 2006-11-10 7:44 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1163144683.554182.685908332811.qpush@grosgo>
These were inherited from ARCH=ppc, but are not needed since parsing of interrupts
should be done via the of_* functions (who can do swizzling). If we ever need to
do non-standard swizzling on bridges without a device-node, then we might add
back a slightly different version of ppc_md.pci_swizzle but for now, that is not
the case.
I removed the couple of calls for these in 83xx. If that breaks something, then
there is a problem with the device-tree on these.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/kernel/pci_32.c | 23 -----------------------
arch/powerpc/platforms/83xx/mpc832x_mds.c | 2 --
arch/powerpc/platforms/83xx/mpc8360e_pb.c | 2 --
include/asm-powerpc/machdep.h | 4 ----
4 files changed, 31 deletions(-)
Index: linux-cell/arch/powerpc/kernel/pci_32.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/pci_32.c 2006-11-06 15:04:50.000000000 +1100
+++ linux-cell/arch/powerpc/kernel/pci_32.c 2006-11-06 15:05:34.000000000 +1100
@@ -1283,10 +1283,6 @@ pcibios_init(void)
if (pci_assign_all_buses && have_of)
pcibios_make_OF_bus_map();
- /* Do machine dependent PCI interrupt routing */
- if (ppc_md.pci_swizzle && ppc_md.pci_map_irq)
- pci_fixup_irqs(ppc_md.pci_swizzle, ppc_md.pci_map_irq);
-
/* Call machine dependent fixup */
if (ppc_md.pcibios_fixup)
ppc_md.pcibios_fixup();
@@ -1309,25 +1305,6 @@ pcibios_init(void)
subsys_initcall(pcibios_init);
-unsigned char __init
-common_swizzle(struct pci_dev *dev, unsigned char *pinp)
-{
- struct pci_controller *hose = dev->sysdata;
-
- if (dev->bus->number != hose->first_busno) {
- u8 pin = *pinp;
- do {
- pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
- /* Move up the chain of bridges. */
- dev = dev->bus->self;
- } while (dev->bus->self);
- *pinp = pin;
-
- /* The slot is the idsel of the last bridge. */
- }
- return PCI_SLOT(dev->devfn);
-}
-
unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
unsigned long start, unsigned long size)
{
Index: linux-cell/arch/powerpc/platforms/83xx/mpc832x_mds.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/83xx/mpc832x_mds.c 2006-11-06 15:01:52.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/83xx/mpc832x_mds.c 2006-11-06 15:05:34.000000000 +1100
@@ -96,8 +96,6 @@ static void __init mpc832x_sys_setup_arc
#ifdef CONFIG_PCI
for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
add_bridge(np);
-
- ppc_md.pci_swizzle = common_swizzle;
ppc_md.pci_exclude_device = mpc83xx_exclude_device;
#endif
Index: linux-cell/arch/powerpc/platforms/83xx/mpc8360e_pb.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/83xx/mpc8360e_pb.c 2006-11-06 15:01:52.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/83xx/mpc8360e_pb.c 2006-11-06 15:05:34.000000000 +1100
@@ -102,8 +102,6 @@ static void __init mpc8360_sys_setup_arc
#ifdef CONFIG_PCI
for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
add_bridge(np);
-
- ppc_md.pci_swizzle = common_swizzle;
ppc_md.pci_exclude_device = mpc83xx_exclude_device;
#endif
Index: linux-cell/include/asm-powerpc/machdep.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/machdep.h 2006-11-06 15:02:21.000000000 +1100
+++ linux-cell/include/asm-powerpc/machdep.h 2006-11-06 15:05:34.000000000 +1100
@@ -199,10 +199,6 @@ struct machdep_calls {
* Returns 0 to allow assignment/enabling of the device. */
int (*pcibios_enable_device_hook)(struct pci_dev *, int initial);
- /* For interrupt routing */
- unsigned char (*pci_swizzle)(struct pci_dev *, unsigned char *);
- int (*pci_map_irq)(struct pci_dev *, unsigned char, unsigned char);
-
/* Called in indirect_* to avoid touching devices */
int (*pci_exclude_device)(unsigned char, unsigned char);
^ permalink raw reply
* [PATCH 9/32] powerpc: Generic DCR infrastructure
From: Benjamin Herrenschmidt @ 2006-11-10 7:44 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1163144683.554182.685908332811.qpush@grosgo>
This patch adds new dcr_map/dcr_read/dcr_write accessors for DCRs that
can be used by drivers to transparently address either native DCRs or
memory mapped DCRs. The implementation for memory mapped DCRs is done
after the binding being currently worked on for SLOF and the Axon
chipset. This patch enables it for the cell native platform
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/Kconfig | 16 ++++
arch/powerpc/kernel/Makefile | 1
arch/powerpc/sysdev/Makefile | 3
arch/powerpc/sysdev/dcr-low.S | 39 +++++++++++
arch/powerpc/sysdev/dcr.c | 137 +++++++++++++++++++++++++++++++++++++++
arch/ppc/Kconfig | 11 +++
include/asm-powerpc/dcr-mmio.h | 51 ++++++++++++++
include/asm-powerpc/dcr-native.h | 39 +++++++++++
include/asm-powerpc/dcr.h | 42 +++++++++++
9 files changed, 337 insertions(+), 2 deletions(-)
Index: linux-cell/include/asm-powerpc/dcr.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-powerpc/dcr.h 2006-11-02 13:21:14.000000000 +1100
@@ -0,0 +1,42 @@
+/*
+ * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ASM_POWERPC_DCR_H
+#define _ASM_POWERPC_DCR_H
+#ifdef __KERNEL__
+
+#ifdef CONFIG_PPC_DCR_NATIVE
+#include <asm/dcr-native.h>
+#else
+#include <asm/dcr-mmio.h>
+#endif
+
+/*
+ * On CONFIG_PPC_MERGE, we have additional helpers to read the DCR
+ * base from the device-tree
+ */
+#ifdef CONFIG_PPC_MERGE
+extern unsigned int dcr_resource_start(struct device_node *np,
+ unsigned int index);
+extern unsigned int dcr_resource_len(struct device_node *np,
+ unsigned int index);
+#endif /* CONFIG_PPC_MERGE */
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_DCR_H */
Index: linux-cell/arch/powerpc/Kconfig
===================================================================
--- linux-cell.orig/arch/powerpc/Kconfig 2006-10-23 14:41:37.000000000 +1000
+++ linux-cell/arch/powerpc/Kconfig 2006-11-02 13:21:14.000000000 +1100
@@ -160,9 +160,11 @@ config PPC_86xx
config 40x
bool "AMCC 40x"
+ select PPC_DCR_NATIVE
config 44x
bool "AMCC 44x"
+ select PPC_DCR_NATIVE
config 8xx
bool "Freescale 8xx"
@@ -208,6 +210,19 @@ config PPC_FPU
bool
default y if PPC64
+config PPC_DCR_NATIVE
+ bool
+ default n
+
+config PPC_DCR_MMIO
+ bool
+ default n
+
+config PPC_DCR
+ bool
+ depends on PPC_DCR_NATIVE || PPC_DCR_MMIO
+ default y
+
config BOOKE
bool
depends on E200 || E500
@@ -445,6 +460,7 @@ config PPC_CELL
config PPC_CELL_NATIVE
bool
select PPC_CELL
+ select PPC_DCR_MMIO
default n
config PPC_IBM_CELL_BLADE
Index: linux-cell/include/asm-powerpc/dcr-mmio.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-powerpc/dcr-mmio.h 2006-11-02 13:21:14.000000000 +1100
@@ -0,0 +1,51 @@
+/*
+ * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ASM_POWERPC_DCR_MMIO_H
+#define _ASM_POWERPC_DCR_MMIO_H
+#ifdef __KERNEL__
+
+#include <asm/io.h>
+
+typedef struct { void __iomem *token; unsigned int stride; } dcr_host_t;
+
+#define DCR_MAP_OK(host) ((host).token != NULL)
+
+extern dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n,
+ unsigned int dcr_c);
+extern void dcr_unmap(dcr_host_t host, unsigned int dcr_n, unsigned int dcr_c);
+
+static inline u32 dcr_read(dcr_host_t host, unsigned int dcr_n)
+{
+ return in_be32(host.token + dcr_n * host.stride);
+}
+
+static inline void dcr_write(dcr_host_t host, unsigned int dcr_n, u32 value)
+{
+ out_be32(host.token + dcr_n * host.stride, value);
+}
+
+extern u64 of_translate_dcr_address(struct device_node *dev,
+ unsigned int dcr_n,
+ unsigned int *stride);
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_DCR_MMIO_H */
+
+
Index: linux-cell/include/asm-powerpc/dcr-native.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-powerpc/dcr-native.h 2006-11-02 13:21:14.000000000 +1100
@@ -0,0 +1,39 @@
+/*
+ * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ASM_POWERPC_DCR_NATIVE_H
+#define _ASM_POWERPC_DCR_NATIVE_H
+#ifdef __KERNEL__
+
+#include <asm/reg.h>
+
+typedef struct {} dcr_host_t;
+
+#define DCR_MAP_OK(host) (1)
+
+#define dcr_map(dev, dcr_n, dcr_c) {}
+#define dcr_unmap(host, dcr_n, dcr_c) {}
+#define dcr_read(host, dcr_n) mfdcr(dcr_n)
+#define dcr_write(host, dcr_n, value) mtdcr(dcr_n, value)
+
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_DCR_NATIVE_H */
+
+
Index: linux-cell/arch/ppc/Kconfig
===================================================================
--- linux-cell.orig/arch/ppc/Kconfig 2006-10-06 13:47:55.000000000 +1000
+++ linux-cell/arch/ppc/Kconfig 2006-11-02 13:21:14.000000000 +1100
@@ -77,9 +77,11 @@ config 6xx
config 40x
bool "40x"
+ select PPC_DCR_NATIVE
config 44x
bool "44x"
+ select PPC_DCR_NATIVE
config 8xx
bool "8xx"
@@ -95,6 +97,15 @@ endchoice
config PPC_FPU
bool
+config PPC_DCR_NATIVE
+ bool
+ default n
+
+config PPC_DCR
+ bool
+ depends on PPC_DCR_NATIVE
+ default y
+
config BOOKE
bool
depends on E200 || E500
Index: linux-cell/arch/powerpc/kernel/Makefile
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/Makefile 2006-11-02 13:16:16.000000000 +1100
+++ linux-cell/arch/powerpc/kernel/Makefile 2006-11-02 13:21:14.000000000 +1100
@@ -59,6 +59,7 @@ obj-$(CONFIG_BOOTX_TEXT) += btext.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o
+
module-$(CONFIG_PPC64) += module_64.o
obj-$(CONFIG_MODULES) += $(module-y)
Index: linux-cell/arch/powerpc/sysdev/Makefile
===================================================================
--- linux-cell.orig/arch/powerpc/sysdev/Makefile 2006-10-06 13:47:54.000000000 +1000
+++ linux-cell/arch/powerpc/sysdev/Makefile 2006-11-02 13:21:14.000000000 +1100
@@ -5,8 +5,7 @@ endif
obj-$(CONFIG_MPIC) += mpic.o
obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
obj-$(CONFIG_PPC_MPC106) += grackle.o
-obj-$(CONFIG_BOOKE) += dcr.o
-obj-$(CONFIG_40x) += dcr.o
+obj-$(CONFIG_PPC_DCR) += dcr.o dcr-low.o
obj-$(CONFIG_U3_DART) += dart_iommu.o
obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o
obj-$(CONFIG_FSL_SOC) += fsl_soc.o
Index: linux-cell/arch/powerpc/sysdev/dcr-low.S
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/arch/powerpc/sysdev/dcr-low.S 2006-11-02 13:21:14.000000000 +1100
@@ -0,0 +1,39 @@
+/*
+ * "Indirect" DCR access
+ *
+ * Copyright (c) 2004 Eugene Surovegin <ebs@ebshome.net>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <asm/ppc_asm.h>
+#include <asm/processor.h>
+
+#define DCR_ACCESS_PROLOG(table) \
+ rlwinm r3,r3,4,18,27; \
+ lis r5,table@h; \
+ ori r5,r5,table@l; \
+ add r3,r3,r5; \
+ mtctr r3; \
+ bctr
+
+_GLOBAL(__mfdcr)
+ DCR_ACCESS_PROLOG(__mfdcr_table)
+
+_GLOBAL(__mtdcr)
+ DCR_ACCESS_PROLOG(__mtdcr_table)
+
+__mfdcr_table:
+ mfdcr r3,0; blr
+__mtdcr_table:
+ mtdcr 0,r4; blr
+
+dcr = 1
+ .rept 1023
+ mfdcr r3,dcr; blr
+ mtdcr dcr,r4; blr
+ dcr = dcr + 1
+ .endr
Index: linux-cell/arch/powerpc/sysdev/dcr.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/arch/powerpc/sysdev/dcr.c 2006-11-02 13:21:14.000000000 +1100
@@ -0,0 +1,137 @@
+/*
+ * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <asm/prom.h>
+#include <asm/dcr.h>
+
+unsigned int dcr_resource_start(struct device_node *np, unsigned int index)
+{
+ unsigned int ds;
+ const u32 *dr = get_property(np, "dcr-reg", &ds);
+
+ if (dr == NULL || ds & 1 || index >= (ds / 8))
+ return 0;
+
+ return dr[index * 2];
+}
+
+unsigned int dcr_resource_len(struct device_node *np, unsigned int index)
+{
+ unsigned int ds;
+ const u32 *dr = get_property(np, "dcr-reg", &ds);
+
+ if (dr == NULL || ds & 1 || index >= (ds / 8))
+ return 0;
+
+ return dr[index * 2 + 1];
+}
+
+#ifndef CONFIG_PPC_DCR_NATIVE
+
+static struct device_node * find_dcr_parent(struct device_node * node)
+{
+ struct device_node *par, *tmp;
+ const u32 *p;
+
+ for (par = of_node_get(node); par;) {
+ if (get_property(par, "dcr-controller", NULL))
+ break;
+ p = get_property(par, "dcr-parent", NULL);
+ tmp = par;
+ if (p == NULL)
+ par = of_get_parent(par);
+ else
+ par = of_find_node_by_phandle(*p);
+ of_node_put(tmp);
+ }
+ return par;
+}
+
+u64 of_translate_dcr_address(struct device_node *dev,
+ unsigned int dcr_n,
+ unsigned int *out_stride)
+{
+ struct device_node *dp;
+ const u32 *p;
+ unsigned int stride;
+ u64 ret;
+
+ dp = find_dcr_parent(dev);
+ if (dp == NULL)
+ return OF_BAD_ADDR;
+
+ /* Stride is not properly defined yet, default to 0x10 for Axon */
+ p = get_property(dp, "dcr-mmio-stride", NULL);
+ stride = (p == NULL) ? 0x10 : *p;
+
+ /* XXX FIXME: Which property name is to use of the 2 following ? */
+ p = get_property(dp, "dcr-mmio-range", NULL);
+ if (p == NULL)
+ p = get_property(dp, "dcr-mmio-space", NULL);
+ if (p == NULL)
+ return OF_BAD_ADDR;
+
+ /* Maybe could do some better range checking here */
+ ret = of_translate_address(dp, p);
+ if (ret != OF_BAD_ADDR)
+ ret += (u64)(stride) * (u64)dcr_n;
+ if (out_stride)
+ *out_stride = stride;
+ return ret;
+}
+
+dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n,
+ unsigned int dcr_c)
+{
+ dcr_host_t ret = { .token = NULL, .stride = 0 };
+ u64 addr;
+
+ pr_debug("dcr_map(%s, 0x%x, 0x%x)\n",
+ dev->full_name, dcr_n, dcr_c);
+
+ addr = of_translate_dcr_address(dev, dcr_n, &ret.stride);
+ pr_debug("translates to addr: 0x%lx, stride: 0x%x\n",
+ addr, ret.stride);
+ if (addr == OF_BAD_ADDR)
+ return ret;
+ pr_debug("mapping 0x%x bytes\n", dcr_c * ret.stride);
+ ret.token = ioremap(addr, dcr_c * ret.stride);
+ if (ret.token == NULL)
+ return ret;
+ pr_debug("mapped at 0x%p -> base is 0x%p\n",
+ ret.token, ret.token - dcr_n * ret.stride);
+ ret.token -= dcr_n * ret.stride;
+ return ret;
+}
+
+void dcr_unmap(dcr_host_t host, unsigned int dcr_n, unsigned int dcr_c)
+{
+ dcr_host_t h = host;
+
+ if (h.token == NULL)
+ return;
+ h.token -= dcr_n * h.stride;
+ iounmap(h.token);
+ h.token = NULL;
+}
+
+#endif /* !defined(CONFIG_PPC_DCR_NATIVE) */
^ permalink raw reply
* [PATCH 10/32] powerpc: Make EMAC use generic DCR access methods
From: Benjamin Herrenschmidt @ 2006-11-10 7:44 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1163144683.554182.685908332811.qpush@grosgo>
This patch makes the EMAC driver use the new DCR access methods. It
doesn't yet uses dcr_map() and thus still only work with real DCRs.
This will be fixed in a later patch
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
drivers/net/ibm_emac/ibm_emac_mal.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
Index: linux-cell/drivers/net/ibm_emac/ibm_emac_mal.h
===================================================================
--- linux-cell.orig/drivers/net/ibm_emac/ibm_emac_mal.h 2006-10-11 13:01:59.000000000 +1000
+++ linux-cell/drivers/net/ibm_emac/ibm_emac_mal.h 2006-10-11 14:35:28.000000000 +1000
@@ -24,6 +24,7 @@
#include <linux/netdevice.h>
#include <asm/io.h>
+#include <asm/dcr.h>
/*
* These MAL "versions" probably aren't the real versions IBM uses for these
@@ -191,6 +192,7 @@ struct mal_commac {
struct ibm_ocp_mal {
int dcrbase;
+ dcr_host_t dcrhost;
struct list_head poll_list;
struct net_device poll_dev;
@@ -207,12 +209,12 @@ struct ibm_ocp_mal {
static inline u32 get_mal_dcrn(struct ibm_ocp_mal *mal, int reg)
{
- return mfdcr(mal->dcrbase + reg);
+ return dcr_read(mal->dcrhost, mal->dcrbase + reg);
}
static inline void set_mal_dcrn(struct ibm_ocp_mal *mal, int reg, u32 val)
{
- mtdcr(mal->dcrbase + reg, val);
+ dcr_write(mal->dcrhost, mal->dcrbase + reg, val);
}
/* Register MAL devices */
^ permalink raw reply
* [PATCH 11/32] powerpc: Support for DCR based MPIC
From: Benjamin Herrenschmidt @ 2006-11-10 7:44 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1163144683.554182.685908332811.qpush@grosgo>
This patch implements support for DCR based MPIC implementations. Such
implementations have the MPIC_USES_DCR flag set and don't use the phys_addr
argument of mpic_alloc (they require a valid dcr mapping in the device node)
This version of the patch can use a little bif of cleanup still (I can
probably consolidate rb->dbase/doff, at least once I'm sure on how the
hardware is actually supposed to work vs. possible simulator issues) and
it should be possible to build a DCR-only version of the driver. I need
to cleanup a bit the CONFIG_* handling for that and probably introduce
CONFIG_MPIC_MMIO and CONFIG_MPIC_DCR.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/sysdev/mpic.c | 138 ++++++++++++++++++++++++++++++++-------------
include/asm-powerpc/mpic.h | 35 ++++++++++-
2 files changed, 132 insertions(+), 41 deletions(-)
Index: linux-cell/arch/powerpc/sysdev/mpic.c
===================================================================
--- linux-cell.orig/arch/powerpc/sysdev/mpic.c 2006-10-16 17:20:39.000000000 +1000
+++ linux-cell/arch/powerpc/sysdev/mpic.c 2006-10-16 17:29:50.000000000 +1000
@@ -147,33 +147,51 @@ static u32 mpic_infos[][MPIC_IDX_END] =
*/
-static inline u32 _mpic_read(unsigned int be, volatile u32 __iomem *base,
- unsigned int reg)
-{
- if (be)
- return in_be32(base + (reg >> 2));
- else
- return in_le32(base + (reg >> 2));
+static inline u32 _mpic_read(enum mpic_reg_type type,
+ struct mpic_reg_bank *rb,
+ unsigned int reg)
+{
+ switch(type) {
+#ifdef CONFIG_PPC_DCR
+ case mpic_access_dcr:
+ return dcr_read(rb->dhost,
+ rb->dbase + reg + rb->doff);
+#endif
+ case mpic_access_mmio_be:
+ return in_be32(rb->base + (reg >> 2));
+ case mpic_access_mmio_le:
+ default:
+ return in_le32(rb->base + (reg >> 2));
+ }
}
-static inline void _mpic_write(unsigned int be, volatile u32 __iomem *base,
- unsigned int reg, u32 value)
+static inline void _mpic_write(enum mpic_reg_type type,
+ struct mpic_reg_bank *rb,
+ unsigned int reg, u32 value)
{
- if (be)
- out_be32(base + (reg >> 2), value);
- else
- out_le32(base + (reg >> 2), value);
+ switch(type) {
+#ifdef CONFIG_PPC_DCR
+ case mpic_access_dcr:
+ return dcr_write(rb->dhost,
+ rb->dbase + reg + rb->doff, value);
+#endif
+ case mpic_access_mmio_be:
+ return out_be32(rb->base + (reg >> 2), value);
+ case mpic_access_mmio_le:
+ default:
+ return out_le32(rb->base + (reg >> 2), value);
+ }
}
static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi)
{
- unsigned int be = (mpic->flags & MPIC_BIG_ENDIAN) != 0;
+ enum mpic_reg_type type = mpic->reg_type;
unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) +
(ipi * MPIC_INFO(GREG_IPI_STRIDE));
- if (mpic->flags & MPIC_BROKEN_IPI)
- be = !be;
- return _mpic_read(be, mpic->gregs, offset);
+ if ((mpic->flags & MPIC_BROKEN_IPI) && type == mpic_access_mmio_le)
+ type = mpic_access_mmio_be;
+ return _mpic_read(type, &mpic->gregs, offset);
}
static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value)
@@ -181,7 +199,7 @@ static inline void _mpic_ipi_write(struc
unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) +
(ipi * MPIC_INFO(GREG_IPI_STRIDE));
- _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->gregs, offset, value);
+ _mpic_write(mpic->reg_type, &mpic->gregs, offset, value);
}
static inline u32 _mpic_cpu_read(struct mpic *mpic, unsigned int reg)
@@ -190,8 +208,7 @@ static inline u32 _mpic_cpu_read(struct
if (mpic->flags & MPIC_PRIMARY)
cpu = hard_smp_processor_id();
- return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN,
- mpic->cpuregs[cpu], reg);
+ return _mpic_read(mpic->reg_type, &mpic->cpuregs[cpu], reg);
}
static inline void _mpic_cpu_write(struct mpic *mpic, unsigned int reg, u32 value)
@@ -201,7 +218,7 @@ static inline void _mpic_cpu_write(struc
if (mpic->flags & MPIC_PRIMARY)
cpu = hard_smp_processor_id();
- _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->cpuregs[cpu], reg, value);
+ _mpic_write(mpic->reg_type, &mpic->cpuregs[cpu], reg, value);
}
static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigned int reg)
@@ -209,7 +226,7 @@ static inline u32 _mpic_irq_read(struct
unsigned int isu = src_no >> mpic->isu_shift;
unsigned int idx = src_no & mpic->isu_mask;
- return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
+ return _mpic_read(mpic->reg_type, &mpic->isus[isu],
reg + (idx * MPIC_INFO(IRQ_STRIDE)));
}
@@ -219,12 +236,12 @@ static inline void _mpic_irq_write(struc
unsigned int isu = src_no >> mpic->isu_shift;
unsigned int idx = src_no & mpic->isu_mask;
- _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
+ _mpic_write(mpic->reg_type, &mpic->isus[isu],
reg + (idx * MPIC_INFO(IRQ_STRIDE)), value);
}
-#define mpic_read(b,r) _mpic_read(mpic->flags & MPIC_BIG_ENDIAN,(b),(r))
-#define mpic_write(b,r,v) _mpic_write(mpic->flags & MPIC_BIG_ENDIAN,(b),(r),(v))
+#define mpic_read(b,r) _mpic_read(mpic->reg_type,&(b),(r))
+#define mpic_write(b,r,v) _mpic_write(mpic->reg_type,&(b),(r),(v))
#define mpic_ipi_read(i) _mpic_ipi_read(mpic,(i))
#define mpic_ipi_write(i,v) _mpic_ipi_write(mpic,(i),(v))
#define mpic_cpu_read(i) _mpic_cpu_read(mpic,(i))
@@ -238,6 +255,38 @@ static inline void _mpic_irq_write(struc
*/
+static void _mpic_map_mmio(struct mpic *mpic, unsigned long phys_addr,
+ struct mpic_reg_bank *rb, unsigned int offset,
+ unsigned int size)
+{
+ rb->base = ioremap(phys_addr + offset, size);
+ BUG_ON(rb->base == NULL);
+}
+
+#ifdef CONFIG_PPC_DCR
+static void _mpic_map_dcr(struct mpic *mpic, struct mpic_reg_bank *rb,
+ unsigned int offset, unsigned int size)
+{
+ rb->dbase = mpic->dcr_base;
+ rb->doff = offset;
+ rb->dhost = dcr_map(mpic->of_node, rb->dbase + rb->doff, size);
+ BUG_ON(!DCR_MAP_OK(rb->dhost));
+}
+
+static inline void mpic_map(struct mpic *mpic, unsigned long phys_addr,
+ struct mpic_reg_bank *rb, unsigned int offset,
+ unsigned int size)
+{
+ if (mpic->flags & MPIC_USES_DCR)
+ _mpic_map_dcr(mpic, rb, offset, size);
+ else
+ _mpic_map_mmio(mpic, phys_addr, rb, offset, size);
+}
+#else /* CONFIG_PPC_DCR */
+#define mpic_map(m,p,b,o,s) _mpic_map_mmio(m,p,b,o,s)
+#endif /* !CONFIG_PPC_DCR */
+
+
/* Check if we have one of those nice broken MPICs with a flipped endian on
* reads from IPI registers
@@ -883,6 +932,7 @@ struct mpic * __init mpic_alloc(struct d
if (flags & MPIC_PRIMARY)
mpic->hc_ht_irq.set_affinity = mpic_set_affinity;
#endif /* CONFIG_MPIC_BROKEN_U3 */
+
#ifdef CONFIG_SMP
mpic->hc_ipi = mpic_ipi_chip;
mpic->hc_ipi.typename = name;
@@ -897,11 +947,26 @@ struct mpic * __init mpic_alloc(struct d
mpic->hw_set = mpic_infos[MPIC_GET_REGSET(flags)];
#endif
+ /* default register type */
+ mpic->reg_type = (flags & MPIC_BIG_ENDIAN) ?
+ mpic_access_mmio_be : mpic_access_mmio_le;
+
+#ifdef CONFIG_PPC_DCR
+ if (mpic->flags & MPIC_USES_DCR) {
+ const u32 *dbasep;
+ BUG_ON(mpic->of_node == NULL);
+ dbasep = get_property(mpic->of_node, "dcr-reg", NULL);
+ BUG_ON(dbasep == NULL);
+ mpic->dcr_base = *dbasep;
+ mpic->reg_type = mpic_access_dcr;
+ }
+#else
+ BUG_ON (mpic->flags & MPIC_USES_DCR);
+#endif /* CONFIG_PPC_DCR */
+
/* Map the global registers */
- mpic->gregs = ioremap(phys_addr + MPIC_INFO(GREG_BASE), 0x1000);
- mpic->tmregs = mpic->gregs +
- ((MPIC_INFO(TIMER_BASE) - MPIC_INFO(GREG_BASE)) >> 2);
- BUG_ON(mpic->gregs == NULL);
+ mpic_map(mpic, phys_addr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000);
+ mpic_map(mpic, phys_addr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
/* Reset */
if (flags & MPIC_WANTS_RESET) {
@@ -926,17 +991,16 @@ struct mpic * __init mpic_alloc(struct d
/* Map the per-CPU registers */
for (i = 0; i < mpic->num_cpus; i++) {
- mpic->cpuregs[i] = ioremap(phys_addr + MPIC_INFO(CPU_BASE) +
- i * MPIC_INFO(CPU_STRIDE), 0x1000);
- BUG_ON(mpic->cpuregs[i] == NULL);
+ mpic_map(mpic, phys_addr, &mpic->cpuregs[i],
+ MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE),
+ 0x1000);
}
/* Initialize main ISU if none provided */
if (mpic->isu_size == 0) {
mpic->isu_size = mpic->num_sources;
- mpic->isus[0] = ioremap(phys_addr + MPIC_INFO(IRQ_BASE),
- MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
- BUG_ON(mpic->isus[0] == NULL);
+ mpic_map(mpic, phys_addr, &mpic->isus[0],
+ MPIC_INFO(IRQ_BASE), MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
}
mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
mpic->isu_mask = (1 << mpic->isu_shift) - 1;
@@ -979,8 +1043,8 @@ void __init mpic_assign_isu(struct mpic
BUG_ON(isu_num >= MPIC_MAX_ISU);
- mpic->isus[isu_num] = ioremap(phys_addr,
- MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
+ mpic_map(mpic, phys_addr, &mpic->isus[isu_num], 0,
+ MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
if ((isu_first + mpic->isu_size) > mpic->num_sources)
mpic->num_sources = isu_first + mpic->isu_size;
}
Index: linux-cell/include/asm-powerpc/mpic.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/mpic.h 2006-10-16 17:20:39.000000000 +1000
+++ linux-cell/include/asm-powerpc/mpic.h 2006-10-16 17:26:46.000000000 +1000
@@ -3,6 +3,7 @@
#ifdef __KERNEL__
#include <linux/irq.h>
+#include <asm/dcr.h>
/*
* Global registers
@@ -225,6 +226,23 @@ struct mpic_irq_fixup
#endif /* CONFIG_MPIC_BROKEN_U3 */
+enum mpic_reg_type {
+ mpic_access_mmio_le,
+ mpic_access_mmio_be,
+#ifdef CONFIG_PPC_DCR
+ mpic_access_dcr
+#endif
+};
+
+struct mpic_reg_bank {
+ u32 __iomem *base;
+#ifdef CONFIG_PPC_DCR
+ dcr_host_t dhost;
+ unsigned int dbase;
+ unsigned int doff;
+#endif /* CONFIG_PPC_DCR */
+};
+
/* The instance data of a given MPIC */
struct mpic
{
@@ -264,11 +282,18 @@ struct mpic
spinlock_t fixup_lock;
#endif
+ /* Register access method */
+ enum mpic_reg_type reg_type;
+
/* The various ioremap'ed bases */
- volatile u32 __iomem *gregs;
- volatile u32 __iomem *tmregs;
- volatile u32 __iomem *cpuregs[MPIC_MAX_CPUS];
- volatile u32 __iomem *isus[MPIC_MAX_ISU];
+ struct mpic_reg_bank gregs;
+ struct mpic_reg_bank tmregs;
+ struct mpic_reg_bank cpuregs[MPIC_MAX_CPUS];
+ struct mpic_reg_bank isus[MPIC_MAX_ISU];
+
+#ifdef CONFIG_PPC_DCR
+ unsigned int dcr_base;
+#endif
#ifdef CONFIG_MPIC_WEIRD
/* Pointer to HW info array */
@@ -305,6 +330,8 @@ struct mpic
#define MPIC_SPV_EOI 0x00000020
/* No passthrough disable */
#define MPIC_NO_PTHROU_DIS 0x00000040
+/* DCR based MPIC */
+#define MPIC_USES_DCR 0x00000080
/* MPIC HW modification ID */
#define MPIC_REGSET_MASK 0xf0000000
^ permalink raw reply
* [PATCH 12/32] powerpc: Improve MPIC driver auto-configuration from DT
From: Benjamin Herrenschmidt @ 2006-11-10 7:44 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1163144683.554182.685908332811.qpush@grosgo>
This patch applies on top of the MPIC DCR support. It makes the MPIC
driver capable of a lot more auto-configuration based on the device-tree,
for example, it can retreive it's own physical address if not passed as
an argument, find out if it's DCR or MMIO mapped, and set the BIG_ENDIAN
flag automatically in the presence of a "big-endian" property in the
device-tree node.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/sysdev/mpic.c | 50 +++++++++++++++++++++++++++++++++------------
include/asm-powerpc/mpic.h | 4 +--
2 files changed, 39 insertions(+), 15 deletions(-)
Index: linux-cell/arch/powerpc/sysdev/mpic.c
===================================================================
--- linux-cell.orig/arch/powerpc/sysdev/mpic.c 2006-11-06 14:34:17.000000000 +1100
+++ linux-cell/arch/powerpc/sysdev/mpic.c 2006-11-06 14:36:45.000000000 +1100
@@ -894,7 +894,7 @@ static struct irq_host_ops mpic_host_ops
*/
struct mpic * __init mpic_alloc(struct device_node *node,
- unsigned long phys_addr,
+ phys_addr_t phys_addr,
unsigned int flags,
unsigned int isu_size,
unsigned int irq_count,
@@ -904,6 +904,7 @@ struct mpic * __init mpic_alloc(struct d
u32 reg;
const char *vers;
int i;
+ u64 paddr = phys_addr;
mpic = alloc_bootmem(sizeof(struct mpic));
if (mpic == NULL)
@@ -943,6 +944,11 @@ struct mpic * __init mpic_alloc(struct d
mpic->irq_count = irq_count;
mpic->num_sources = 0; /* so far */
+ /* Check for "big-endian" in device-tree */
+ if (node && get_property(node, "big-endian", NULL) != NULL)
+ mpic->flags |= MPIC_BIG_ENDIAN;
+
+
#ifdef CONFIG_MPIC_WEIRD
mpic->hw_set = mpic_infos[MPIC_GET_REGSET(flags)];
#endif
@@ -951,11 +957,17 @@ struct mpic * __init mpic_alloc(struct d
mpic->reg_type = (flags & MPIC_BIG_ENDIAN) ?
mpic_access_mmio_be : mpic_access_mmio_le;
+ /* If no physical address is passed in, a device-node is mandatory */
+ BUG_ON(paddr == 0 && node == NULL);
+
+ /* If no physical address passed in, check if it's dcr based */
+ if (paddr == 0 && get_property(node, "dcr-reg", NULL) != NULL)
+ mpic->flags |= MPIC_USES_DCR;
+
#ifdef CONFIG_PPC_DCR
if (mpic->flags & MPIC_USES_DCR) {
const u32 *dbasep;
- BUG_ON(mpic->of_node == NULL);
- dbasep = get_property(mpic->of_node, "dcr-reg", NULL);
+ dbasep = get_property(node, "dcr-reg", NULL);
BUG_ON(dbasep == NULL);
mpic->dcr_base = *dbasep;
mpic->reg_type = mpic_access_dcr;
@@ -964,9 +976,20 @@ struct mpic * __init mpic_alloc(struct d
BUG_ON (mpic->flags & MPIC_USES_DCR);
#endif /* CONFIG_PPC_DCR */
+ /* If the MPIC is not DCR based, and no physical address was passed
+ * in, try to obtain one
+ */
+ if (paddr == 0 && !(mpic->flags & MPIC_USES_DCR)) {
+ const u32 *reg;
+ reg = get_property(node, "reg", NULL);
+ BUG_ON(reg == NULL);
+ paddr = of_translate_address(node, reg);
+ BUG_ON(paddr == OF_BAD_ADDR);
+ }
+
/* Map the global registers */
- mpic_map(mpic, phys_addr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000);
- mpic_map(mpic, phys_addr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
+ mpic_map(mpic, paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000);
+ mpic_map(mpic, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
/* Reset */
if (flags & MPIC_WANTS_RESET) {
@@ -991,7 +1014,7 @@ struct mpic * __init mpic_alloc(struct d
/* Map the per-CPU registers */
for (i = 0; i < mpic->num_cpus; i++) {
- mpic_map(mpic, phys_addr, &mpic->cpuregs[i],
+ mpic_map(mpic, paddr, &mpic->cpuregs[i],
MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE),
0x1000);
}
@@ -999,7 +1022,7 @@ struct mpic * __init mpic_alloc(struct d
/* Initialize main ISU if none provided */
if (mpic->isu_size == 0) {
mpic->isu_size = mpic->num_sources;
- mpic_map(mpic, phys_addr, &mpic->isus[0],
+ mpic_map(mpic, paddr, &mpic->isus[0],
MPIC_INFO(IRQ_BASE), MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
}
mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
@@ -1020,10 +1043,11 @@ struct mpic * __init mpic_alloc(struct d
vers = "<unknown>";
break;
}
- printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %lx, max %d CPUs\n",
- name, vers, phys_addr, mpic->num_cpus);
- printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n", mpic->isu_size,
- mpic->isu_shift, mpic->isu_mask);
+ printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %llx,"
+ " max %d CPUs\n",
+ name, vers, (unsigned long long)paddr, mpic->num_cpus);
+ printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n",
+ mpic->isu_size, mpic->isu_shift, mpic->isu_mask);
mpic->next = mpics;
mpics = mpic;
@@ -1037,13 +1061,13 @@ struct mpic * __init mpic_alloc(struct d
}
void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
- unsigned long phys_addr)
+ phys_addr_t paddr)
{
unsigned int isu_first = isu_num * mpic->isu_size;
BUG_ON(isu_num >= MPIC_MAX_ISU);
- mpic_map(mpic, phys_addr, &mpic->isus[isu_num], 0,
+ mpic_map(mpic, paddr, &mpic->isus[isu_num], 0,
MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
if ((isu_first + mpic->isu_size) > mpic->num_sources)
mpic->num_sources = isu_first + mpic->isu_size;
Index: linux-cell/include/asm-powerpc/mpic.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/mpic.h 2006-11-06 14:34:17.000000000 +1100
+++ linux-cell/include/asm-powerpc/mpic.h 2006-11-06 14:34:38.000000000 +1100
@@ -364,7 +364,7 @@ struct mpic
* that is senses[0] correspond to linux irq "irq_offset".
*/
extern struct mpic *mpic_alloc(struct device_node *node,
- unsigned long phys_addr,
+ phys_addr_t phys_addr,
unsigned int flags,
unsigned int isu_size,
unsigned int irq_count,
@@ -377,7 +377,7 @@ extern struct mpic *mpic_alloc(struct de
* @phys_addr: physical address of the ISU
*/
extern void mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
- unsigned long phys_addr);
+ phys_addr_t phys_addr);
/* Set default sense codes
*
^ permalink raw reply
* [PATCH 13/32] powerpc: Native cell support for MPIC in southbridge
From: Benjamin Herrenschmidt @ 2006-11-10 7:44 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1163144683.554182.685908332811.qpush@grosgo>
Add support for southbridges using the MPIC interrupt controller to
the native cell platforms.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/Kconfig | 1
arch/powerpc/platforms/cell/setup.c | 44 ++++++++++++++++++++++++++++++++++++
2 files changed, 45 insertions(+)
Index: linux-cell/arch/powerpc/Kconfig
===================================================================
--- linux-cell.orig/arch/powerpc/Kconfig 2006-11-06 15:05:40.000000000 +1100
+++ linux-cell/arch/powerpc/Kconfig 2006-11-06 15:15:45.000000000 +1100
@@ -461,6 +461,7 @@ config PPC_CELL_NATIVE
bool
select PPC_CELL
select PPC_DCR_MMIO
+ select MPIC
default n
config PPC_IBM_CELL_BLADE
Index: linux-cell/arch/powerpc/platforms/cell/setup.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/cell/setup.c 2006-11-06 15:02:21.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/cell/setup.c 2006-11-06 15:05:44.000000000 +1100
@@ -50,6 +50,7 @@
#include <asm/spu.h>
#include <asm/spu_priv1.h>
#include <asm/udbg.h>
+#include <asm/mpic.h>
#include "interrupt.h"
#include "iommu.h"
@@ -80,10 +81,53 @@ static void cell_progress(char *s, unsig
printk("*** %04x : %s\n", hex, s ? s : "");
}
+static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc)
+{
+ struct mpic *mpic = desc->handler_data;
+ unsigned int virq;
+
+ virq = mpic_get_one_irq(mpic);
+ if (virq != NO_IRQ)
+ generic_handle_irq(virq);
+ desc->chip->eoi(irq);
+}
+
+static void __init mpic_init_IRQ(void)
+{
+ struct device_node *dn;
+ struct mpic *mpic;
+ unsigned int virq;
+
+ for (dn = NULL;
+ (dn = of_find_node_by_name(dn, "interrupt-controller"));) {
+ if (!device_is_compatible(dn, "CBEA,platform-open-pic"))
+ continue;
+
+ /* The MPIC driver will get everything it needs from the
+ * device-tree, just pass 0 to all arguments
+ */
+ mpic = mpic_alloc(dn, 0, 0, 0, 0, " MPIC ");
+ if (mpic == NULL)
+ continue;
+ mpic_init(mpic);
+
+ virq = irq_of_parse_and_map(dn, 0);
+ if (virq == NO_IRQ)
+ continue;
+
+ printk(KERN_INFO "%s : hooking up to IRQ %d\n",
+ dn->full_name, virq);
+ set_irq_data(virq, mpic);
+ set_irq_chained_handler(virq, cell_mpic_cascade);
+ }
+}
+
+
static void __init cell_init_irq(void)
{
iic_init_IRQ();
spider_init_IRQ();
+ mpic_init_IRQ();
}
static void __init cell_setup_arch(void)
^ 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