* Re: RTC on 2.6.36 for PowerMac 8600
From: Andreas Schwab @ 2012-01-29 8:29 UTC (permalink / raw)
To: kevin diggs; +Cc: Linux PPC Development
In-Reply-To: <CAKTLLVQTt8aRFb2QpXkUUikTJshnV_ytTWJ778MZ1ACyoD8aOw__43210.997261531$1327806577$gmane$org@mail.gmail.com>
kevin diggs <diggskevin38@gmail.com> writes:
> [root@PowerMac8600B root]# hwclock --debug
> hwclock from util-linux-2.12pre
> Using /dev/rtc interface to clock.
> Last drift adjustment done at 1317444443 seconds after 1969
> Last calibration done at 1317444443 seconds after 1969
> Hardware clock is on local time
> Assuming hardware clock is kept in local time.
> Waiting for clock tick...
> /dev/rtc does not have interrupt functions. Waiting in loop for time
> from /dev/rtc to change
> RTC_RD_TIME: Invalid argument
Perhaps the RTC was reset due to battery running out? That would set
the year to 1900, but the kernel RTC interface cannot represent dates
before 1970. Unfortunately hwclock insists on reading the RTC even when
you just want to write to it, so you cannot fix that with hwclock -w.
When the battery of my iBook has run out I'm using the following to
reset RTC to current time so that it is usable again.
Andreas.
#include <time.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/rtc.h>
int
main (void)
{
time_t now;
struct tm gmt;
struct rtc_time rtc;
int fd;
now = time (0);
gmt = *gmtime (&now);
rtc.tm_sec = gmt.tm_sec;
rtc.tm_min = gmt.tm_min;
rtc.tm_hour = gmt.tm_hour;
rtc.tm_mday = gmt.tm_mday;
rtc.tm_mon = gmt.tm_mon;
rtc.tm_year = gmt.tm_year;
rtc.tm_wday = gmt.tm_wday;
rtc.tm_yday = gmt.tm_yday;
rtc.tm_isdst = gmt.tm_isdst;
fd = open ("/dev/rtc", O_RDONLY);
if (fd < 0)
fd = open ("/dev/rtc0", O_RDONLY);
if (fd < 0)
{
perror ("/dev/rtc");
return 1;
}
if (ioctl (fd, RTC_SET_TIME, &rtc) < 0)
{
perror ("RTC_SET_TIME");
return 1;
}
return 0;
}
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply
* Re: Problem in getting shared memory access on P1022RDK
From: tiejun.chen @ 2012-01-29 3:15 UTC (permalink / raw)
To: Arshad, Farrukh; +Cc: Scott Wood, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <93CD5F41FDBC6042A6B449764F3B35CC050CE2CD@EU-MBX-03.mgc.mentorg.com>
Arshad, Farrukh wrote:
> I have dumped TLB entries while mapping shared memory. On both cores M-Bit (MAS2[61]) is set in TLB0 entries. On both cores M-Bit is set for all valid TLB1 entries. TLB1 does contains some invalid entries which has M-Bit cleared. So I believe at this time the coherency is not the issue. Any further thoughts on the issue ?
>
Did you check all associated TLBx VPN/RPN and attribute setting are same between
two scenarios: W -> Core0 & R <- Core1 and W -> Core1 & R <- Core0?
Can you send me your TLB dump log separately if possible?
And did you try this flag 'O_SYNC'?
Tiejun
> I have modified dump_tlb_book3e function (found in arch/powerpc/xmon/xmon.c) function for BookE MMU to dump TLB entries.
>
> Regards,
> Farrukh Arshad
>
>
> -----Original Message-----
> From: tiejun.chen [mailto:tiejun.chen@windriver.com]
> Sent: Thursday, January 12, 2012 1:09 PM
> To: Arshad, Farrukh
> Cc: Scott Wood; linuxppc-dev@lists.ozlabs.org
> Subject: Re: Problem in getting shared memory access on P1022RDK
>
> Arshad, Farrukh wrote:
>> Adding more it,
>>
>> I have removed the shared memory kernel driver dependency just to narrow down the problem area and I have written a small piece of code in user space. A writer & a reader application which access the shared memory and I got the same behavior as with the shared memory kernel driver. Interestingly, my user space application work fine on P1022DS but not on P1022RDK however both using the same CPU modules.
>>
>> When I write a simple string on shared memory from Core 1 it is read
>> at Core 0 properly When I write a simple string on shared memory from Core 0 it is not read at Core 1.
>>
>
> Did you dump TLB entry to check page memory coherence attribute for a shared memory as I mentioned previously? This should be consistent on both sides.
>
>> With this test now I am sure the problem lies in the kernel itself. Any pointers to look for the troubled area ?
>>
>> My application code is (error checking and other code is omitted)
>>
>> #define SHM_BASE 0x1C000000
>> #define SHM_SIZE 0x400000 // 4 MB of Shared Memory
>> #define PAGE_SIZE (4*1024)
>>
>> fd = open(device, O_RDWR);
>
> You may need to add with 'O_SYNC'.
>
> Tiejun
>
>> shm = malloc(SHM_SIZE + (PAGE_SIZE - 1)); if ( (unsigned long) shm %
>> PAGE_SIZE) {
>> shm += PAGE_SIZE - ((unsigned long)shm % PAGE_SIZE); }
>>
>> shm = mmap(shm, SHM_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED |
>> MAP_FIXED, fd, SHM_BASE); ......
>> ...... write some string at shm.
>>
>> My memory partitioning for both systems is
>>
>> Core Base Address Size
>> Core 0 0x0000,0000 0x1000,0000
>> Core 1 0x1000,0000 0x0C00,0000
>> Shared Memory 0x1C00,0000 0x0400,0000
>>
>> Regards,
>> Farrukh Arshad.
>> Mentor Graphics Pakistan
>
^ permalink raw reply
* RTC on 2.6.36 for PowerMac 8600
From: kevin diggs @ 2012-01-29 3:08 UTC (permalink / raw)
To: Linux PPC Development
Hi,
What will give me access to the RTC hardware on an old PowerMac 8600?
I modload rtc-generic. /proc/devices has:
254 rtc
and ls -l /dev/rtc*:
crw-r--r-- 2 root root 254, 0 Sep 2 2010 /dev/rtc
crw-r--r-- 2 root root 254, 0 Sep 2 2010 /dev/rtc0
crw-r--r-- 1 root root 10, 135 Aug 10 2004 /dev/rtc.old
Trying to run hwclock gives:
[root@PowerMac8600B root]# hwclock --debug
hwclock from util-linux-2.12pre
Using /dev/rtc interface to clock.
Last drift adjustment done at 1317444443 seconds after 1969
Last calibration done at 1317444443 seconds after 1969
Hardware clock is on local time
Assuming hardware clock is kept in local time.
Waiting for clock tick...
/dev/rtc does not have interrupt functions. Waiting in loop for time
from /dev/rtc to change
RTC_RD_TIME: Invalid argument
ioctl() to /dev/rtc to read the time failed.
I could have sworn this used to work on this system???
What am I forgetting?
gzip -dc /proc/config.gz|grep -i rtc lists:
CONFIG_RTC_LIB=m
CONFIG_RTC_CLASS=m
# RTC interfaces
CONFIG_RTC_INTF_SYSFS=y
CONFIG_RTC_INTF_PROC=y
CONFIG_RTC_INTF_DEV=y
# Platform RTC drivers
CONFIG_RTC_DRV_CMOS=m
# on-CPU RTC drivers
CONFIG_RTC_DRV_GENERIC=m
Thanks!
kevin
^ permalink raw reply
* Re: [PATCH v3 22/25] irq_domain/x86: Convert x86 (embedded) to use common irq_domain
From: Grant Likely @ 2012-01-29 0:39 UTC (permalink / raw)
To: Sebastian Andrzej Siewior
Cc: Stephen Rothwell, devicetree-discuss, linux-kernel, Rob Herring,
Milton Miller, Thomas Gleixner, linuxppc-dev, linux-arm-kernel
In-Reply-To: <20120129003550.GA21385@ponder.secretlab.ca>
On Sat, Jan 28, 2012 at 5:35 PM, Grant Likely <grant.likely@secretlab.ca> w=
rote:
> On Sat, Jan 28, 2012 at 05:44:05PM +0100, Sebastian Andrzej Siewior wrote=
:
>> * Grant Likely | 2012-01-27 14:36:16 [-0700]:
>>
>> >This patch removes the x86-specific definition of irq_domain and replac=
es
>> >it with the common implementation.
>>
>> I pulled your devicetree/next tree. After this patch I get:
>>
>> |Hierarchical RCU implementation.
>> |NR_IRQS:2304 nr_irqs:256 16
>> |------------[ cut here ]------------
>> |WARNING: at /home/bigeasy/work/shiva/git/linux-2.6-tip/kernel/irq/irqdo=
main.c:114 irq_domain_add_legacy+0x75/0x150()
>> |Modules linked in:
>> |Pid: 0, comm: swapper/0 Not tainted 3.3.0-rc1+ #65
>> |Call Trace:
>> | [<c15044e0>] ? printk+0x18/0x1a
>> | [<c102cdbd>] warn_slowpath_common+0x6d/0xa0
>> | [<c1095575>] ? irq_domain_add_legacy+0x75/0x150
>> | [<c1095575>] ? irq_domain_add_legacy+0x75/0x150
>> | [<c102ce0d>] warn_slowpath_null+0x1d/0x20
>> | [<c1095575>] irq_domain_add_legacy+0x75/0x150
>> | [<c1714824>] x86_add_irq_domains+0x96/0xd6
>> | [<c1708df2>] init_IRQ+0x8/0x33
>> | [<c170557f>] start_kernel+0x191/0x2e1
>> | [<c170517f>] ? loglevel+0x2b/0x2b
>> | [<c1705081>] i386_start_kernel+0x81/0x86
>> |---[ end trace 4eaa2a86a8e2da22 ]---
>> |------------[ cut here ]------------
>> |kernel BUG at /home/bigeasy/work/shiva/git/linux-2.6-tip/arch/x86/kerne=
l/devicetree.c:367!
>>
>> The warning is comming from this piece in irq_domain_add_legacy()
>> |for (i =3D 0; i < size; i++) {
>> | =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 int irq =3D first_irq + i;
>> | =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct irq_data *irq_data =3D irq_get_=
irq_data(irq);
>> |
>> | =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (WARN_ON(!irq_data || irq_data->dom=
ain)) {
>>
>> irq_data is NULL here.
>>
>> | =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mutex_unlock(&irq_doma=
in_mutex);
>> | =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 of_node_put(domain->of=
_node);
>> | =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 kfree(domain);
>> | =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return NULL;
>> | =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
>> | =A0 =A0 =A0 =A0 }
>> |
>>
>> This is not always the case. arch_early_irq_init() in [0] sets up the
>> first 16 entries. The reminaing few (there is a toal of 24 irqs for
>> first ioapic and a second ioapic) are not initialized. This happens
>> later via ->xlate, ioapic_xlate() =3D> io_apic_setup_irq_pin() =3D>
>> alloc_irq_and_cfg_at() calls irq_set_chip_data() on demand.
>>
>> [0] arch/x86/kernel/apic/io_apic.c
>
> That's not going to work then. =A0The irqs must not be set up in ->xlate.
> They need to be set up either before creating the irq_domain, or in the
> .map hook. =A0Inside the map hook is preferred, but having some
> configured and some not at initialization time does make it difficult
Actually, that's still not right. irq_set_chip_data() (sets
desc->irq_data.chip_data) has nothing to do with irq_get_irq_data()
(which returns desc->irq_data). It's the allocation of the irq_desc
that is at issue here. Where does the allocation occur? (I haven't
dug in to find it yet)
g.
^ permalink raw reply
* Re: [PATCH v3 22/25] irq_domain/x86: Convert x86 (embedded) to use common irq_domain
From: Grant Likely @ 2012-01-29 0:35 UTC (permalink / raw)
To: Sebastian Andrzej Siewior
Cc: Stephen Rothwell, devicetree-discuss, linux-kernel, Rob Herring,
Milton Miller, Thomas Gleixner, linuxppc-dev, linux-arm-kernel
In-Reply-To: <20120128164405.GA20763@linutronix.de>
On Sat, Jan 28, 2012 at 05:44:05PM +0100, Sebastian Andrzej Siewior wrote:
> * Grant Likely | 2012-01-27 14:36:16 [-0700]:
>
> >This patch removes the x86-specific definition of irq_domain and replaces
> >it with the common implementation.
>
> I pulled your devicetree/next tree. After this patch I get:
>
> |Hierarchical RCU implementation.
> |NR_IRQS:2304 nr_irqs:256 16
> |------------[ cut here ]------------
> |WARNING: at /home/bigeasy/work/shiva/git/linux-2.6-tip/kernel/irq/irqdomain.c:114 irq_domain_add_legacy+0x75/0x150()
> |Modules linked in:
> |Pid: 0, comm: swapper/0 Not tainted 3.3.0-rc1+ #65
> |Call Trace:
> | [<c15044e0>] ? printk+0x18/0x1a
> | [<c102cdbd>] warn_slowpath_common+0x6d/0xa0
> | [<c1095575>] ? irq_domain_add_legacy+0x75/0x150
> | [<c1095575>] ? irq_domain_add_legacy+0x75/0x150
> | [<c102ce0d>] warn_slowpath_null+0x1d/0x20
> | [<c1095575>] irq_domain_add_legacy+0x75/0x150
> | [<c1714824>] x86_add_irq_domains+0x96/0xd6
> | [<c1708df2>] init_IRQ+0x8/0x33
> | [<c170557f>] start_kernel+0x191/0x2e1
> | [<c170517f>] ? loglevel+0x2b/0x2b
> | [<c1705081>] i386_start_kernel+0x81/0x86
> |---[ end trace 4eaa2a86a8e2da22 ]---
> |------------[ cut here ]------------
> |kernel BUG at /home/bigeasy/work/shiva/git/linux-2.6-tip/arch/x86/kernel/devicetree.c:367!
>
> The warning is comming from this piece in irq_domain_add_legacy()
> |for (i = 0; i < size; i++) {
> | int irq = first_irq + i;
> | struct irq_data *irq_data = irq_get_irq_data(irq);
> |
> | if (WARN_ON(!irq_data || irq_data->domain)) {
>
> irq_data is NULL here.
>
> | mutex_unlock(&irq_domain_mutex);
> | of_node_put(domain->of_node);
> | kfree(domain);
> | return NULL;
> | }
> | }
> |
>
> This is not always the case. arch_early_irq_init() in [0] sets up the
> first 16 entries. The reminaing few (there is a toal of 24 irqs for
> first ioapic and a second ioapic) are not initialized. This happens
> later via ->xlate, ioapic_xlate() => io_apic_setup_irq_pin() =>
> alloc_irq_and_cfg_at() calls irq_set_chip_data() on demand.
>
> [0] arch/x86/kernel/apic/io_apic.c
That's not going to work then. The irqs must not be set up in ->xlate.
They need to be set up either before creating the irq_domain, or in the
.map hook. Inside the map hook is preferred, but having some
configured and some not at initialization time does make it difficult
g.
^ permalink raw reply
* Re: [PATCH-RFC 06/10] mips: switch to GENERIC_PCI_IOMAP
From: Kevin Cernekee @ 2012-01-28 22:38 UTC (permalink / raw)
To: Ralf Baechle, Michael S. Tsirkin
Cc: Nicolas Pitre, linux-mips, linux-m68k, linux-ia64, linux-sh,
linux, linux-pci, Jesse Barnes, Chen Liqin, Paul Mackerras,
H. Peter Anvin, sparclinux, Guan Xuetao, Lennox Wu, Jonas Bonn,
Jesper Nilsson, Russell King, linux-hexagon, Helge Deller, x86,
James E.J. Bottomley, Ingo Molnar, Geert Uytterhoeven, linux-arch,
Arend van Spriel, Matt Turner, Fenghua Yu, Lasse Collin,
Arnd Bergmann, Lucas De Marchi, microblaze-uclinux, Paul Bolle,
Rob Herring, Mikael Starvik, Ivan Kokshaysky, Franky Lin,
Thomas Gleixner, Fabio Baltieri, linux-arm-kernel,
Richard Henderson, Michael Ellerman, Michal Simek, Tony Luck,
linux-parisc, linux-cris-kernel, Paul Gortmaker, linux-kernel,
Richard Kuo, Kyle McMartin, Paul Mundt, linux-alpha,
Olof Johansson, Andrew Morton, linuxppc-dev, David S. Miller
In-Reply-To: <66457f7750d7d14229fcf8d0b011aba63185a75d.1322163031.git.mst@redhat.com>
On Thu, Nov 24, 2011 at 12:18 PM, Michael S. Tsirkin <mst@redhat.com> wrote=
:
> mips copied pci_iomap from generic code, probably to avoid
> pulling the rest of iomap.c in. =C2=A0Since that's in
> a separate file now, we can reuse the common implementation.
[snip]
> - =C2=A0 =C2=A0 =C2=A0 if (flags & IORESOURCE_IO)
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return ioport_map_pci(=
dev, start, len);
While investigating a new warning on the 3.3-rc1 MIPS build (unused
static function ioport_map_pci()), I noticed that this patch has shown
up in Linus' tree as commit eab90291d35438bcebf7c3dc85be66d0f24e3002.
I am not completely clear on the implications it has on mapping PCI I/O reg=
ions:
Prior to this change, the MIPS version of pci_iomap() called a
MIPS-specific function, ioport_map_pci(), which tried to use the PCI
controller's io_map_base field to determine the base address of the
PCI I/O space. It also had a fallback mechanism to deal with the case
where io_map_base is unset.
Now, in 3.3-rc1, the generic version of pci_iomap() is used instead.
This code just calls arch/mips/lib/iomap.c:ioport_map() on these
regions. ioport_map() falls through to ioport_map_legacy(), which
always uses mips_io_port_base (not the PCI controller's io_map_base)
as the base address. But on MIPS, it is still permissible to use
different I/O port bases for PCI devices and for legacy (ISA?)
devices.
Is this new behavior desirable, or are there any supported platforms
on which adverse effects might be seen?
As for my part, I don't use PCI I/O regions at all - just memory
regions. I'm more worried about making sure my tree builds with 0
warnings.
If we do want to move ahead with the switch to GENERIC_PCI_IOMAP now,
I have patches to scrap iomap-pci.c entirely and squash the unused
function warning.
If we still want to support the case where io_map_base !=3D
mips_io_port_base, maybe it would be better to revert commit eab90291
for 3.3.
Might also want to take a look at SH since it also appears to have an
orphaned ioport_map_pci() function.
What are your thoughts?
^ permalink raw reply
* Re: [PATCH v3 01/25] irq_domain: add documentation and MAINTAINERS entry.
From: Grant Likely @ 2012-01-28 19:59 UTC (permalink / raw)
To: Randy Dunlap
Cc: Stephen Rothwell, devicetree-discuss, linux-kernel, Rob Herring,
Milton Miller, Thomas Gleixner, linuxppc-dev, linux-arm-kernel
In-Reply-To: <4F243D2C.7040709@xenotime.net>
[-- Attachment #1: Type: text/plain, Size: 382 bytes --]
On Jan 28, 2012 10:25 AM, "Randy Dunlap" <rdunlap@xenotime.net> wrote:
>
> On 01/27/2012 01:35 PM, Grant Likely wrote:
> > Documentation for irq_domain library which will be created in subsequent
> > patches.
>
> I posted a lot of comments to v2 on Jan. 24.
> Looks like they were ignored.
I just hadn't gotten to them. I've made the changes since and they will be
part of v4.
g.
[-- Attachment #2: Type: text/html, Size: 527 bytes --]
^ permalink raw reply
* Re: [PATCH v3 00/25] irq_domain generalization and refinement
From: Grant Likely @ 2012-01-28 19:10 UTC (permalink / raw)
To: Rob Herring
Cc: Stephen Rothwell, devicetree-discuss, linux-kernel, Rob Herring,
Milton Miller, Thomas Gleixner, linuxppc-dev, linux-arm-kernel
In-Reply-To: <4F2440A2.5080601@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 8608 bytes --]
On Jan 28, 2012 11:38 AM, "Rob Herring" <robherring2@gmail.com> wrote:
>
> On 01/27/2012 03:35 PM, Grant Likely wrote:
> > Hey everyone,
> >
> > This patch series is ready for much wider consumption now. I'd like
> > to get it into linux-next ASAP because there will be ARM board support
> > depending on it. I'll wait a few days before I ask Stephen to pull
> > this in.
> >
> > Stephen/Milton/Ben, any testing you can help with here would be
> > appreciated since you've got access to a wider variety of Power
> > machines than I do.
> >
> > Thomas, I think it makes sense to maintain this in a separate branch
> > from other irq changes until the next merge window. If you prefer,
> > I'm happy to maintain this branch until then.
> >
>
> I picked up your irqdomain/next branch and it doesn't compile:
>
> CC kernel/irq/irqdomain.o
> kernel/irq/irqdomain.c: In function ‘irq_create_mapping’:
> kernel/irq/irqdomain.c:403:47: error: ‘irq’ undeclared (first use in
> this function)
> kernel/irq/irqdomain.c:403:47: note: each undeclared identifier is
> reported only once for each function it app
Oops, I had fixed that but didn't refresh the patch. Change the references
in that function from irq to virq, or pop off the top patch to fix.
I'll push out a fixed tree when I get home.
g.
>
> Rob
>
> > Cheers,
> > g.
> >
> > The following changes since commit
dcd6c92267155e70a94b3927bce681ce74b80d1f:
> >
> > Linux 3.3-rc1 (2012-01-19 15:04:48 -0800)
> >
> > are available in the git repository at:
> > git://git.secretlab.ca/git/linux-2.6 irqdomain/next
> >
> > Grant Likely (24):
> > irq_domain: add documentation and MAINTAINERS entry.
> > dt: Make irqdomain less verbose
> > irq_domain: Make irq_domain structure match powerpc's irq_host
> > irq_domain: convert microblaze from irq_host to irq_domain
> > irq_domain/powerpc: Use common irq_domain structure instead of
irq_host
> > irq_domain/powerpc: eliminate irq_map; use irq_alloc_desc()
instead
> > irq_domain/powerpc: Eliminate virq_is_host()
> > irq_domain: Move irq_domain code from powerpc to kernel/irq
> > irqdomain: remove NO_IRQ from irq domain code
> > irq_domain: Remove references to old irq_host names
> > irq_domain: Replace irq_alloc_host() with revmap-specific
initializers
> > irq_domain: Add support for base irq and hwirq in legacy mappings
> > irq_domain: Remove 'new' irq_domain in favour of the ppc one
> > irq_domain: Remove irq_domain_add_simple()
> > irq_domain: Create common xlate functions that device drivers can
use
> > irq_domain: constify irq_domain_ops
> > irq_domain/c6x: constify irq_domain structures
> > irq_domain/c6x: Use library of xlate functions
> > irq_domain/powerpc: constify irq_domain_ops
> > irqdomain/powerpc: Replace custom xlate functions with library
functions
> > irq_domain/x86: Convert x86 (embedded) to use common irq_domain
> > irq_domain: Include hwirq number in /proc/interrupts
> > irq_domain: remove "hint" when allocating irq numbers
> > irq_domain: mostly eliminate slow-path revmap lookups
> >
> > Mark Salter (1):
> > irq_domain/c6x: Convert c6x to use generic irq_domain support.
> >
> > Documentation/IRQ-domain.txt | 113 +++
> > MAINTAINERS | 9 +
> > arch/arm/common/gic.c | 95 ++--
> > arch/arm/common/vic.c | 16 +-
> > arch/arm/include/asm/hardware/gic.h | 4 +-
> > arch/arm/include/asm/hardware/vic.h | 2 +
> > arch/arm/mach-exynos/common.c | 2 +-
> > arch/arm/mach-imx/mach-imx6q.c | 3 +-
> > arch/arm/mach-msm/board-msm8x60.c | 8 +-
> > arch/arm/mach-mx5/imx51-dt.c | 4 +-
> > arch/arm/mach-mx5/imx53-dt.c | 4 +-
> > arch/arm/mach-omap2/board-generic.c | 2 +-
> > arch/arm/mach-prima2/irq.c | 2 +-
> > arch/arm/mach-versatile/core.c | 5 +-
> > arch/c6x/Kconfig | 1 +
> > arch/c6x/include/asm/irq.h | 245 +-------
> > arch/c6x/kernel/irq.c | 612
+----------------
> > arch/c6x/platforms/megamod-pic.c | 25 +-
> > arch/microblaze/include/asm/irq.h | 4 +-
> > arch/microblaze/kernel/irq.c | 2 +-
> > arch/microblaze/kernel/setup.c | 2 -
> > arch/powerpc/Kconfig | 1 +
> > arch/powerpc/include/asm/ehv_pic.h | 2 +-
> > arch/powerpc/include/asm/i8259.h | 2 +-
> > arch/powerpc/include/asm/irq.h | 247 +-------
> > arch/powerpc/include/asm/mpic.h | 2 +-
> > arch/powerpc/include/asm/xics.h | 2 +-
> > arch/powerpc/kernel/irq.c | 617
+----------------
> > arch/powerpc/platforms/512x/mpc5121_ads_cpld.c | 12 +-
> > arch/powerpc/platforms/52xx/media5200.c | 15 +-
> > arch/powerpc/platforms/52xx/mpc52xx_gpt.c | 16 +-
> > arch/powerpc/platforms/52xx/mpc52xx_pic.c | 12 +-
> > arch/powerpc/platforms/82xx/pq2ads-pci-pic.c | 14 +-
> > arch/powerpc/platforms/85xx/socrates_fpga_pic.c | 15 +-
> > arch/powerpc/platforms/86xx/gef_pic.c | 15 +-
> > arch/powerpc/platforms/cell/axon_msi.c | 29 +-
> > arch/powerpc/platforms/cell/beat_interrupt.c | 16 +-
> > arch/powerpc/platforms/cell/interrupt.c | 16 +-
> > arch/powerpc/platforms/cell/spider-pic.c | 14 +-
> > arch/powerpc/platforms/embedded6xx/flipper-pic.c | 30 +-
> > arch/powerpc/platforms/embedded6xx/hlwd-pic.c | 35 +-
> > arch/powerpc/platforms/iseries/irq.c | 11 +-
> > arch/powerpc/platforms/powermac/pic.c | 26 +-
> > arch/powerpc/platforms/powermac/smp.c | 9 +-
> > arch/powerpc/platforms/ps3/interrupt.c | 11 +-
> > arch/powerpc/platforms/wsp/opb_pic.c | 26 +-
> > arch/powerpc/sysdev/cpm1.c | 9 +-
> > arch/powerpc/sysdev/cpm2_pic.c | 23 +-
> > arch/powerpc/sysdev/ehv_pic.c | 14 +-
> > arch/powerpc/sysdev/fsl_msi.c | 10 +-
> > arch/powerpc/sysdev/fsl_msi.h | 2 +-
> > arch/powerpc/sysdev/i8259.c | 15 +-
> > arch/powerpc/sysdev/ipic.c | 31 +-
> > arch/powerpc/sysdev/ipic.h | 2 +-
> > arch/powerpc/sysdev/mpc8xx_pic.c | 11 +-
> > arch/powerpc/sysdev/mpic.c | 17 +-
> > arch/powerpc/sysdev/mpic_msi.c | 2 +-
> > arch/powerpc/sysdev/mv64x60_pic.c | 11 +-
> > arch/powerpc/sysdev/qe_lib/qe_ic.c | 26 +-
> > arch/powerpc/sysdev/qe_lib/qe_ic.h | 2 +-
> > arch/powerpc/sysdev/tsi108_pci.c | 22 +-
> > arch/powerpc/sysdev/uic.c | 26 +-
> > arch/powerpc/sysdev/xics/xics-common.c | 28 +-
> > arch/powerpc/sysdev/xilinx_intc.c | 19 +-
> > arch/x86/Kconfig | 2 +
> > arch/x86/include/asm/irq_controller.h | 12 -
> > arch/x86/include/asm/prom.h | 10 -
> > arch/x86/kernel/devicetree.c | 101 +--
> > drivers/gpio/gpio-mpc8xxx.c | 30 +-
> > drivers/mfd/twl-core.c | 12 +-
> > drivers/net/phy/mdio-gpio.c | 4 +-
> > include/linux/irqdomain.h | 190 ++++--
> > kernel/irq/irqdomain.c | 816
+++++++++++++++++++---
> > kernel/irq/proc.c | 3 +
> > 74 files changed, 1334 insertions(+), 2471 deletions(-)
> > create mode 100644 Documentation/IRQ-domain.txt
> > delete mode 100644 arch/x86/include/asm/irq_controller.h
> >
> > _______________________________________________
> > devicetree-discuss mailing list
> > devicetree-discuss@lists.ozlabs.org
> > https://lists.ozlabs.org/listinfo/devicetree-discuss
>
[-- Attachment #2: Type: text/html, Size: 10383 bytes --]
^ permalink raw reply
* Re: [PATCH v3 00/25] irq_domain generalization and refinement
From: Rob Herring @ 2012-01-28 18:38 UTC (permalink / raw)
To: Grant Likely
Cc: Stephen Rothwell, devicetree-discuss, linux-kernel, Rob Herring,
Milton Miller, Thomas Gleixner, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1327700179-17454-1-git-send-email-grant.likely@secretlab.ca>
On 01/27/2012 03:35 PM, Grant Likely wrote:
> Hey everyone,
>
> This patch series is ready for much wider consumption now. I'd like
> to get it into linux-next ASAP because there will be ARM board support
> depending on it. I'll wait a few days before I ask Stephen to pull
> this in.
>
> Stephen/Milton/Ben, any testing you can help with here would be
> appreciated since you've got access to a wider variety of Power
> machines than I do.
>
> Thomas, I think it makes sense to maintain this in a separate branch
> from other irq changes until the next merge window. If you prefer,
> I'm happy to maintain this branch until then.
>
I picked up your irqdomain/next branch and it doesn't compile:
CC kernel/irq/irqdomain.o
kernel/irq/irqdomain.c: In function ‘irq_create_mapping’:
kernel/irq/irqdomain.c:403:47: error: ‘irq’ undeclared (first use in
this function)
kernel/irq/irqdomain.c:403:47: note: each undeclared identifier is
reported only once for each function it app
Rob
> Cheers,
> g.
>
> The following changes since commit dcd6c92267155e70a94b3927bce681ce74b80d1f:
>
> Linux 3.3-rc1 (2012-01-19 15:04:48 -0800)
>
> are available in the git repository at:
> git://git.secretlab.ca/git/linux-2.6 irqdomain/next
>
> Grant Likely (24):
> irq_domain: add documentation and MAINTAINERS entry.
> dt: Make irqdomain less verbose
> irq_domain: Make irq_domain structure match powerpc's irq_host
> irq_domain: convert microblaze from irq_host to irq_domain
> irq_domain/powerpc: Use common irq_domain structure instead of irq_host
> irq_domain/powerpc: eliminate irq_map; use irq_alloc_desc() instead
> irq_domain/powerpc: Eliminate virq_is_host()
> irq_domain: Move irq_domain code from powerpc to kernel/irq
> irqdomain: remove NO_IRQ from irq domain code
> irq_domain: Remove references to old irq_host names
> irq_domain: Replace irq_alloc_host() with revmap-specific initializers
> irq_domain: Add support for base irq and hwirq in legacy mappings
> irq_domain: Remove 'new' irq_domain in favour of the ppc one
> irq_domain: Remove irq_domain_add_simple()
> irq_domain: Create common xlate functions that device drivers can use
> irq_domain: constify irq_domain_ops
> irq_domain/c6x: constify irq_domain structures
> irq_domain/c6x: Use library of xlate functions
> irq_domain/powerpc: constify irq_domain_ops
> irqdomain/powerpc: Replace custom xlate functions with library functions
> irq_domain/x86: Convert x86 (embedded) to use common irq_domain
> irq_domain: Include hwirq number in /proc/interrupts
> irq_domain: remove "hint" when allocating irq numbers
> irq_domain: mostly eliminate slow-path revmap lookups
>
> Mark Salter (1):
> irq_domain/c6x: Convert c6x to use generic irq_domain support.
>
> Documentation/IRQ-domain.txt | 113 +++
> MAINTAINERS | 9 +
> arch/arm/common/gic.c | 95 ++--
> arch/arm/common/vic.c | 16 +-
> arch/arm/include/asm/hardware/gic.h | 4 +-
> arch/arm/include/asm/hardware/vic.h | 2 +
> arch/arm/mach-exynos/common.c | 2 +-
> arch/arm/mach-imx/mach-imx6q.c | 3 +-
> arch/arm/mach-msm/board-msm8x60.c | 8 +-
> arch/arm/mach-mx5/imx51-dt.c | 4 +-
> arch/arm/mach-mx5/imx53-dt.c | 4 +-
> arch/arm/mach-omap2/board-generic.c | 2 +-
> arch/arm/mach-prima2/irq.c | 2 +-
> arch/arm/mach-versatile/core.c | 5 +-
> arch/c6x/Kconfig | 1 +
> arch/c6x/include/asm/irq.h | 245 +-------
> arch/c6x/kernel/irq.c | 612 +----------------
> arch/c6x/platforms/megamod-pic.c | 25 +-
> arch/microblaze/include/asm/irq.h | 4 +-
> arch/microblaze/kernel/irq.c | 2 +-
> arch/microblaze/kernel/setup.c | 2 -
> arch/powerpc/Kconfig | 1 +
> arch/powerpc/include/asm/ehv_pic.h | 2 +-
> arch/powerpc/include/asm/i8259.h | 2 +-
> arch/powerpc/include/asm/irq.h | 247 +-------
> arch/powerpc/include/asm/mpic.h | 2 +-
> arch/powerpc/include/asm/xics.h | 2 +-
> arch/powerpc/kernel/irq.c | 617 +----------------
> arch/powerpc/platforms/512x/mpc5121_ads_cpld.c | 12 +-
> arch/powerpc/platforms/52xx/media5200.c | 15 +-
> arch/powerpc/platforms/52xx/mpc52xx_gpt.c | 16 +-
> arch/powerpc/platforms/52xx/mpc52xx_pic.c | 12 +-
> arch/powerpc/platforms/82xx/pq2ads-pci-pic.c | 14 +-
> arch/powerpc/platforms/85xx/socrates_fpga_pic.c | 15 +-
> arch/powerpc/platforms/86xx/gef_pic.c | 15 +-
> arch/powerpc/platforms/cell/axon_msi.c | 29 +-
> arch/powerpc/platforms/cell/beat_interrupt.c | 16 +-
> arch/powerpc/platforms/cell/interrupt.c | 16 +-
> arch/powerpc/platforms/cell/spider-pic.c | 14 +-
> arch/powerpc/platforms/embedded6xx/flipper-pic.c | 30 +-
> arch/powerpc/platforms/embedded6xx/hlwd-pic.c | 35 +-
> arch/powerpc/platforms/iseries/irq.c | 11 +-
> arch/powerpc/platforms/powermac/pic.c | 26 +-
> arch/powerpc/platforms/powermac/smp.c | 9 +-
> arch/powerpc/platforms/ps3/interrupt.c | 11 +-
> arch/powerpc/platforms/wsp/opb_pic.c | 26 +-
> arch/powerpc/sysdev/cpm1.c | 9 +-
> arch/powerpc/sysdev/cpm2_pic.c | 23 +-
> arch/powerpc/sysdev/ehv_pic.c | 14 +-
> arch/powerpc/sysdev/fsl_msi.c | 10 +-
> arch/powerpc/sysdev/fsl_msi.h | 2 +-
> arch/powerpc/sysdev/i8259.c | 15 +-
> arch/powerpc/sysdev/ipic.c | 31 +-
> arch/powerpc/sysdev/ipic.h | 2 +-
> arch/powerpc/sysdev/mpc8xx_pic.c | 11 +-
> arch/powerpc/sysdev/mpic.c | 17 +-
> arch/powerpc/sysdev/mpic_msi.c | 2 +-
> arch/powerpc/sysdev/mv64x60_pic.c | 11 +-
> arch/powerpc/sysdev/qe_lib/qe_ic.c | 26 +-
> arch/powerpc/sysdev/qe_lib/qe_ic.h | 2 +-
> arch/powerpc/sysdev/tsi108_pci.c | 22 +-
> arch/powerpc/sysdev/uic.c | 26 +-
> arch/powerpc/sysdev/xics/xics-common.c | 28 +-
> arch/powerpc/sysdev/xilinx_intc.c | 19 +-
> arch/x86/Kconfig | 2 +
> arch/x86/include/asm/irq_controller.h | 12 -
> arch/x86/include/asm/prom.h | 10 -
> arch/x86/kernel/devicetree.c | 101 +--
> drivers/gpio/gpio-mpc8xxx.c | 30 +-
> drivers/mfd/twl-core.c | 12 +-
> drivers/net/phy/mdio-gpio.c | 4 +-
> include/linux/irqdomain.h | 190 ++++--
> kernel/irq/irqdomain.c | 816 +++++++++++++++++++---
> kernel/irq/proc.c | 3 +
> 74 files changed, 1334 insertions(+), 2471 deletions(-)
> create mode 100644 Documentation/IRQ-domain.txt
> delete mode 100644 arch/x86/include/asm/irq_controller.h
>
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
^ permalink raw reply
* Re: [PATCH v3 01/25] irq_domain: add documentation and MAINTAINERS entry.
From: Randy Dunlap @ 2012-01-28 18:23 UTC (permalink / raw)
To: Grant Likely
Cc: Stephen Rothwell, devicetree-discuss, linux-kernel, Rob Herring,
Milton Miller, Thomas Gleixner, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1327700179-17454-2-git-send-email-grant.likely@secretlab.ca>
On 01/27/2012 01:35 PM, Grant Likely wrote:
> Documentation for irq_domain library which will be created in subsequent
> patches.
I posted a lot of comments to v2 on Jan. 24.
Looks like they were ignored.
Please see http://marc.info/?l=linuxppc-embedded&m=132742951211808&w=2
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Rob Herring <rob.herring@calxeda.com>
> Cc: Milton Miller <miltonm@bga.com>
> ---
> Documentation/IRQ-domain.txt | 113 ++++++++++++++++++++++++++++++++++++++++++
> MAINTAINERS | 9 +++
> 2 files changed, 122 insertions(+), 0 deletions(-)
> create mode 100644 Documentation/IRQ-domain.txt
--
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
^ permalink raw reply
* Re: [PATCH v3 22/25] irq_domain/x86: Convert x86 (embedded) to use common irq_domain
From: Sebastian Andrzej Siewior @ 2012-01-28 16:44 UTC (permalink / raw)
To: Grant Likely
Cc: Stephen Rothwell, devicetree-discuss, linux-kernel, Rob Herring,
Milton Miller, Thomas Gleixner, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1327700179-17454-23-git-send-email-grant.likely@secretlab.ca>
* Grant Likely | 2012-01-27 14:36:16 [-0700]:
>This patch removes the x86-specific definition of irq_domain and replaces
>it with the common implementation.
I pulled your devicetree/next tree. After this patch I get:
|Hierarchical RCU implementation.
|NR_IRQS:2304 nr_irqs:256 16
|------------[ cut here ]------------
|WARNING: at /home/bigeasy/work/shiva/git/linux-2.6-tip/kernel/irq/irqdomain.c:114 irq_domain_add_legacy+0x75/0x150()
|Modules linked in:
|Pid: 0, comm: swapper/0 Not tainted 3.3.0-rc1+ #65
|Call Trace:
| [<c15044e0>] ? printk+0x18/0x1a
| [<c102cdbd>] warn_slowpath_common+0x6d/0xa0
| [<c1095575>] ? irq_domain_add_legacy+0x75/0x150
| [<c1095575>] ? irq_domain_add_legacy+0x75/0x150
| [<c102ce0d>] warn_slowpath_null+0x1d/0x20
| [<c1095575>] irq_domain_add_legacy+0x75/0x150
| [<c1714824>] x86_add_irq_domains+0x96/0xd6
| [<c1708df2>] init_IRQ+0x8/0x33
| [<c170557f>] start_kernel+0x191/0x2e1
| [<c170517f>] ? loglevel+0x2b/0x2b
| [<c1705081>] i386_start_kernel+0x81/0x86
|---[ end trace 4eaa2a86a8e2da22 ]---
|------------[ cut here ]------------
|kernel BUG at /home/bigeasy/work/shiva/git/linux-2.6-tip/arch/x86/kernel/devicetree.c:367!
The warning is comming from this piece in irq_domain_add_legacy()
|for (i = 0; i < size; i++) {
| int irq = first_irq + i;
| struct irq_data *irq_data = irq_get_irq_data(irq);
|
| if (WARN_ON(!irq_data || irq_data->domain)) {
irq_data is NULL here.
| mutex_unlock(&irq_domain_mutex);
| of_node_put(domain->of_node);
| kfree(domain);
| return NULL;
| }
| }
|
This is not always the case. arch_early_irq_init() in [0] sets up the
first 16 entries. The reminaing few (there is a toal of 24 irqs for
first ioapic and a second ioapic) are not initialized. This happens
later via ->xlate, ioapic_xlate() => io_apic_setup_irq_pin() =>
alloc_irq_and_cfg_at() calls irq_set_chip_data() on demand.
[0] arch/x86/kernel/apic/io_apic.c
Sebastian
^ permalink raw reply
* Re: [RFCv2 01/14] irq_domain: add documentation and MAINTAINERS entry.
From: Grant Likely @ 2012-01-28 17:05 UTC (permalink / raw)
To: Randy Dunlap
Cc: devicetree-discuss, linux-kernel, Milton Miller, Rob Herring,
Thomas Gleixner, linuxppc-dev
In-Reply-To: <4F1F02E5.3000605@xenotime.net>
On Tue, Jan 24, 2012 at 11:13:41AM -0800, Randy Dunlap wrote:
> On 01/23/2012 01:07 PM, Grant Likely wrote:
> > Documentation for irq_domain library which will be created in subsequent
> > patches.
> >
> > Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > ---
> > Documentation/IRQ-domain.txt | 113 ++++++++++++++++++++++++++++++++++++++++++
> > MAINTAINERS | 9 +++
> > 2 files changed, 122 insertions(+), 0 deletions(-)
> > create mode 100644 Documentation/IRQ-domain.txt
> >
> > diff --git a/Documentation/IRQ-domain.txt b/Documentation/IRQ-domain.txt
> > new file mode 100644
> > index 0000000..247f32a
> > --- /dev/null
> > +++ b/Documentation/IRQ-domain.txt
> > @@ -0,0 +1,113 @@
> > +irq_domain interrupt number mapping library
> > +
> > +The current design of the Linux kernel uses a single large number
> > +space where each separate IRQ source is assigned a different number.
> > +This is simple when there is only one interrupt controller, but in
> > +systems with controllers the kernel must ensure that each one does not
>
> with multiple interrupt controllers,
Hi Randy. Thanks for the comments. I've made the changes and they'll appear
in v4 of the series.
g.
^ permalink raw reply
* [PATCH 06/13] PCI, powerpc: Register busn_res for root buses
From: Yinghai Lu @ 2012-01-28 2:49 UTC (permalink / raw)
To: Jesse Barnes, Benjamin Herrenschmidt, Tony Luck
Cc: linux-arch, linux-pci, linuxppc-dev, linux-kernel, Linus Torvalds,
Paul Mackerras, Bjorn Helgaas, Yinghai Lu
In-Reply-To: <1327718971-9598-1-git-send-email-yinghai@kernel.org>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
---
arch/powerpc/kernel/pci-common.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index cce98d7..501f29b 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1732,6 +1732,8 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose)
bus->secondary = hose->first_busno;
hose->bus = bus;
+ pci_bus_insert_busn_res(bus, hose->first_busno, hose->last_busno);
+
/* Get probe mode and perform scan */
mode = PCI_PROBE_NORMAL;
if (node && ppc_md.pci_probe_mode)
@@ -1742,8 +1744,11 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose)
of_scan_bus(node, bus);
}
- if (mode == PCI_PROBE_NORMAL)
+ if (mode == PCI_PROBE_NORMAL) {
+ pci_bus_update_busn_res_end(bus, 255);
hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
+ pci_bus_update_busn_res_end(bus, bus->subordinate);
+ }
/* Platform gets a chance to do some global fixups before
* we proceed to resource allocation
--
1.7.7
^ permalink raw reply related
* Re: [RFCv2 00/14]
From: Grant Likely @ 2012-01-27 22:13 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Cousson, Benoit, devicetree-discuss, linux-kernel, Milton Miller,
Rob Herring, Shawn Guo, linuxppc-dev
In-Reply-To: <1327702113.24487.19.camel@pasglop>
On Fri, Jan 27, 2012 at 3:08 PM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Thu, 2012-01-26 at 14:33 -0700, Grant Likely wrote:
>
>> I've got the x86 fix in my tree now. =A0It will be part of the next
>> merge. =A0MIPS, Microblaze and OpenRISC cannot turn on CONFIG_IRQ_DOMAIN
>> without rework. =A0I just hacked together the microblaze version, but
>> Michal will have to verify that it is correct. =A0I just posted it. =A0I=
t
>> will be similar for the other two.
>>
>> The real problem is sparc which does something entirely different for
>> irqs. =A0Rather than resolving irqs on-demand, it calculates the Linux
>> irq numbers at boot time for every node in the tree. =A0The irq_domains
>> will need to be set up for all interrupt controllers before sparc
>> begins it's big walk of the tree to resolve interrupts. =A0I haven't dug
>> into everything that needs to be done to support this.
>>
>> I don't think you can count on turning on IRQ_DOMAIN on all
>> architectures just yet. =A0Adding irq_domain support directly to
>> irq_generic_chip is going to be difficult for that reason. =A0However,
>> it would be useful to have an irq_domain+irq_generic_chip wrapper that
>> can be enabled only when IRQ_DOMAIN is enabled.
>
> Beware also that there are plenty of cases where 1 irq domain !=3D 1 irq
> chip, for example on cell or xics where a single domain can encompass
> multiple chips. I don't know whether x86 APICs are the same, they could
> be tho :-)
Right, there will be some controllers using multiple irq_generic_chip
instances for a single irq_domain. Anything with banks of irq
registers is a candidate here.
g.
^ permalink raw reply
* Re: [RFCv2 00/14]
From: Benjamin Herrenschmidt @ 2012-01-27 22:08 UTC (permalink / raw)
To: Grant Likely
Cc: Cousson, Benoit, devicetree-discuss, linux-kernel, Milton Miller,
Rob Herring, Shawn Guo, linuxppc-dev
In-Reply-To: <CACxGe6vA6CSCAU82uuMaycqDBt+JG3KvXzAURDWQ0Deyeg13Ow@mail.gmail.com>
On Thu, 2012-01-26 at 14:33 -0700, Grant Likely wrote:
> I've got the x86 fix in my tree now. It will be part of the next
> merge. MIPS, Microblaze and OpenRISC cannot turn on CONFIG_IRQ_DOMAIN
> without rework. I just hacked together the microblaze version, but
> Michal will have to verify that it is correct. I just posted it. It
> will be similar for the other two.
>
> The real problem is sparc which does something entirely different for
> irqs. Rather than resolving irqs on-demand, it calculates the Linux
> irq numbers at boot time for every node in the tree. The irq_domains
> will need to be set up for all interrupt controllers before sparc
> begins it's big walk of the tree to resolve interrupts. I haven't dug
> into everything that needs to be done to support this.
>
> I don't think you can count on turning on IRQ_DOMAIN on all
> architectures just yet. Adding irq_domain support directly to
> irq_generic_chip is going to be difficult for that reason. However,
> it would be useful to have an irq_domain+irq_generic_chip wrapper that
> can be enabled only when IRQ_DOMAIN is enabled.
Beware also that there are plenty of cases where 1 irq domain != 1 irq
chip, for example on cell or xics where a single domain can encompass
multiple chips. I don't know whether x86 APICs are the same, they could
be tho :-)
Cheers,
Ben.
^ permalink raw reply
* [PATCH v3 25/25] irq_domain: mostly eliminate slow-path revmap lookups
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
Milton Miller, Rob Herring, Stephen Rothwell
Cc: devicetree-discuss, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1327700179-17454-1-git-send-email-grant.likely@secretlab.ca>
With the current state of irq_domain, the reverse map is always used when
new IRQs get mapped. This means that the irq_find_mapping() function
can be simplified to always call out to the revmap-specific lookup function.
This patch adds lookup functions for the revmaps that don't yet have one
and removes the slow path lookup from most of the code paths. The only
place where the slow path legitimately remains is when the linear map
is used with a hwirq number larger than the revmap size.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>
---
arch/powerpc/sysdev/xics/xics-common.c | 3 -
include/linux/irqdomain.h | 3 +-
kernel/irq/irqdomain.c | 94 +++++++++++++++++---------------
3 files changed, 51 insertions(+), 49 deletions(-)
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
index ea5e204..1d7067d 100644
--- a/arch/powerpc/sysdev/xics/xics-common.c
+++ b/arch/powerpc/sysdev/xics/xics-common.c
@@ -330,9 +330,6 @@ static int xics_host_map(struct irq_domain *h, unsigned int virq,
pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hw);
- /* Insert the interrupt mapping into the radix tree for fast lookup */
- irq_radix_revmap_insert(xics_host, virq, hw);
-
/* They aren't all level sensitive but we just don't really know */
irq_set_status_flags(virq, IRQ_LEVEL);
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 0b00f83..38314f2 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -93,6 +93,7 @@ struct irq_domain {
struct list_head link;
/* type of reverse mapping_technique */
+ unsigned int (*revmap)(struct irq_domain *host, irq_hw_number_t hwirq);
unsigned int revmap_type;
union {
struct {
@@ -155,8 +156,6 @@ extern void irq_dispose_mapping(unsigned int virq);
extern unsigned int irq_find_mapping(struct irq_domain *host,
irq_hw_number_t hwirq);
extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
-extern void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq,
- irq_hw_number_t hwirq);
extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
irq_hw_number_t hwirq);
extern unsigned int irq_linear_revmap(struct irq_domain *host,
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 5b4fc4d..91c1cb7 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -104,6 +104,7 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
domain->revmap_data.legacy.first_irq = first_irq;
domain->revmap_data.legacy.first_hwirq = first_hwirq;
domain->revmap_data.legacy.size = size;
+ domain->revmap = irq_domain_legacy_revmap;
mutex_lock(&irq_domain_mutex);
/* Verify that all the irqs are available */
@@ -174,18 +175,35 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
}
domain->revmap_data.linear.size = size;
domain->revmap_data.linear.revmap = revmap;
+ domain->revmap = irq_linear_revmap;
irq_domain_add(domain);
return domain;
}
+static unsigned int irq_domain_nomap_revmap(struct irq_domain *domain,
+ irq_hw_number_t hwirq)
+{
+ struct irq_data *data = irq_get_irq_data(hwirq);
+
+ if (WARN_ON_ONCE(domain->revmap_type != IRQ_DOMAIN_MAP_NOMAP))
+ return irq_find_mapping(domain, hwirq);
+
+ /* Verify that the map has actually been established */
+ if (data && (data->domain == domain) && (data->hwirq == hwirq))
+ return hwirq;
+ return 0;
+}
+
struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
const struct irq_domain_ops *ops,
void *host_data)
{
struct irq_domain *domain = irq_domain_alloc(of_node,
IRQ_DOMAIN_MAP_NOMAP, ops, host_data);
- if (domain)
+ if (domain) {
+ domain->revmap = irq_domain_nomap_revmap;
irq_domain_add(domain);
+ }
return domain;
}
@@ -205,6 +223,7 @@ struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
IRQ_DOMAIN_MAP_TREE, ops, host_data);
if (domain) {
INIT_RADIX_TREE(&domain->revmap_data.tree, GFP_KERNEL);
+ domain->revmap = irq_radix_revmap_lookup;
irq_domain_add(domain);
}
return domain;
@@ -378,6 +397,19 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
return 0;
}
+ switch(domain->revmap_type) {
+ case IRQ_DOMAIN_MAP_LINEAR:
+ if (hwirq < domain->revmap_data.linear.size)
+ domain->revmap_data.linear.revmap[hwirq] = irq;
+ break;
+ case IRQ_DOMAIN_MAP_TREE:
+ mutex_lock(&revmap_trees_mutex);
+ radix_tree_insert(&domain->revmap_data.tree, hwirq,
+ irq_get_irq_data(irq));
+ mutex_unlock(&revmap_trees_mutex);
+
+ break;
+ }
pr_debug("irq: irq %lu on domain %s mapped to virtual irq %u\n",
hwirq, domain->of_node ? domain->of_node->full_name : "null", virq);
@@ -478,25 +510,27 @@ EXPORT_SYMBOL_GPL(irq_dispose_mapping);
* irq_find_mapping() - Find a linux irq from an hw irq number.
* @domain: domain owning this hardware interrupt
* @hwirq: hardware irq number in that domain space
- *
- * This is a slow path, for use by generic code. It's expected that an
- * irq controller implementation directly calls the appropriate low level
- * mapping function.
*/
unsigned int irq_find_mapping(struct irq_domain *domain,
irq_hw_number_t hwirq)
{
- unsigned int i;
-
- /* Look for default domain if nececssary */
- if (domain == NULL)
+ if (!domain)
domain = irq_default_domain;
- if (domain == NULL)
- return 0;
+ return domain ? domain->revmap(domain, hwirq) : 0;
+}
+EXPORT_SYMBOL_GPL(irq_find_mapping);
- /* legacy -> bail early */
- if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
- return irq_domain_legacy_revmap(domain, hwirq);
+/**
+ * irq_find_mapping_slow() - slow path for finding the irq mapped to a hwirq
+ *
+ * This is the failsafe slow path for finding an irq mapping. The only time
+ * this will reasonably get called is when the linear map is used with a
+ * hwirq number larger than the size of the reverse map.
+ */
+static unsigned int irq_find_mapping_slow(struct irq_domain *domain,
+ irq_hw_number_t hwirq)
+{
+ int i;
/* Slow path does a linear search of the map */
for (i = 0; i < irq_virq_count; i++) {
@@ -506,7 +540,6 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
}
return 0;
}
-EXPORT_SYMBOL_GPL(irq_find_mapping);
/**
* irq_radix_revmap_lookup() - Find a linux irq from a hw irq number.
@@ -537,31 +570,7 @@ unsigned int irq_radix_revmap_lookup(struct irq_domain *domain,
* Else fallback to linear lookup - this should not happen in practice
* as it means that we failed to insert the node in the radix tree.
*/
- return irq_data ? irq_data->irq : irq_find_mapping(domain, hwirq);
-}
-
-/**
- * irq_radix_revmap_insert() - Insert a hw irq to linux irq number mapping.
- * @domain: domain owning this hardware interrupt
- * @virq: linux irq number
- * @hwirq: hardware irq number in that domain space
- *
- * This is for use by irq controllers that use a radix tree reverse
- * mapping for fast lookup.
- */
-void irq_radix_revmap_insert(struct irq_domain *domain, unsigned int virq,
- irq_hw_number_t hwirq)
-{
- struct irq_data *irq_data = irq_get_irq_data(virq);
-
- if (WARN_ON(domain->revmap_type != IRQ_DOMAIN_MAP_TREE))
- return;
-
- if (virq) {
- mutex_lock(&revmap_trees_mutex);
- radix_tree_insert(&domain->revmap_data.tree, hwirq, irq_data);
- mutex_unlock(&revmap_trees_mutex);
- }
+ return irq_data ? irq_data->irq : irq_find_mapping_slow(domain, hwirq);
}
/**
@@ -585,14 +594,11 @@ unsigned int irq_linear_revmap(struct irq_domain *domain,
if (unlikely(hwirq >= domain->revmap_data.linear.size))
return irq_find_mapping(domain, hwirq);
- /* Check if revmap was allocated */
revmap = domain->revmap_data.linear.revmap;
- if (unlikely(revmap == NULL))
- return irq_find_mapping(domain, hwirq);
/* Fill up revmap with slow path if no mapping found */
if (unlikely(!revmap[hwirq]))
- revmap[hwirq] = irq_find_mapping(domain, hwirq);
+ revmap[hwirq] = irq_find_mapping_slow(domain, hwirq);
return revmap[hwirq];
}
--
1.7.5.4
^ permalink raw reply related
* [PATCH v3 24/25] irq_domain: remove "hint" when allocating irq numbers
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
Milton Miller, Rob Herring, Stephen Rothwell
Cc: devicetree-discuss, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1327700179-17454-1-git-send-email-grant.likely@secretlab.ca>
The 'hint' used to try and line up irq numbers with hw irq numbers is
rather a hack and not very useful. Now that /proc/interrupts also outputs
the hwirq number, it is even less useful to keep around the 'hint' heuristic.
This patch removes it.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>
---
kernel/irq/irqdomain.c | 18 ++++--------------
1 files changed, 4 insertions(+), 14 deletions(-)
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index bf181ef..5b4fc4d 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -339,7 +339,7 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain)
unsigned int irq_create_mapping(struct irq_domain *domain,
irq_hw_number_t hwirq)
{
- unsigned int virq, hint;
+ unsigned int virq;
pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq);
@@ -366,10 +366,7 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
return irq_domain_legacy_revmap(domain, hwirq);
/* Allocate a virtual interrupt number */
- hint = hwirq % irq_virq_count;
- virq = irq_alloc_desc_from(hint, 0);
- if (!virq)
- virq = irq_alloc_desc(0);
+ virq = irq_alloc_desc(0);
if (!virq) {
pr_debug("irq: -> virq allocation failed\n");
return 0;
@@ -490,7 +487,6 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
irq_hw_number_t hwirq)
{
unsigned int i;
- unsigned int hint = hwirq % irq_virq_count;
/* Look for default domain if nececssary */
if (domain == NULL)
@@ -503,17 +499,11 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
return irq_domain_legacy_revmap(domain, hwirq);
/* Slow path does a linear search of the map */
- if (hint < NUM_ISA_INTERRUPTS)
- hint = NUM_ISA_INTERRUPTS;
- i = hint;
- do {
+ for (i = 0; i < irq_virq_count; i++) {
struct irq_data *data = irq_get_irq_data(i);
if (data && (data->domain == domain) && (data->hwirq == hwirq))
return i;
- i++;
- if (i >= irq_virq_count)
- i = NUM_ISA_INTERRUPTS;
- } while(i != hint);
+ }
return 0;
}
EXPORT_SYMBOL_GPL(irq_find_mapping);
--
1.7.5.4
^ permalink raw reply related
* [PATCH v3 23/25] irq_domain: Include hwirq number in /proc/interrupts
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
Milton Miller, Rob Herring, Stephen Rothwell
Cc: devicetree-discuss, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1327700179-17454-1-git-send-email-grant.likely@secretlab.ca>
Add the hardware interrupt number to the output of /proc/interrupts.
It is often important to have access to the hardware interrupt number because
it identifies exactly how an interrupt signal is wired up to the interrupt
controller. This is especially important when using irq_domains since irq
numbers get dynamically allocated in that case, and have no relation to the
actual hardware number.
Note: This output is currently conditional on whether or not the irq_domain
pointer is set; however hwirq could still be used without irq_domain. It
may be worthwhile to always output the hwirq number regardless of the
domain pointer.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/proc.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index 4bd4faa..2ec61d0 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -472,6 +472,9 @@ int show_interrupts(struct seq_file *p, void *v)
if (desc->name)
seq_printf(p, "-%-8s", desc->name);
+ if (desc->irq_data.domain)
+ seq_printf(p, " %-8d", (int) desc->irq_data.hwirq);
+
if (action) {
seq_printf(p, " %s", action->name);
while ((action = action->next) != NULL)
--
1.7.5.4
^ permalink raw reply related
* [PATCH v3 22/25] irq_domain/x86: Convert x86 (embedded) to use common irq_domain
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
Milton Miller, Rob Herring, Stephen Rothwell
Cc: devicetree-discuss, linuxppc-dev, Sebastian Andrzej Siewior,
linux-arm-kernel
In-Reply-To: <1327700179-17454-1-git-send-email-grant.likely@secretlab.ca>
This patch removes the x86-specific definition of irq_domain and replaces
it with the common implementation.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/Kconfig | 2 +
arch/x86/include/asm/irq_controller.h | 12 ----
arch/x86/include/asm/prom.h | 10 ---
arch/x86/kernel/devicetree.c | 101 ++++++++++-----------------------
drivers/net/phy/mdio-gpio.c | 4 +-
5 files changed, 34 insertions(+), 95 deletions(-)
delete mode 100644 arch/x86/include/asm/irq_controller.h
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 864cc6e..5c44039 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -399,6 +399,7 @@ config X86_INTEL_CE
select X86_REBOOTFIXUPS
select OF
select OF_EARLY_FLATTREE
+ select IRQ_DOMAIN
---help---
Select for the Intel CE media processor (CE4100) SOC.
This option compiles in support for the CE4100 SOC for settop
@@ -2077,6 +2078,7 @@ config OLPC
select GPIOLIB
select OF
select OF_PROMTREE
+ select IRQ_DOMAIN
---help---
Add support for detecting the unique features of the OLPC
XO hardware.
diff --git a/arch/x86/include/asm/irq_controller.h b/arch/x86/include/asm/irq_controller.h
deleted file mode 100644
index 423bbbd..0000000
--- a/arch/x86/include/asm/irq_controller.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef __IRQ_CONTROLLER__
-#define __IRQ_CONTROLLER__
-
-struct irq_domain {
- int (*xlate)(struct irq_domain *h, const u32 *intspec, u32 intsize,
- u32 *out_hwirq, u32 *out_type);
- void *priv;
- struct device_node *controller;
- struct list_head l;
-};
-
-#endif
diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
index 644dd885..60bef66 100644
--- a/arch/x86/include/asm/prom.h
+++ b/arch/x86/include/asm/prom.h
@@ -21,7 +21,6 @@
#include <asm/irq.h>
#include <linux/atomic.h>
#include <asm/setup.h>
-#include <asm/irq_controller.h>
#ifdef CONFIG_OF
extern int of_ioapic;
@@ -43,15 +42,6 @@ extern char cmd_line[COMMAND_LINE_SIZE];
#define pci_address_to_pio pci_address_to_pio
unsigned long pci_address_to_pio(phys_addr_t addr);
-/**
- * irq_dispose_mapping - Unmap an interrupt
- * @virq: linux virq number of the interrupt to unmap
- *
- * FIXME: We really should implement proper virq handling like power,
- * but that's going to be major surgery.
- */
-static inline void irq_dispose_mapping(unsigned int virq) { }
-
#define HAVE_ARCH_DEVTREE_FIXUPS
#endif /* __ASSEMBLY__ */
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index 5282179..3ae2ced 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -4,6 +4,7 @@
#include <linux/bootmem.h>
#include <linux/export.h>
#include <linux/io.h>
+#include <linux/irqdomain.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/of.h>
@@ -17,64 +18,14 @@
#include <linux/initrd.h>
#include <asm/hpet.h>
-#include <asm/irq_controller.h>
#include <asm/apic.h>
#include <asm/pci_x86.h>
__initdata u64 initial_dtb;
char __initdata cmd_line[COMMAND_LINE_SIZE];
-static LIST_HEAD(irq_domains);
-static DEFINE_RAW_SPINLOCK(big_irq_lock);
int __initdata of_ioapic;
-#ifdef CONFIG_X86_IO_APIC
-static void add_interrupt_host(struct irq_domain *ih)
-{
- unsigned long flags;
-
- raw_spin_lock_irqsave(&big_irq_lock, flags);
- list_add(&ih->l, &irq_domains);
- raw_spin_unlock_irqrestore(&big_irq_lock, flags);
-}
-#endif
-
-static struct irq_domain *get_ih_from_node(struct device_node *controller)
-{
- struct irq_domain *ih, *found = NULL;
- unsigned long flags;
-
- raw_spin_lock_irqsave(&big_irq_lock, flags);
- list_for_each_entry(ih, &irq_domains, l) {
- if (ih->controller == controller) {
- found = ih;
- break;
- }
- }
- raw_spin_unlock_irqrestore(&big_irq_lock, flags);
- return found;
-}
-
-unsigned int irq_create_of_mapping(struct device_node *controller,
- const u32 *intspec, unsigned int intsize)
-{
- struct irq_domain *ih;
- u32 virq, type;
- int ret;
-
- ih = get_ih_from_node(controller);
- if (!ih)
- return 0;
- ret = ih->xlate(ih, intspec, intsize, &virq, &type);
- if (ret)
- return 0;
- if (type == IRQ_TYPE_NONE)
- return virq;
- irq_set_irq_type(virq, type);
- return virq;
-}
-EXPORT_SYMBOL_GPL(irq_create_of_mapping);
-
unsigned long pci_address_to_pio(phys_addr_t address)
{
/*
@@ -354,36 +305,43 @@ static struct of_ioapic_type of_ioapic_type[] =
},
};
-static int ioapic_xlate(struct irq_domain *id, const u32 *intspec, u32 intsize,
- u32 *out_hwirq, u32 *out_type)
+static int ioapic_xlate(struct irq_domain *domain,
+ struct device_node *controller,
+ const u32 *intspec, u32 intsize,
+ irq_hw_number_t *out_hwirq, u32 *out_type)
{
- struct mp_ioapic_gsi *gsi_cfg;
struct io_apic_irq_attr attr;
struct of_ioapic_type *it;
- u32 line, idx, type;
+ u32 line, idx;
+ int rc;
- if (intsize < 2)
+ if (WARN_ON(intsize < 2))
return -EINVAL;
- line = *intspec;
- idx = (u32) id->priv;
- gsi_cfg = mp_ioapic_gsi_routing(idx);
- *out_hwirq = line + gsi_cfg->gsi_base;
-
- intspec++;
- type = *intspec;
+ line = intspec[0];
- if (type >= ARRAY_SIZE(of_ioapic_type))
+ if (intspec[1] >= ARRAY_SIZE(of_ioapic_type))
return -EINVAL;
- it = of_ioapic_type + type;
- *out_type = it->out_type;
+ it = &of_ioapic_type[intspec[1]];
+ idx = (u32) domain->host_data;
set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity);
- return io_apic_setup_irq_pin_once(*out_hwirq, cpu_to_node(0), &attr);
+ rc = io_apic_setup_irq_pin_once(irq_find_mapping(domain, line),
+ cpu_to_node(0), &attr);
+ if (rc)
+ return rc;
+
+ *out_hwirq = line;
+ *out_type = it->out_type;
+ return 0;
}
+const struct irq_domain_ops ioapic_irq_domain_ops = {
+ .xlate = ioapic_xlate,
+};
+
static void __init ioapic_add_ofnode(struct device_node *np)
{
struct resource r;
@@ -399,13 +357,14 @@ static void __init ioapic_add_ofnode(struct device_node *np)
for (i = 0; i < nr_ioapics; i++) {
if (r.start == mpc_ioapic_addr(i)) {
struct irq_domain *id;
+ struct mp_ioapic_gsi *gsi_cfg;
+
+ gsi_cfg = mp_ioapic_gsi_routing(i);
- id = kzalloc(sizeof(*id), GFP_KERNEL);
+ id = irq_domain_add_legacy(np, 32, gsi_cfg->gsi_base, 0,
+ &ioapic_irq_domain_ops,
+ (void*)i);
BUG_ON(!id);
- id->controller = np;
- id->xlate = ioapic_xlate;
- id->priv = (void *)i;
- add_interrupt_host(id);
return;
}
}
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
index 50e8e5e..7189adf 100644
--- a/drivers/net/phy/mdio-gpio.c
+++ b/drivers/net/phy/mdio-gpio.c
@@ -255,13 +255,13 @@ static inline int __init mdio_ofgpio_init(void)
return platform_driver_register(&mdio_ofgpio_driver);
}
-static inline void __exit mdio_ofgpio_exit(void)
+static inline void mdio_ofgpio_exit(void)
{
platform_driver_unregister(&mdio_ofgpio_driver);
}
#else
static inline int __init mdio_ofgpio_init(void) { return 0; }
-static inline void __exit mdio_ofgpio_exit(void) { }
+static inline void mdio_ofgpio_exit(void) { }
#endif /* CONFIG_OF_GPIO */
static struct platform_driver mdio_gpio_driver = {
--
1.7.5.4
^ permalink raw reply related
* [PATCH v3 21/25] irqdomain/powerpc: Replace custom xlate functions with library functions
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
Milton Miller, Rob Herring, Stephen Rothwell
Cc: devicetree-discuss, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1327700179-17454-1-git-send-email-grant.likely@secretlab.ca>
This patch converts a number of the powerpc drivers to use the common library
of irq_domain xlate functions, dropping a bunch of lines in the process.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>
---
arch/powerpc/platforms/powermac/pic.c | 13 +------------
arch/powerpc/platforms/wsp/opb_pic.c | 13 +------------
arch/powerpc/sysdev/cpm2_pic.c | 14 +-------------
arch/powerpc/sysdev/ipic.c | 18 +-----------------
arch/powerpc/sysdev/qe_lib/qe_ic.c | 15 +--------------
arch/powerpc/sysdev/tsi108_pci.c | 11 +----------
arch/powerpc/sysdev/uic.c | 14 +-------------
drivers/gpio/gpio-mpc8xxx.c | 17 +----------------
8 files changed, 8 insertions(+), 107 deletions(-)
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 46a5f32..3af29d1 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -288,21 +288,10 @@ static int pmac_pic_host_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static int pmac_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
- const u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq,
- unsigned int *out_flags)
-
-{
- *out_flags = IRQ_TYPE_NONE;
- *out_hwirq = *intspec;
- return 0;
-}
-
static const struct irq_domain_ops pmac_pic_host_ops = {
.match = pmac_pic_host_match,
.map = pmac_pic_host_map,
- .xlate = pmac_pic_host_xlate,
+ .xlate = irq_domain_xlate_onecell;
};
static void __init pmac_pic_probe_oldstyle(void)
diff --git a/arch/powerpc/platforms/wsp/opb_pic.c b/arch/powerpc/platforms/wsp/opb_pic.c
index 0c6fe0b..cb565bf 100644
--- a/arch/powerpc/platforms/wsp/opb_pic.c
+++ b/arch/powerpc/platforms/wsp/opb_pic.c
@@ -196,20 +196,9 @@ static int opb_host_map(struct irq_domain *host, unsigned int virq,
return 0;
}
-static int opb_host_xlate(struct irq_domain *host, struct device_node *dn,
- const u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq, unsigned int *out_type)
-{
- /* Interrupt size must == 2 */
- BUG_ON(intsize != 2);
- *out_hwirq = intspec[0];
- *out_type = intspec[1];
- return 0;
-}
-
static const struct irq_domain_ops opb_host_ops = {
.map = opb_host_map,
- .xlate = opb_host_xlate,
+ .xlate = irq_domain_xlate_twocell,
};
irqreturn_t opb_irq_handler(int irq, void *private)
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
index 8c9fc9c..d3be961 100644
--- a/arch/powerpc/sysdev/cpm2_pic.c
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -224,21 +224,9 @@ static int cpm2_pic_host_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static int cpm2_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
- const u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq, unsigned int *out_flags)
-{
- *out_hwirq = intspec[0];
- if (intsize > 1)
- *out_flags = intspec[1];
- else
- *out_flags = IRQ_TYPE_NONE;
- return 0;
-}
-
static const struct irq_domain_ops cpm2_pic_host_ops = {
.map = cpm2_pic_host_map,
- .xlate = cpm2_pic_host_xlate,
+ .xlate = irq_domain_xlate_onetwocell,
};
void cpm2_pic_init(struct device_node *node)
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 0eaaa01..b50f978 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -692,26 +692,10 @@ static int ipic_host_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static int ipic_host_xlate(struct irq_domain *h, struct device_node *ct,
- const u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq, unsigned int *out_flags)
-
-{
- /* interrupt sense values coming from the device tree equal either
- * LEVEL_LOW (low assertion) or EDGE_FALLING (high-to-low change)
- */
- *out_hwirq = intspec[0];
- if (intsize > 1)
- *out_flags = intspec[1];
- else
- *out_flags = IRQ_TYPE_NONE;
- return 0;
-}
-
static struct irq_domain_ops ipic_host_ops = {
.match = ipic_host_match,
.map = ipic_host_map,
- .xlate = ipic_host_xlate,
+ .xlate = irq_domain_xlate_onetwocell,
};
struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index e9b3d5c..2fba6ef 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -272,23 +272,10 @@ static int qe_ic_host_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static int qe_ic_host_xlate(struct irq_domain *h, struct device_node *ct,
- const u32 * intspec, unsigned int intsize,
- irq_hw_number_t * out_hwirq,
- unsigned int *out_flags)
-{
- *out_hwirq = intspec[0];
- if (intsize > 1)
- *out_flags = intspec[1];
- else
- *out_flags = IRQ_TYPE_NONE;
- return 0;
-}
-
static struct irq_domain_ops qe_ic_host_ops = {
.match = qe_ic_host_match,
.map = qe_ic_host_map,
- .xlate = qe_ic_host_xlate,
+ .xlate = irq_domain_xlate_onetwocell,
};
/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 188012c..470c1ef 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -376,15 +376,6 @@ static struct irq_chip tsi108_pci_irq = {
.irq_unmask = tsi108_pci_irq_unmask,
};
-static int pci_irq_host_xlate(struct irq_domain *h, struct device_node *ct,
- const u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq, unsigned int *out_flags)
-{
- *out_hwirq = intspec[0];
- *out_flags = IRQ_TYPE_LEVEL_HIGH;
- return 0;
-}
-
static int pci_irq_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{ unsigned int irq;
@@ -399,7 +390,7 @@ static int pci_irq_host_map(struct irq_domain *h, unsigned int virq,
static struct irq_domain_ops pci_irq_domain_ops = {
.map = pci_irq_host_map,
- .xlate = pci_irq_host_xlate,
+ .xlate = irq_domain_xlate_pci,
};
/*
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
index 84e59c9..9203393 100644
--- a/arch/powerpc/sysdev/uic.c
+++ b/arch/powerpc/sysdev/uic.c
@@ -190,21 +190,9 @@ static int uic_host_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static int uic_host_xlate(struct irq_domain *h, struct device_node *ct,
- const u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq, unsigned int *out_type)
-
-{
- /* UIC intspecs must have 2 cells */
- BUG_ON(intsize != 2);
- *out_hwirq = intspec[0];
- *out_type = intspec[1];
- return 0;
-}
-
static struct irq_domain_ops uic_host_ops = {
.map = uic_host_map,
- .xlate = uic_host_xlate,
+ .xlate = irq_domain_xlate_twocell,
};
void uic_irq_cascade(unsigned int virq, struct irq_desc *desc)
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
index 149d987..e6568c1 100644
--- a/drivers/gpio/gpio-mpc8xxx.c
+++ b/drivers/gpio/gpio-mpc8xxx.c
@@ -296,24 +296,9 @@ static int mpc8xxx_gpio_irq_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static int mpc8xxx_gpio_irq_xlate(struct irq_domain *h, struct device_node *ct,
- const u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq,
- unsigned int *out_flags)
-
-{
- /* interrupt sense values coming from the device tree equal either
- * EDGE_FALLING or EDGE_BOTH
- */
- *out_hwirq = intspec[0];
- *out_flags = intspec[1];
-
- return 0;
-}
-
static struct irq_domain_ops mpc8xxx_gpio_irq_ops = {
.map = mpc8xxx_gpio_irq_map,
- .xlate = mpc8xxx_gpio_irq_xlate,
+ .xlate = irq_domain_xlate_twocell,
};
static struct of_device_id mpc8xxx_gpio_ids[] __initdata = {
--
1.7.5.4
^ permalink raw reply related
* [PATCH v3 20/25] irq_domain/powerpc: constify irq_domain_ops
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
Milton Miller, Rob Herring, Stephen Rothwell
Cc: devicetree-discuss, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1327700179-17454-1-git-send-email-grant.likely@secretlab.ca>
Make all the irq_domain_ops structures in powerpc 'static const'
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>
---
arch/powerpc/platforms/512x/mpc5121_ads_cpld.c | 2 +-
arch/powerpc/platforms/52xx/media5200.c | 2 +-
arch/powerpc/platforms/52xx/mpc52xx_gpt.c | 2 +-
arch/powerpc/platforms/52xx/mpc52xx_pic.c | 2 +-
arch/powerpc/platforms/82xx/pq2ads-pci-pic.c | 2 +-
arch/powerpc/platforms/85xx/socrates_fpga_pic.c | 2 +-
arch/powerpc/platforms/86xx/gef_pic.c | 2 +-
arch/powerpc/platforms/cell/axon_msi.c | 2 +-
arch/powerpc/platforms/cell/beat_interrupt.c | 2 +-
arch/powerpc/platforms/cell/interrupt.c | 2 +-
arch/powerpc/platforms/cell/spider-pic.c | 2 +-
arch/powerpc/platforms/embedded6xx/flipper-pic.c | 2 +-
arch/powerpc/platforms/embedded6xx/hlwd-pic.c | 2 +-
arch/powerpc/platforms/iseries/irq.c | 2 +-
arch/powerpc/platforms/powermac/pic.c | 2 +-
arch/powerpc/platforms/powermac/smp.c | 2 +-
arch/powerpc/platforms/ps3/interrupt.c | 2 +-
arch/powerpc/platforms/wsp/opb_pic.c | 2 +-
arch/powerpc/sysdev/cpm1.c | 2 +-
arch/powerpc/sysdev/cpm2_pic.c | 2 +-
arch/powerpc/sysdev/ehv_pic.c | 2 +-
arch/powerpc/sysdev/fsl_msi.c | 2 +-
22 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
index 291d61c..ca3a062 100644
--- a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
+++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
@@ -137,7 +137,7 @@ cpld_pic_host_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static struct irq_domain_ops cpld_pic_host_ops = {
+static const struct irq_domain_ops cpld_pic_host_ops = {
.match = cpld_pic_host_match,
.map = cpld_pic_host_map,
};
diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c
index 5db5cfb..17d91b7 100644
--- a/arch/powerpc/platforms/52xx/media5200.c
+++ b/arch/powerpc/platforms/52xx/media5200.c
@@ -136,7 +136,7 @@ static int media5200_irq_xlate(struct irq_domain *h, struct device_node *ct,
return 0;
}
-static struct irq_domain_ops media5200_irq_ops = {
+static const struct irq_domain_ops media5200_irq_ops = {
.map = media5200_irq_map,
.xlate = media5200_irq_xlate,
};
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index b53275d..028470b 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -236,7 +236,7 @@ static int mpc52xx_gpt_irq_xlate(struct irq_domain *h, struct device_node *ct,
return 0;
}
-static struct irq_domain_ops mpc52xx_gpt_irq_ops = {
+static const struct irq_domain_ops mpc52xx_gpt_irq_ops = {
.map = mpc52xx_gpt_irq_map,
.xlate = mpc52xx_gpt_irq_xlate,
};
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 41fa671..8520b58 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -384,7 +384,7 @@ static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static struct irq_domain_ops mpc52xx_irqhost_ops = {
+static const struct irq_domain_ops mpc52xx_irqhost_ops = {
.xlate = mpc52xx_irqhost_xlate,
.map = mpc52xx_irqhost_map,
};
diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
index 4ef9d69..328d221 100644
--- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
+++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
@@ -112,7 +112,7 @@ static int pci_pic_host_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static struct irq_domain_ops pci_pic_host_ops = {
+static const struct irq_domain_ops pci_pic_host_ops = {
.map = pci_pic_host_map,
};
diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
index 1092c12..3bbbf74 100644
--- a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
+++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
@@ -269,7 +269,7 @@ static int socrates_fpga_pic_host_xlate(struct irq_domain *h,
return 0;
}
-static struct irq_domain_ops socrates_fpga_pic_host_ops = {
+static const struct irq_domain_ops socrates_fpga_pic_host_ops = {
.map = socrates_fpga_pic_host_map,
.xlate = socrates_fpga_pic_host_xlate,
};
diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c
index 126a94b..af3fd69 100644
--- a/arch/powerpc/platforms/86xx/gef_pic.c
+++ b/arch/powerpc/platforms/86xx/gef_pic.c
@@ -177,7 +177,7 @@ static int gef_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
return 0;
}
-static struct irq_domain_ops gef_pic_host_ops = {
+static const struct irq_domain_ops gef_pic_host_ops = {
.map = gef_pic_host_map,
.xlate = gef_pic_host_xlate,
};
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index cf9fd3c..db360fc 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -327,7 +327,7 @@ static int msic_host_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static struct irq_domain_ops msic_host_ops = {
+static const struct irq_domain_ops msic_host_ops = {
.map = msic_host_map,
};
diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c
index bbdf574..e5c3a2c 100644
--- a/arch/powerpc/platforms/cell/beat_interrupt.c
+++ b/arch/powerpc/platforms/cell/beat_interrupt.c
@@ -172,7 +172,7 @@ static int beatic_pic_host_match(struct irq_domain *h, struct device_node *np)
return 1;
}
-static struct irq_domain_ops beatic_pic_host_ops = {
+static const struct irq_domain_ops beatic_pic_host_ops = {
.map = beatic_pic_host_map,
.unmap = beatic_pic_host_unmap,
.xlate = beatic_pic_host_xlate,
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index c844797..2d42f3b 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -285,7 +285,7 @@ static int iic_host_xlate(struct irq_domain *h, struct device_node *ct,
return 0;
}
-static struct irq_domain_ops iic_host_ops = {
+static const struct irq_domain_ops iic_host_ops = {
.match = iic_host_match,
.map = iic_host_map,
.xlate = iic_host_xlate,
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 6521d20..d8b7cc8 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -194,7 +194,7 @@ static int spider_host_xlate(struct irq_domain *h, struct device_node *ct,
return 0;
}
-static struct irq_domain_ops spider_host_ops = {
+static const struct irq_domain_ops spider_host_ops = {
.map = spider_host_map,
.xlate = spider_host_xlate,
};
diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
index 4345971..675335a 100644
--- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
@@ -113,7 +113,7 @@ static int flipper_pic_match(struct irq_domain *h, struct device_node *np)
}
-static struct irq_domain_ops flipper_irq_domain_ops = {
+static const struct irq_domain_ops flipper_irq_domain_ops = {
.map = flipper_pic_map,
.match = flipper_pic_match,
};
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
index 499d410..da6ca02 100644
--- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
@@ -100,7 +100,7 @@ static int hlwd_pic_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static struct irq_domain_ops hlwd_irq_domain_ops = {
+static const struct irq_domain_ops hlwd_irq_domain_ops = {
.map = hlwd_pic_map,
};
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index 5538b59..05ce516 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -356,7 +356,7 @@ static int iseries_irq_host_match(struct irq_domain *h, struct device_node *np)
return 1;
}
-static struct irq_domain_ops iseries_irq_domain_ops = {
+static const struct irq_domain_ops iseries_irq_domain_ops = {
.map = iseries_irq_host_map,
.match = iseries_irq_host_match,
};
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 646fdf3..46a5f32 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -299,7 +299,7 @@ static int pmac_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
return 0;
}
-static struct irq_domain_ops pmac_pic_host_ops = {
+static const struct irq_domain_ops pmac_pic_host_ops = {
.match = pmac_pic_host_match,
.map = pmac_pic_host_map,
.xlate = pmac_pic_host_xlate,
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 09afd70..a81e5a8 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -184,7 +184,7 @@ static int psurge_host_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-struct irq_domain_ops psurge_host_ops = {
+static const struct irq_domain_ops psurge_host_ops = {
.map = psurge_host_map,
};
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index c05808f..2a4ff86 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -684,7 +684,7 @@ static int ps3_host_match(struct irq_domain *h, struct device_node *np)
return 1;
}
-static struct irq_domain_ops ps3_host_ops = {
+static const struct irq_domain_ops ps3_host_ops = {
.map = ps3_host_map,
.match = ps3_host_match,
};
diff --git a/arch/powerpc/platforms/wsp/opb_pic.c b/arch/powerpc/platforms/wsp/opb_pic.c
index 4837515..0c6fe0b 100644
--- a/arch/powerpc/platforms/wsp/opb_pic.c
+++ b/arch/powerpc/platforms/wsp/opb_pic.c
@@ -207,7 +207,7 @@ static int opb_host_xlate(struct irq_domain *host, struct device_node *dn,
return 0;
}
-static struct irq_domain_ops opb_host_ops = {
+static const struct irq_domain_ops opb_host_ops = {
.map = opb_host_map,
.xlate = opb_host_xlate,
};
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
index 53f39db..d4fa03f 100644
--- a/arch/powerpc/sysdev/cpm1.c
+++ b/arch/powerpc/sysdev/cpm1.c
@@ -123,7 +123,7 @@ static struct irqaction cpm_error_irqaction = {
.name = "error",
};
-static struct irq_domain_ops cpm_pic_host_ops = {
+static const struct irq_domain_ops cpm_pic_host_ops = {
.map = cpm_pic_host_map,
};
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
index b364332..8c9fc9c 100644
--- a/arch/powerpc/sysdev/cpm2_pic.c
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -236,7 +236,7 @@ static int cpm2_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
return 0;
}
-static struct irq_domain_ops cpm2_pic_host_ops = {
+static const struct irq_domain_ops cpm2_pic_host_ops = {
.map = cpm2_pic_host_map,
.xlate = cpm2_pic_host_xlate,
};
diff --git a/arch/powerpc/sysdev/ehv_pic.c b/arch/powerpc/sysdev/ehv_pic.c
index adea322..6e0e100 100644
--- a/arch/powerpc/sysdev/ehv_pic.c
+++ b/arch/powerpc/sysdev/ehv_pic.c
@@ -248,7 +248,7 @@ static int ehv_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
return 0;
}
-static struct irq_domain_ops ehv_pic_host_ops = {
+static const struct irq_domain_ops ehv_pic_host_ops = {
.match = ehv_pic_host_match,
.map = ehv_pic_host_map,
.xlate = ehv_pic_host_xlate,
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index f4fd95b..0c01deb 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -74,7 +74,7 @@ static int fsl_msi_host_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static struct irq_domain_ops fsl_msi_host_ops = {
+static const struct irq_domain_ops fsl_msi_host_ops = {
.map = fsl_msi_host_map,
};
--
1.7.5.4
^ permalink raw reply related
* [PATCH v3 19/25] irq_domain/c6x: Use library of xlate functions
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
Milton Miller, Rob Herring, Stephen Rothwell
Cc: devicetree-discuss, linuxppc-dev, linux-arm-kernel, Mark Salter
In-Reply-To: <1327700179-17454-1-git-send-email-grant.likely@secretlab.ca>
The c6x irq controllers don't need to define custom .xlate hooks
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Mark Salter <msalter@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
arch/c6x/kernel/irq.c | 1 +
arch/c6x/platforms/megamod-pic.c | 14 +-------------
2 files changed, 2 insertions(+), 13 deletions(-)
diff --git a/arch/c6x/kernel/irq.c b/arch/c6x/kernel/irq.c
index c6b36e8..d77bcfd 100644
--- a/arch/c6x/kernel/irq.c
+++ b/arch/c6x/kernel/irq.c
@@ -88,6 +88,7 @@ static int core_domain_map(struct irq_domain *h, unsigned int virq,
static const struct irq_domain_ops core_domain_ops = {
.map = core_domain_map,
+ .xlate = irq_domain_xlate_onecell,
};
void __init init_IRQ(void)
diff --git a/arch/c6x/platforms/megamod-pic.c b/arch/c6x/platforms/megamod-pic.c
index 9f35fbf..c1c4e2a 100644
--- a/arch/c6x/platforms/megamod-pic.c
+++ b/arch/c6x/platforms/megamod-pic.c
@@ -136,21 +136,9 @@ static int megamod_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static int megamod_xlate(struct irq_domain *h, struct device_node *ct,
- const u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq, unsigned int *out_type)
-
-{
- /* megamod intspecs must have 1 cell */
- BUG_ON(intsize != 1);
- *out_hwirq = intspec[0];
- *out_type = IRQ_TYPE_NONE;
- return 0;
-}
-
static const struct irq_domain_ops megamod_domain_ops = {
.map = megamod_map,
- .xlate = megamod_xlate,
+ .xlate = irq_domain_xlate_onecell,
};
static void __init set_megamod_mux(struct megamod_pic *pic, int src, int output)
--
1.7.5.4
^ permalink raw reply related
* [PATCH v3 18/25] irq_domain/c6x: constify irq_domain structures
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
Milton Miller, Rob Herring, Stephen Rothwell
Cc: devicetree-discuss, linuxppc-dev, linux-arm-kernel, Mark Salter
In-Reply-To: <1327700179-17454-1-git-send-email-grant.likely@secretlab.ca>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Mark Salter <msalter@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
arch/arm/common/gic.c | 2 +-
arch/c6x/kernel/irq.c | 2 +-
arch/c6x/platforms/megamod-pic.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 5d91eb9..8cf934c 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -638,7 +638,7 @@ static int gic_irq_domain_xlate(struct irq_domain *d,
return 0;
}
-struct irq_domain_ops gic_irq_domain_ops = {
+const struct irq_domain_ops gic_irq_domain_ops = {
.map = gic_irq_domain_map,
.xlate = gic_irq_domain_xlate,
};
diff --git a/arch/c6x/kernel/irq.c b/arch/c6x/kernel/irq.c
index 3d5ac60..c6b36e8 100644
--- a/arch/c6x/kernel/irq.c
+++ b/arch/c6x/kernel/irq.c
@@ -86,7 +86,7 @@ static int core_domain_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-static struct irq_domain_ops core_domain_ops = {
+static const struct irq_domain_ops core_domain_ops = {
.map = core_domain_map,
};
diff --git a/arch/c6x/platforms/megamod-pic.c b/arch/c6x/platforms/megamod-pic.c
index 61f5863..9f35fbf 100644
--- a/arch/c6x/platforms/megamod-pic.c
+++ b/arch/c6x/platforms/megamod-pic.c
@@ -148,7 +148,7 @@ static int megamod_xlate(struct irq_domain *h, struct device_node *ct,
return 0;
}
-static struct irq_domain_ops megamod_domain_ops = {
+static const struct irq_domain_ops megamod_domain_ops = {
.map = megamod_map,
.xlate = megamod_xlate,
};
--
1.7.5.4
^ permalink raw reply related
* [PATCH v3 17/25] irq_domain/c6x: Convert c6x to use generic irq_domain support.
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
Milton Miller, Rob Herring, Stephen Rothwell
Cc: Aurelien Jacquiot, devicetree-discuss, Mark Salter, linuxppc-dev,
linux-arm-kernel
In-Reply-To: <1327700179-17454-1-git-send-email-grant.likely@secretlab.ca>
From: Mark Salter <msalter@redhat.com>
The C6X IRQ support was copied almost verbatim from the PowerPC virtual IRQ
code. The PowerPC code was used as the basis for generic irq_domain support,
so this patch mostly copies what what done to arch/powerpc by Grant Likely
in his irq_domain patch series.
Signed-off-by: Mark Salter <msalter@redhat.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Aurelien Jacquiot <a-jacquiot@ti.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
arch/c6x/Kconfig | 1 +
arch/c6x/include/asm/irq.h | 245 +---------------
arch/c6x/kernel/irq.c | 611 +-------------------------------------
arch/c6x/platforms/megamod-pic.c | 13 +-
4 files changed, 21 insertions(+), 849 deletions(-)
diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig
index 26e67f0..3c64b28 100644
--- a/arch/c6x/Kconfig
+++ b/arch/c6x/Kconfig
@@ -12,6 +12,7 @@ config TMS320C6X
select HAVE_GENERIC_HARDIRQS
select HAVE_MEMBLOCK
select HAVE_SPARSE_IRQ
+ select IRQ_DOMAIN
select OF
select OF_EARLY_FLATTREE
diff --git a/arch/c6x/include/asm/irq.h b/arch/c6x/include/asm/irq.h
index a6ae3c9..f13b78d 100644
--- a/arch/c6x/include/asm/irq.h
+++ b/arch/c6x/include/asm/irq.h
@@ -13,6 +13,7 @@
#ifndef _ASM_C6X_IRQ_H
#define _ASM_C6X_IRQ_H
+#include <linux/irqdomain.h>
#include <linux/threads.h>
#include <linux/list.h>
#include <linux/radix-tree.h>
@@ -41,253 +42,9 @@
/* This number is used when no interrupt has been assigned */
#define NO_IRQ 0
-/* This type is the placeholder for a hardware interrupt number. It has to
- * be big enough to enclose whatever representation is used by a given
- * platform.
- */
-typedef unsigned long irq_hw_number_t;
-
-/* Interrupt controller "host" data structure. This could be defined as a
- * irq domain controller. That is, it handles the mapping between hardware
- * and virtual interrupt numbers for a given interrupt domain. The host
- * structure is generally created by the PIC code for a given PIC instance
- * (though a host can cover more than one PIC if they have a flat number
- * model). It's the host callbacks that are responsible for setting the
- * irq_chip on a given irq_desc after it's been mapped.
- *
- * The host code and data structures are fairly agnostic to the fact that
- * we use an open firmware device-tree. We do have references to struct
- * device_node in two places: in irq_find_host() to find the host matching
- * a given interrupt controller node, and of course as an argument to its
- * counterpart host->ops->match() callback. However, those are treated as
- * generic pointers by the core and the fact that it's actually a device-node
- * pointer is purely a convention between callers and implementation. This
- * code could thus be used on other architectures by replacing those two
- * by some sort of arch-specific void * "token" used to identify interrupt
- * controllers.
- */
-struct irq_host;
-struct radix_tree_root;
-struct device_node;
-
-/* Functions below are provided by the host and called whenever a new mapping
- * is created or an old mapping is disposed. The host can then proceed to
- * whatever internal data structures management is required. It also needs
- * to setup the irq_desc when returning from map().
- */
-struct irq_host_ops {
- /* Match an interrupt controller device node to a host, returns
- * 1 on a match
- */
- int (*match)(struct irq_host *h, struct device_node *node);
-
- /* Create or update a mapping between a virtual irq number and a hw
- * irq number. This is called only once for a given mapping.
- */
- int (*map)(struct irq_host *h, unsigned int virq, irq_hw_number_t hw);
-
- /* Dispose of such a mapping */
- void (*unmap)(struct irq_host *h, unsigned int virq);
-
- /* Translate device-tree interrupt specifier from raw format coming
- * from the firmware to a irq_hw_number_t (interrupt line number) and
- * type (sense) that can be passed to set_irq_type(). In the absence
- * of this callback, irq_create_of_mapping() and irq_of_parse_and_map()
- * will return the hw number in the first cell and IRQ_TYPE_NONE for
- * the type (which amount to keeping whatever default value the
- * interrupt controller has for that line)
- */
- int (*xlate)(struct irq_host *h, struct device_node *ctrler,
- const u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq, unsigned int *out_type);
-};
-
-struct irq_host {
- struct list_head link;
-
- /* type of reverse mapping technique */
- unsigned int revmap_type;
-#define IRQ_HOST_MAP_PRIORITY 0 /* core priority irqs, get irqs 1..15 */
-#define IRQ_HOST_MAP_NOMAP 1 /* no fast reverse mapping */
-#define IRQ_HOST_MAP_LINEAR 2 /* linear map of interrupts */
-#define IRQ_HOST_MAP_TREE 3 /* radix tree */
- union {
- struct {
- unsigned int size;
- unsigned int *revmap;
- } linear;
- struct radix_tree_root tree;
- } revmap_data;
- struct irq_host_ops *ops;
- void *host_data;
- irq_hw_number_t inval_irq;
-
- /* Optional device node pointer */
- struct device_node *of_node;
-};
-
struct irq_data;
extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
extern irq_hw_number_t virq_to_hw(unsigned int virq);
-extern bool virq_is_host(unsigned int virq, struct irq_host *host);
-
-/**
- * irq_alloc_host - Allocate a new irq_host data structure
- * @of_node: optional device-tree node of the interrupt controller
- * @revmap_type: type of reverse mapping to use
- * @revmap_arg: for IRQ_HOST_MAP_LINEAR linear only: size of the map
- * @ops: map/unmap host callbacks
- * @inval_irq: provide a hw number in that host space that is always invalid
- *
- * Allocates and initialize and irq_host structure. Note that in the case of
- * IRQ_HOST_MAP_LEGACY, the map() callback will be called before this returns
- * for all legacy interrupts except 0 (which is always the invalid irq for
- * a legacy controller). For a IRQ_HOST_MAP_LINEAR, the map is allocated by
- * this call as well. For a IRQ_HOST_MAP_TREE, the radix tree will be allocated
- * later during boot automatically (the reverse mapping will use the slow path
- * until that happens).
- */
-extern struct irq_host *irq_alloc_host(struct device_node *of_node,
- unsigned int revmap_type,
- unsigned int revmap_arg,
- struct irq_host_ops *ops,
- irq_hw_number_t inval_irq);
-
-
-/**
- * irq_find_host - Locates a host for a given device node
- * @node: device-tree node of the interrupt controller
- */
-extern struct irq_host *irq_find_host(struct device_node *node);
-
-
-/**
- * irq_set_default_host - Set a "default" host
- * @host: default host pointer
- *
- * For convenience, it's possible to set a "default" host that will be used
- * whenever NULL is passed to irq_create_mapping(). It makes life easier for
- * platforms that want to manipulate a few hard coded interrupt numbers that
- * aren't properly represented in the device-tree.
- */
-extern void irq_set_default_host(struct irq_host *host);
-
-
-/**
- * irq_set_virq_count - Set the maximum number of virt irqs
- * @count: number of linux virtual irqs, capped with NR_IRQS
- *
- * This is mainly for use by platforms like iSeries who want to program
- * the virtual irq number in the controller to avoid the reverse mapping
- */
-extern void irq_set_virq_count(unsigned int count);
-
-
-/**
- * irq_create_mapping - Map a hardware interrupt into linux virq space
- * @host: host owning this hardware interrupt or NULL for default host
- * @hwirq: hardware irq number in that host space
- *
- * Only one mapping per hardware interrupt is permitted. Returns a linux
- * virq number.
- * If the sense/trigger is to be specified, set_irq_type() should be called
- * on the number returned from that call.
- */
-extern unsigned int irq_create_mapping(struct irq_host *host,
- irq_hw_number_t hwirq);
-
-
-/**
- * irq_dispose_mapping - Unmap an interrupt
- * @virq: linux virq number of the interrupt to unmap
- */
-extern void irq_dispose_mapping(unsigned int virq);
-
-/**
- * irq_find_mapping - Find a linux virq from an hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
- *
- * This is a slow path, for use by generic code. It's expected that an
- * irq controller implementation directly calls the appropriate low level
- * mapping function.
- */
-extern unsigned int irq_find_mapping(struct irq_host *host,
- irq_hw_number_t hwirq);
-
-/**
- * irq_create_direct_mapping - Allocate a virq for direct mapping
- * @host: host to allocate the virq for or NULL for default host
- *
- * This routine is used for irq controllers which can choose the hardware
- * interrupt numbers they generate. In such a case it's simplest to use
- * the linux virq as the hardware interrupt number.
- */
-extern unsigned int irq_create_direct_mapping(struct irq_host *host);
-
-/**
- * irq_radix_revmap_insert - Insert a hw irq to linux virq number mapping.
- * @host: host owning this hardware interrupt
- * @virq: linux irq number
- * @hwirq: hardware irq number in that host space
- *
- * This is for use by irq controllers that use a radix tree reverse
- * mapping for fast lookup.
- */
-extern void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
- irq_hw_number_t hwirq);
-
-/**
- * irq_radix_revmap_lookup - Find a linux virq from a hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
- *
- * This is a fast path, for use by irq controller code that uses radix tree
- * revmaps
- */
-extern unsigned int irq_radix_revmap_lookup(struct irq_host *host,
- irq_hw_number_t hwirq);
-
-/**
- * irq_linear_revmap - Find a linux virq from a hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
- *
- * This is a fast path, for use by irq controller code that uses linear
- * revmaps. It does fallback to the slow path if the revmap doesn't exist
- * yet and will create the revmap entry with appropriate locking
- */
-
-extern unsigned int irq_linear_revmap(struct irq_host *host,
- irq_hw_number_t hwirq);
-
-
-
-/**
- * irq_alloc_virt - Allocate virtual irq numbers
- * @host: host owning these new virtual irqs
- * @count: number of consecutive numbers to allocate
- * @hint: pass a hint number, the allocator will try to use a 1:1 mapping
- *
- * This is a low level function that is used internally by irq_create_mapping()
- * and that can be used by some irq controllers implementations for things
- * like allocating ranges of numbers for MSIs. The revmaps are left untouched.
- */
-extern unsigned int irq_alloc_virt(struct irq_host *host,
- unsigned int count,
- unsigned int hint);
-
-/**
- * irq_free_virt - Free virtual irq numbers
- * @virq: virtual irq number of the first interrupt to free
- * @count: number of interrupts to free
- *
- * This function is the opposite of irq_alloc_virt. It will not clear reverse
- * maps, this should be done previously by unmap'ing the interrupt. In fact,
- * all interrupts covered by the range being freed should have been unmapped
- * prior to calling this.
- */
-extern void irq_free_virt(unsigned int virq, unsigned int count);
extern void __init init_pic_c64xplus(void);
diff --git a/arch/c6x/kernel/irq.c b/arch/c6x/kernel/irq.c
index 0929e4b..3d5ac60 100644
--- a/arch/c6x/kernel/irq.c
+++ b/arch/c6x/kernel/irq.c
@@ -73,10 +73,10 @@ asmlinkage void c6x_do_IRQ(unsigned int prio, struct pt_regs *regs)
set_irq_regs(old_regs);
}
-static struct irq_host *core_host;
+static struct irq_domain *core_domain;
-static int core_host_map(struct irq_host *h, unsigned int virq,
- irq_hw_number_t hw)
+static int core_domain_map(struct irq_domain *h, unsigned int virq,
+ irq_hw_number_t hw)
{
if (hw < 4 || hw >= NR_PRIORITY_IRQS)
return -EINVAL;
@@ -86,8 +86,8 @@ static int core_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static struct irq_host_ops core_host_ops = {
- .map = core_host_map,
+static struct irq_domain_ops core_domain_ops = {
+ .map = core_domain_map,
};
void __init init_IRQ(void)
@@ -100,10 +100,11 @@ void __init init_IRQ(void)
np = of_find_compatible_node(NULL, NULL, "ti,c64x+core-pic");
if (np != NULL) {
/* create the core host */
- core_host = irq_alloc_host(np, IRQ_HOST_MAP_PRIORITY, 0,
- &core_host_ops, 0);
- if (core_host)
- irq_set_default_host(core_host);
+ core_domain = irq_domain_add_legacy(np, NR_PRIORITY_IRQS,
+ 0, 0, &core_domain_ops,
+ NULL);
+ if (core_domain)
+ irq_set_default_host(core_domain);
of_node_put(np);
}
@@ -128,601 +129,15 @@ int arch_show_interrupts(struct seq_file *p, int prec)
return 0;
}
-/*
- * IRQ controller and virtual interrupts
- */
-
-/* The main irq map itself is an array of NR_IRQ entries containing the
- * associate host and irq number. An entry with a host of NULL is free.
- * An entry can be allocated if it's free, the allocator always then sets
- * hwirq first to the host's invalid irq number and then fills ops.
- */
-struct irq_map_entry {
- irq_hw_number_t hwirq;
- struct irq_host *host;
-};
-
-static LIST_HEAD(irq_hosts);
-static DEFINE_RAW_SPINLOCK(irq_big_lock);
-static DEFINE_MUTEX(revmap_trees_mutex);
-static struct irq_map_entry irq_map[NR_IRQS];
-static unsigned int irq_virq_count = NR_IRQS;
-static struct irq_host *irq_default_host;
-
irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
{
- return irq_map[d->irq].hwirq;
+ return d->hwirq;
}
EXPORT_SYMBOL_GPL(irqd_to_hwirq);
irq_hw_number_t virq_to_hw(unsigned int virq)
{
- return irq_map[virq].hwirq;
+ struct irq_data *irq_data = irq_get_irq_data(virq);
+ return WARN_ON(!irq_data) ? 0 : irq_data->hwirq;
}
EXPORT_SYMBOL_GPL(virq_to_hw);
-
-bool virq_is_host(unsigned int virq, struct irq_host *host)
-{
- return irq_map[virq].host == host;
-}
-EXPORT_SYMBOL_GPL(virq_is_host);
-
-static int default_irq_host_match(struct irq_host *h, struct device_node *np)
-{
- return h->of_node != NULL && h->of_node == np;
-}
-
-struct irq_host *irq_alloc_host(struct device_node *of_node,
- unsigned int revmap_type,
- unsigned int revmap_arg,
- struct irq_host_ops *ops,
- irq_hw_number_t inval_irq)
-{
- struct irq_host *host;
- unsigned int size = sizeof(struct irq_host);
- unsigned int i;
- unsigned int *rmap;
- unsigned long flags;
-
- /* Allocate structure and revmap table if using linear mapping */
- if (revmap_type == IRQ_HOST_MAP_LINEAR)
- size += revmap_arg * sizeof(unsigned int);
- host = kzalloc(size, GFP_KERNEL);
- if (host == NULL)
- return NULL;
-
- /* Fill structure */
- host->revmap_type = revmap_type;
- host->inval_irq = inval_irq;
- host->ops = ops;
- host->of_node = of_node_get(of_node);
-
- if (host->ops->match == NULL)
- host->ops->match = default_irq_host_match;
-
- raw_spin_lock_irqsave(&irq_big_lock, flags);
-
- /* Check for the priority controller. */
- if (revmap_type == IRQ_HOST_MAP_PRIORITY) {
- if (irq_map[0].host != NULL) {
- raw_spin_unlock_irqrestore(&irq_big_lock, flags);
- of_node_put(host->of_node);
- kfree(host);
- return NULL;
- }
- irq_map[0].host = host;
- }
-
- list_add(&host->link, &irq_hosts);
- raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-
- /* Additional setups per revmap type */
- switch (revmap_type) {
- case IRQ_HOST_MAP_PRIORITY:
- /* 0 is always the invalid number for priority */
- host->inval_irq = 0;
- /* setup us as the host for all priority interrupts */
- for (i = 1; i < NR_PRIORITY_IRQS; i++) {
- irq_map[i].hwirq = i;
- smp_wmb();
- irq_map[i].host = host;
- smp_wmb();
-
- ops->map(host, i, i);
- }
- break;
- case IRQ_HOST_MAP_LINEAR:
- rmap = (unsigned int *)(host + 1);
- for (i = 0; i < revmap_arg; i++)
- rmap[i] = NO_IRQ;
- host->revmap_data.linear.size = revmap_arg;
- smp_wmb();
- host->revmap_data.linear.revmap = rmap;
- break;
- case IRQ_HOST_MAP_TREE:
- INIT_RADIX_TREE(&host->revmap_data.tree, GFP_KERNEL);
- break;
- default:
- break;
- }
-
- pr_debug("irq: Allocated host of type %d @0x%p\n", revmap_type, host);
-
- return host;
-}
-
-struct irq_host *irq_find_host(struct device_node *node)
-{
- struct irq_host *h, *found = NULL;
- unsigned long flags;
-
- /* We might want to match the legacy controller last since
- * it might potentially be set to match all interrupts in
- * the absence of a device node. This isn't a problem so far
- * yet though...
- */
- raw_spin_lock_irqsave(&irq_big_lock, flags);
- list_for_each_entry(h, &irq_hosts, link)
- if (h->ops->match(h, node)) {
- found = h;
- break;
- }
- raw_spin_unlock_irqrestore(&irq_big_lock, flags);
- return found;
-}
-EXPORT_SYMBOL_GPL(irq_find_host);
-
-void irq_set_default_host(struct irq_host *host)
-{
- pr_debug("irq: Default host set to @0x%p\n", host);
-
- irq_default_host = host;
-}
-
-void irq_set_virq_count(unsigned int count)
-{
- pr_debug("irq: Trying to set virq count to %d\n", count);
-
- BUG_ON(count < NR_PRIORITY_IRQS);
- if (count < NR_IRQS)
- irq_virq_count = count;
-}
-
-static int irq_setup_virq(struct irq_host *host, unsigned int virq,
- irq_hw_number_t hwirq)
-{
- int res;
-
- res = irq_alloc_desc_at(virq, 0);
- if (res != virq) {
- pr_debug("irq: -> allocating desc failed\n");
- goto error;
- }
-
- /* map it */
- smp_wmb();
- irq_map[virq].hwirq = hwirq;
- smp_mb();
-
- if (host->ops->map(host, virq, hwirq)) {
- pr_debug("irq: -> mapping failed, freeing\n");
- goto errdesc;
- }
-
- irq_clear_status_flags(virq, IRQ_NOREQUEST);
-
- return 0;
-
-errdesc:
- irq_free_descs(virq, 1);
-error:
- irq_free_virt(virq, 1);
- return -1;
-}
-
-unsigned int irq_create_direct_mapping(struct irq_host *host)
-{
- unsigned int virq;
-
- if (host == NULL)
- host = irq_default_host;
-
- BUG_ON(host == NULL);
- WARN_ON(host->revmap_type != IRQ_HOST_MAP_NOMAP);
-
- virq = irq_alloc_virt(host, 1, 0);
- if (virq == NO_IRQ) {
- pr_debug("irq: create_direct virq allocation failed\n");
- return NO_IRQ;
- }
-
- pr_debug("irq: create_direct obtained virq %d\n", virq);
-
- if (irq_setup_virq(host, virq, virq))
- return NO_IRQ;
-
- return virq;
-}
-
-unsigned int irq_create_mapping(struct irq_host *host,
- irq_hw_number_t hwirq)
-{
- unsigned int virq, hint;
-
- pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", host, hwirq);
-
- /* Look for default host if nececssary */
- if (host == NULL)
- host = irq_default_host;
- if (host == NULL) {
- printk(KERN_WARNING "irq_create_mapping called for"
- " NULL host, hwirq=%lx\n", hwirq);
- WARN_ON(1);
- return NO_IRQ;
- }
- pr_debug("irq: -> using host @%p\n", host);
-
- /* Check if mapping already exists */
- virq = irq_find_mapping(host, hwirq);
- if (virq != NO_IRQ) {
- pr_debug("irq: -> existing mapping on virq %d\n", virq);
- return virq;
- }
-
- /* Allocate a virtual interrupt number */
- hint = hwirq % irq_virq_count;
- virq = irq_alloc_virt(host, 1, hint);
- if (virq == NO_IRQ) {
- pr_debug("irq: -> virq allocation failed\n");
- return NO_IRQ;
- }
-
- if (irq_setup_virq(host, virq, hwirq))
- return NO_IRQ;
-
- pr_debug("irq: irq %lu on host %s mapped to virtual irq %u\n",
- hwirq, host->of_node ? host->of_node->full_name : "null", virq);
-
- return virq;
-}
-EXPORT_SYMBOL_GPL(irq_create_mapping);
-
-unsigned int irq_create_of_mapping(struct device_node *controller,
- const u32 *intspec, unsigned int intsize)
-{
- struct irq_host *host;
- irq_hw_number_t hwirq;
- unsigned int type = IRQ_TYPE_NONE;
- unsigned int virq;
-
- if (controller == NULL)
- host = irq_default_host;
- else
- host = irq_find_host(controller);
- if (host == NULL) {
- printk(KERN_WARNING "irq: no irq host found for %s !\n",
- controller->full_name);
- return NO_IRQ;
- }
-
- /* If host has no translation, then we assume interrupt line */
- if (host->ops->xlate == NULL)
- hwirq = intspec[0];
- else {
- if (host->ops->xlate(host, controller, intspec, intsize,
- &hwirq, &type))
- return NO_IRQ;
- }
-
- /* Create mapping */
- virq = irq_create_mapping(host, hwirq);
- if (virq == NO_IRQ)
- return virq;
-
- /* Set type if specified and different than the current one */
- if (type != IRQ_TYPE_NONE &&
- type != (irqd_get_trigger_type(irq_get_irq_data(virq))))
- irq_set_irq_type(virq, type);
- return virq;
-}
-EXPORT_SYMBOL_GPL(irq_create_of_mapping);
-
-void irq_dispose_mapping(unsigned int virq)
-{
- struct irq_host *host;
- irq_hw_number_t hwirq;
-
- if (virq == NO_IRQ)
- return;
-
- /* Never unmap priority interrupts */
- if (virq < NR_PRIORITY_IRQS)
- return;
-
- host = irq_map[virq].host;
- if (WARN_ON(host == NULL))
- return;
-
- irq_set_status_flags(virq, IRQ_NOREQUEST);
-
- /* remove chip and handler */
- irq_set_chip_and_handler(virq, NULL, NULL);
-
- /* Make sure it's completed */
- synchronize_irq(virq);
-
- /* Tell the PIC about it */
- if (host->ops->unmap)
- host->ops->unmap(host, virq);
- smp_mb();
-
- /* Clear reverse map */
- hwirq = irq_map[virq].hwirq;
- switch (host->revmap_type) {
- case IRQ_HOST_MAP_LINEAR:
- if (hwirq < host->revmap_data.linear.size)
- host->revmap_data.linear.revmap[hwirq] = NO_IRQ;
- break;
- case IRQ_HOST_MAP_TREE:
- mutex_lock(&revmap_trees_mutex);
- radix_tree_delete(&host->revmap_data.tree, hwirq);
- mutex_unlock(&revmap_trees_mutex);
- break;
- }
-
- /* Destroy map */
- smp_mb();
- irq_map[virq].hwirq = host->inval_irq;
-
- irq_free_descs(virq, 1);
- /* Free it */
- irq_free_virt(virq, 1);
-}
-EXPORT_SYMBOL_GPL(irq_dispose_mapping);
-
-unsigned int irq_find_mapping(struct irq_host *host,
- irq_hw_number_t hwirq)
-{
- unsigned int i;
- unsigned int hint = hwirq % irq_virq_count;
-
- /* Look for default host if nececssary */
- if (host == NULL)
- host = irq_default_host;
- if (host == NULL)
- return NO_IRQ;
-
- /* Slow path does a linear search of the map */
- i = hint;
- do {
- if (irq_map[i].host == host &&
- irq_map[i].hwirq == hwirq)
- return i;
- i++;
- if (i >= irq_virq_count)
- i = 4;
- } while (i != hint);
- return NO_IRQ;
-}
-EXPORT_SYMBOL_GPL(irq_find_mapping);
-
-unsigned int irq_radix_revmap_lookup(struct irq_host *host,
- irq_hw_number_t hwirq)
-{
- struct irq_map_entry *ptr;
- unsigned int virq;
-
- if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_TREE))
- return irq_find_mapping(host, hwirq);
-
- /*
- * The ptr returned references the static global irq_map.
- * but freeing an irq can delete nodes along the path to
- * do the lookup via call_rcu.
- */
- rcu_read_lock();
- ptr = radix_tree_lookup(&host->revmap_data.tree, hwirq);
- rcu_read_unlock();
-
- /*
- * If found in radix tree, then fine.
- * Else fallback to linear lookup - this should not happen in practice
- * as it means that we failed to insert the node in the radix tree.
- */
- if (ptr)
- virq = ptr - irq_map;
- else
- virq = irq_find_mapping(host, hwirq);
-
- return virq;
-}
-
-void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
- irq_hw_number_t hwirq)
-{
- if (WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE))
- return;
-
- if (virq != NO_IRQ) {
- mutex_lock(&revmap_trees_mutex);
- radix_tree_insert(&host->revmap_data.tree, hwirq,
- &irq_map[virq]);
- mutex_unlock(&revmap_trees_mutex);
- }
-}
-
-unsigned int irq_linear_revmap(struct irq_host *host,
- irq_hw_number_t hwirq)
-{
- unsigned int *revmap;
-
- if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_LINEAR))
- return irq_find_mapping(host, hwirq);
-
- /* Check revmap bounds */
- if (unlikely(hwirq >= host->revmap_data.linear.size))
- return irq_find_mapping(host, hwirq);
-
- /* Check if revmap was allocated */
- revmap = host->revmap_data.linear.revmap;
- if (unlikely(revmap == NULL))
- return irq_find_mapping(host, hwirq);
-
- /* Fill up revmap with slow path if no mapping found */
- if (unlikely(revmap[hwirq] == NO_IRQ))
- revmap[hwirq] = irq_find_mapping(host, hwirq);
-
- return revmap[hwirq];
-}
-
-unsigned int irq_alloc_virt(struct irq_host *host,
- unsigned int count,
- unsigned int hint)
-{
- unsigned long flags;
- unsigned int i, j, found = NO_IRQ;
-
- if (count == 0 || count > (irq_virq_count - NR_PRIORITY_IRQS))
- return NO_IRQ;
-
- raw_spin_lock_irqsave(&irq_big_lock, flags);
-
- /* Use hint for 1 interrupt if any */
- if (count == 1 && hint >= NR_PRIORITY_IRQS &&
- hint < irq_virq_count && irq_map[hint].host == NULL) {
- found = hint;
- goto hint_found;
- }
-
- /* Look for count consecutive numbers in the allocatable
- * (non-legacy) space
- */
- for (i = NR_PRIORITY_IRQS, j = 0; i < irq_virq_count; i++) {
- if (irq_map[i].host != NULL)
- j = 0;
- else
- j++;
-
- if (j == count) {
- found = i - count + 1;
- break;
- }
- }
- if (found == NO_IRQ) {
- raw_spin_unlock_irqrestore(&irq_big_lock, flags);
- return NO_IRQ;
- }
- hint_found:
- for (i = found; i < (found + count); i++) {
- irq_map[i].hwirq = host->inval_irq;
- smp_wmb();
- irq_map[i].host = host;
- }
- raw_spin_unlock_irqrestore(&irq_big_lock, flags);
- return found;
-}
-
-void irq_free_virt(unsigned int virq, unsigned int count)
-{
- unsigned long flags;
- unsigned int i;
-
- WARN_ON(virq < NR_PRIORITY_IRQS);
- WARN_ON(count == 0 || (virq + count) > irq_virq_count);
-
- if (virq < NR_PRIORITY_IRQS) {
- if (virq + count < NR_PRIORITY_IRQS)
- return;
- count -= NR_PRIORITY_IRQS - virq;
- virq = NR_PRIORITY_IRQS;
- }
-
- if (count > irq_virq_count || virq > irq_virq_count - count) {
- if (virq > irq_virq_count)
- return;
- count = irq_virq_count - virq;
- }
-
- raw_spin_lock_irqsave(&irq_big_lock, flags);
- for (i = virq; i < (virq + count); i++) {
- struct irq_host *host;
-
- host = irq_map[i].host;
- irq_map[i].hwirq = host->inval_irq;
- smp_wmb();
- irq_map[i].host = NULL;
- }
- raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-}
-
-#ifdef CONFIG_VIRQ_DEBUG
-static int virq_debug_show(struct seq_file *m, void *private)
-{
- unsigned long flags;
- struct irq_desc *desc;
- const char *p;
- static const char none[] = "none";
- void *data;
- int i;
-
- seq_printf(m, "%-5s %-7s %-15s %-18s %s\n", "virq", "hwirq",
- "chip name", "chip data", "host name");
-
- for (i = 1; i < nr_irqs; i++) {
- desc = irq_to_desc(i);
- if (!desc)
- continue;
-
- raw_spin_lock_irqsave(&desc->lock, flags);
-
- if (desc->action && desc->action->handler) {
- struct irq_chip *chip;
-
- seq_printf(m, "%5d ", i);
- seq_printf(m, "0x%05lx ", irq_map[i].hwirq);
-
- chip = irq_desc_get_chip(desc);
- if (chip && chip->name)
- p = chip->name;
- else
- p = none;
- seq_printf(m, "%-15s ", p);
-
- data = irq_desc_get_chip_data(desc);
- seq_printf(m, "0x%16p ", data);
-
- if (irq_map[i].host && irq_map[i].host->of_node)
- p = irq_map[i].host->of_node->full_name;
- else
- p = none;
- seq_printf(m, "%s\n", p);
- }
-
- raw_spin_unlock_irqrestore(&desc->lock, flags);
- }
-
- return 0;
-}
-
-static int virq_debug_open(struct inode *inode, struct file *file)
-{
- return single_open(file, virq_debug_show, inode->i_private);
-}
-
-static const struct file_operations virq_debug_fops = {
- .open = virq_debug_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int __init irq_debugfs_init(void)
-{
- if (debugfs_create_file("virq_mapping", S_IRUGO, powerpc_debugfs_root,
- NULL, &virq_debug_fops) == NULL)
- return -ENOMEM;
-
- return 0;
-}
-device_initcall(irq_debugfs_init);
-#endif /* CONFIG_VIRQ_DEBUG */
diff --git a/arch/c6x/platforms/megamod-pic.c b/arch/c6x/platforms/megamod-pic.c
index 7c37a94..61f5863 100644
--- a/arch/c6x/platforms/megamod-pic.c
+++ b/arch/c6x/platforms/megamod-pic.c
@@ -48,7 +48,7 @@ struct megamod_regs {
};
struct megamod_pic {
- struct irq_host *irqhost;
+ struct irq_domain *irqhost;
struct megamod_regs __iomem *regs;
raw_spinlock_t lock;
@@ -116,7 +116,7 @@ static void megamod_irq_cascade(unsigned int irq, struct irq_desc *desc)
}
}
-static int megamod_map(struct irq_host *h, unsigned int virq,
+static int megamod_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
struct megamod_pic *pic = h->host_data;
@@ -136,7 +136,7 @@ static int megamod_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static int megamod_xlate(struct irq_host *h, struct device_node *ct,
+static int megamod_xlate(struct irq_domain *h, struct device_node *ct,
const u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq, unsigned int *out_type)
@@ -148,7 +148,7 @@ static int megamod_xlate(struct irq_host *h, struct device_node *ct,
return 0;
}
-static struct irq_host_ops megamod_host_ops = {
+static struct irq_domain_ops megamod_domain_ops = {
.map = megamod_map,
.xlate = megamod_xlate,
};
@@ -223,9 +223,8 @@ static struct megamod_pic * __init init_megamod_pic(struct device_node *np)
return NULL;
}
- pic->irqhost = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
- NR_COMBINERS * 32, &megamod_host_ops,
- IRQ_UNMAPPED);
+ pic->irqhost = irq_domain_add_linear(np, NR_COMBINERS * 32,
+ &megamod_domain_ops, pic);
if (!pic->irqhost) {
pr_err("%s: Could not alloc host.\n", np->full_name);
goto error_free;
--
1.7.5.4
^ permalink raw reply related
* [PATCH v3 16/25] irq_domain: constify irq_domain_ops
From: Grant Likely @ 2012-01-27 21:36 UTC (permalink / raw)
To: linux-kernel, Benjamin Herrenschmidt, Thomas Gleixner,
Milton Miller, Rob Herring, Stephen Rothwell
Cc: devicetree-discuss, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1327700179-17454-1-git-send-email-grant.likely@secretlab.ca>
Make irq_domain_ops pointer a constant to make it safer for multiple
instances to share the same ops pointer and change the irq_domain code
so that it does not modify the ops.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Milton Miller <miltonm@bga.com>
---
include/linux/irqdomain.h | 14 +++++++-------
kernel/irq/irqdomain.c | 31 +++++++++++++++----------------
2 files changed, 22 insertions(+), 23 deletions(-)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 1db30df..0b00f83 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -106,7 +106,7 @@ struct irq_domain {
} linear;
struct radix_tree_root tree;
} revmap_data;
- struct irq_domain_ops *ops;
+ const struct irq_domain_ops *ops;
void *host_data;
irq_hw_number_t inval_irq;
@@ -119,17 +119,17 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
unsigned int size,
unsigned int first_irq,
irq_hw_number_t first_hwirq,
- struct irq_domain_ops *ops,
+ const struct irq_domain_ops *ops,
void *host_data);
struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
unsigned int size,
- struct irq_domain_ops *ops,
+ const struct irq_domain_ops *ops,
void *host_data);
struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
- struct irq_domain_ops *ops,
+ const struct irq_domain_ops *ops,
void *host_data);
struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
- struct irq_domain_ops *ops,
+ const struct irq_domain_ops *ops,
void *host_data);
extern struct irq_domain *irq_find_host(struct device_node *node);
@@ -138,7 +138,7 @@ extern void irq_set_virq_count(unsigned int count);
static inline struct irq_domain *irq_domain_add_legacy_isa(
struct device_node *of_node,
- struct irq_domain_ops *ops,
+ const struct irq_domain_ops *ops,
void *host_data)
{
return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops,
@@ -162,7 +162,7 @@ extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
extern unsigned int irq_linear_revmap(struct irq_domain *host,
irq_hw_number_t hwirq);
-extern struct irq_domain_ops irq_domain_simple_ops;
+extern const struct irq_domain_ops irq_domain_simple_ops;
/* stock xlate functions */
int irq_domain_xlate_onecell(struct irq_domain *d, struct device_node *ctrlr,
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index b0ed3be..bf181ef 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -21,11 +21,6 @@ static DEFINE_MUTEX(revmap_trees_mutex);
static unsigned int irq_virq_count = NR_IRQS;
static struct irq_domain *irq_default_domain;
-static int default_irq_domain_match(struct irq_domain *d, struct device_node *np)
-{
- return d->of_node != NULL && d->of_node == np;
-}
-
/**
* irq_domain_alloc() - Allocate a new irq_domain data structure
* @of_node: optional device-tree node of the interrupt controller
@@ -39,7 +34,7 @@ static int default_irq_domain_match(struct irq_domain *d, struct device_node *np
*/
static struct irq_domain *irq_domain_alloc(struct device_node *of_node,
unsigned int revmap_type,
- struct irq_domain_ops *ops,
+ const struct irq_domain_ops *ops,
void *host_data)
{
struct irq_domain *domain;
@@ -54,9 +49,6 @@ static struct irq_domain *irq_domain_alloc(struct device_node *of_node,
domain->host_data = host_data;
domain->of_node = of_node_get(of_node);
- if (domain->ops->match == NULL)
- domain->ops->match = default_irq_domain_match;
-
return domain;
}
@@ -99,7 +91,7 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
unsigned int size,
unsigned int first_irq,
irq_hw_number_t first_hwirq,
- struct irq_domain_ops *ops,
+ const struct irq_domain_ops *ops,
void *host_data)
{
struct irq_domain *domain;
@@ -165,7 +157,7 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
*/
struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
unsigned int size,
- struct irq_domain_ops *ops,
+ const struct irq_domain_ops *ops,
void *host_data)
{
struct irq_domain *domain;
@@ -187,7 +179,7 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
}
struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
- struct irq_domain_ops *ops,
+ const struct irq_domain_ops *ops,
void *host_data)
{
struct irq_domain *domain = irq_domain_alloc(of_node,
@@ -206,7 +198,7 @@ struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
* (the reverse mapping will use the slow path until that happens).
*/
struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
- struct irq_domain_ops *ops,
+ const struct irq_domain_ops *ops,
void *host_data)
{
struct irq_domain *domain = irq_domain_alloc(of_node,
@@ -225,6 +217,7 @@ struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
struct irq_domain *irq_find_host(struct device_node *node)
{
struct irq_domain *h, *found = NULL;
+ int rc;
/* We might want to match the legacy controller last since
* it might potentially be set to match all interrupts in
@@ -232,11 +225,17 @@ struct irq_domain *irq_find_host(struct device_node *node)
* yet though...
*/
mutex_lock(&irq_domain_mutex);
- list_for_each_entry(h, &irq_domain_list, link)
- if (h->ops->match(h, node)) {
+ list_for_each_entry(h, &irq_domain_list, link) {
+ if (h->ops->match)
+ rc = h->ops->match(h, node);
+ else
+ rc = (h->of_node != NULL) && (h->of_node == node);
+
+ if (rc) {
found = h;
break;
}
+ }
mutex_unlock(&irq_domain_mutex);
return found;
}
@@ -766,7 +765,7 @@ int irq_domain_xlate_pci(struct irq_domain *d, struct device_node *ctrlr,
}
EXPORT_SYMBOL_GPL(irq_domain_xlate_pci);
-struct irq_domain_ops irq_domain_simple_ops = {
+const struct irq_domain_ops irq_domain_simple_ops = {
.map = irq_domain_simple_map,
.xlate = irq_domain_xlate_onetwocell,
};
--
1.7.5.4
^ permalink raw reply related
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