[U-Boot] [PATCH 0/6] dm: x86: Remove pirq_init() and cpu_irq_init()

This series adds an interrupt driver for x86. Since different platforms can implement this in their own way, we no-longer need the platform-specific weak function. We can also dispense with the arch_misc_init() call in some cases.
Simon Glass (6): dm: x86: Create a driver for x86 interrupts dm: x86: Set up interrupt routing from interrupt_init() dm: x86: Add a common PIRQ init function dm: x86: quark: Add an interrupt driver dm: x86: queensbay: Add an interrupt driver dm: x86: Drop the weak cpu_irq_init() function
arch/x86/cpu/baytrail/valleyview.c | 2 +- arch/x86/cpu/interrupts.c | 9 ++++++ arch/x86/cpu/irq.c | 32 ++++++++++++++----- arch/x86/cpu/qemu/qemu.c | 5 --- arch/x86/cpu/quark/Makefile | 2 +- arch/x86/cpu/quark/irq.c | 49 ++++++++++++++++++++++++++++ arch/x86/cpu/quark/quark.c | 27 +--------------- arch/x86/cpu/queensbay/Makefile | 2 +- arch/x86/cpu/queensbay/irq.c | 65 ++++++++++++++++++++++++++++++++++++++ arch/x86/cpu/queensbay/tnc.c | 39 +---------------------- arch/x86/dts/crownbay.dts | 2 +- arch/x86/dts/galileo.dts | 2 +- arch/x86/include/asm/irq.h | 19 ++--------- include/configs/qemu-x86.h | 1 - include/dm/uclass-id.h | 1 + 15 files changed, 158 insertions(+), 99 deletions(-) create mode 100644 arch/x86/cpu/quark/irq.c create mode 100644 arch/x86/cpu/queensbay/irq.c

It seems likely that at some point we will want a generic interrupt uclass. But this is a big undertaking as it involves unifying code across multiple architectures.
As a first step, create a simple IRQ uclass and a driver for x86. This can be generalised later as required.
Adjust pirq_init() to probe this driver, which has the effect of creating routing tables and setting up the interrupt routing. This is a start towards making interrupts fit better with driver model.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/cpu/irq.c | 25 +++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + 2 files changed, 26 insertions(+)
diff --git a/arch/x86/cpu/irq.c b/arch/x86/cpu/irq.c index 205405b..9b699cf 100644 --- a/arch/x86/cpu/irq.c +++ b/arch/x86/cpu/irq.c @@ -5,6 +5,7 @@ */
#include <common.h> +#include <dm.h> #include <errno.h> #include <fdtdec.h> #include <malloc.h> @@ -232,6 +233,13 @@ static int create_pirq_routing_table(void)
int pirq_init(void) { + struct udevice *dev; + + return uclass_first_device(UCLASS_IRQ, &dev); +} + +int irq_router_probe(struct udevice *dev) +{ int ret;
cpu_irq_init(); @@ -255,3 +263,20 @@ u32 write_pirq_routing_table(u32 addr)
return copy_pirq_routing_table(addr, pirq_routing_table); } + +static const struct udevice_id irq_router_ids[] = { + { .compatible = "intel,irq-router" }, + { } +}; + +U_BOOT_DRIVER(irq_router_drv) = { + .name = "intel_irq", + .id = UCLASS_IRQ, + .of_match = irq_router_ids, + .probe = irq_router_probe, +}; + +UCLASS_DRIVER(irq) = { + .id = UCLASS_IRQ, + .name = "irq", +}; diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 27fa0b6..ef145af 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -37,6 +37,7 @@ enum uclass_id { UCLASS_I2C_EEPROM, /* I2C EEPROM device */ UCLASS_I2C_GENERIC, /* Generic I2C device */ UCLASS_I2C_MUX, /* I2C multiplexer */ + UCLASS_IRQ, /* Interrupt controller */ UCLASS_KEYBOARD, /* Keyboard input device */ UCLASS_LED, /* Light-emitting diode (LED) */ UCLASS_LPC, /* x86 'low pin count' interface */

Hi Simon,
On Tue, Dec 1, 2015 at 12:46 PM, Simon Glass sjg@chromium.org wrote:
It seems likely that at some point we will want a generic interrupt uclass. But this is a big undertaking as it involves unifying code across multiple architectures.
As a first step, create a simple IRQ uclass and a driver for x86. This can be generalised later as required.
Adjust pirq_init() to probe this driver, which has the effect of creating routing tables and setting up the interrupt routing. This is a start towards making interrupts fit better with driver model.
Signed-off-by: Simon Glass sjg@chromium.org
Reviewed-by: Bin Meng bmeng.cn@gmail.com
I will test this series when all previous DM changes are applied.
Regards, Bin

Hi Bin,
On 13 December 2015 at 23:05, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Tue, Dec 1, 2015 at 12:46 PM, Simon Glass sjg@chromium.org wrote:
It seems likely that at some point we will want a generic interrupt uclass. But this is a big undertaking as it involves unifying code across multiple architectures.
As a first step, create a simple IRQ uclass and a driver for x86. This can be generalised later as required.
Adjust pirq_init() to probe this driver, which has the effect of creating routing tables and setting up the interrupt routing. This is a start towards making interrupts fit better with driver model.
Signed-off-by: Simon Glass sjg@chromium.org
Reviewed-by: Bin Meng bmeng.cn@gmail.com
I will test this series when all previous DM changes are applied.
Do you mean the series that I just pushed to dm/next. or something else?
Regards, Simon

Hi Simon,
On Tue, Dec 15, 2015 at 6:14 AM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On 13 December 2015 at 23:05, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Tue, Dec 1, 2015 at 12:46 PM, Simon Glass sjg@chromium.org wrote:
It seems likely that at some point we will want a generic interrupt uclass. But this is a big undertaking as it involves unifying code across multiple architectures.
As a first step, create a simple IRQ uclass and a driver for x86. This can be generalised later as required.
Adjust pirq_init() to probe this driver, which has the effect of creating routing tables and setting up the interrupt routing. This is a start towards making interrupts fit better with driver model.
Signed-off-by: Simon Glass sjg@chromium.org
Reviewed-by: Bin Meng bmeng.cn@gmail.com
I will test this series when all previous DM changes are applied.
Do you mean the series that I just pushed to dm/next. or something else?
Yes, I mean all previous DM changes as I suspect this series has some dependency on previous series. I will apply this series on top of dm/next and test there.
Regards, Bin

Hi Simon,
On Tue, Dec 15, 2015 at 10:04 AM, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Tue, Dec 15, 2015 at 6:14 AM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On 13 December 2015 at 23:05, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Tue, Dec 1, 2015 at 12:46 PM, Simon Glass sjg@chromium.org wrote:
It seems likely that at some point we will want a generic interrupt uclass. But this is a big undertaking as it involves unifying code across multiple architectures.
As a first step, create a simple IRQ uclass and a driver for x86. This can be generalised later as required.
Adjust pirq_init() to probe this driver, which has the effect of creating routing tables and setting up the interrupt routing. This is a start towards making interrupts fit better with driver model.
Signed-off-by: Simon Glass sjg@chromium.org
Reviewed-by: Bin Meng bmeng.cn@gmail.com
I will test this series when all previous DM changes are applied.
Do you mean the series that I just pushed to dm/next. or something else?
Yes, I mean all previous DM changes as I suspect this series has some dependency on previous series. I will apply this series on top of dm/next and test there.
patch#4, patch#5 does not apply on top of dm/next. I guess there are some other dependencies?
Regards, Bin

Hi Bin,
On 14 December 2015 at 22:45, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Tue, Dec 15, 2015 at 10:04 AM, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Tue, Dec 15, 2015 at 6:14 AM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On 13 December 2015 at 23:05, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Tue, Dec 1, 2015 at 12:46 PM, Simon Glass sjg@chromium.org wrote:
It seems likely that at some point we will want a generic interrupt uclass. But this is a big undertaking as it involves unifying code across multiple architectures.
As a first step, create a simple IRQ uclass and a driver for x86. This can be generalised later as required.
Adjust pirq_init() to probe this driver, which has the effect of creating routing tables and setting up the interrupt routing. This is a start towards making interrupts fit better with driver model.
Signed-off-by: Simon Glass sjg@chromium.org
Reviewed-by: Bin Meng bmeng.cn@gmail.com
I will test this series when all previous DM changes are applied.
Do you mean the series that I just pushed to dm/next. or something else?
Yes, I mean all previous DM changes as I suspect this series has some dependency on previous series. I will apply this series on top of dm/next and test there.
patch#4, patch#5 does not apply on top of dm/next. I guess there are some other dependencies?
I'm not sure, but you can use u-boot-dm/pcid-working for your testing.
Regards, Simon

On Mon, Dec 14, 2015 at 2:05 PM, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Tue, Dec 1, 2015 at 12:46 PM, Simon Glass sjg@chromium.org wrote:
It seems likely that at some point we will want a generic interrupt uclass. But this is a big undertaking as it involves unifying code across multiple architectures.
As a first step, create a simple IRQ uclass and a driver for x86. This can be generalised later as required.
Adjust pirq_init() to probe this driver, which has the effect of creating routing tables and setting up the interrupt routing. This is a start towards making interrupts fit better with driver model.
Signed-off-by: Simon Glass sjg@chromium.org
Reviewed-by: Bin Meng bmeng.cn@gmail.com
I will test this series when all previous DM changes are applied.
Apply this patch manually on top of dm/next, tested on Crown Bay
Tested-by: Bin Meng bmeng.cn@gmail.com

At present interrupt routing is set up from arch_misc_init(). We can do it a little later instead, in interrupt_init().
This removes the manual pirq_init() call. Where the platform does not have an interrupt router defined in its device tree, no error is generated. Some platforms do not have this.
Drop pirq_init() since it is no-longer used.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/cpu/baytrail/valleyview.c | 2 +- arch/x86/cpu/interrupts.c | 9 +++++++++ arch/x86/cpu/irq.c | 7 ------- arch/x86/cpu/qemu/qemu.c | 5 ----- arch/x86/cpu/quark/quark.c | 2 +- arch/x86/cpu/queensbay/tnc.c | 2 +- arch/x86/include/asm/irq.h | 10 ---------- include/configs/qemu-x86.h | 1 - 8 files changed, 12 insertions(+), 26 deletions(-)
diff --git a/arch/x86/cpu/baytrail/valleyview.c b/arch/x86/cpu/baytrail/valleyview.c index 7299f2c..25382f9 100644 --- a/arch/x86/cpu/baytrail/valleyview.c +++ b/arch/x86/cpu/baytrail/valleyview.c @@ -50,7 +50,7 @@ int arch_misc_init(void) mrccache_save(); #endif
- return pirq_init(); + return 0; }
int reserve_arch(void) diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c index b00ddc0..c40200b 100644 --- a/arch/x86/cpu/interrupts.c +++ b/arch/x86/cpu/interrupts.c @@ -12,6 +12,7 @@ */
#include <common.h> +#include <dm.h> #include <asm/cache.h> #include <asm/control_regs.h> #include <asm/interrupt.h> @@ -244,6 +245,14 @@ int disable_interrupts(void)
int interrupt_init(void) { + struct udevice *dev; + int ret; + + /* Try to set up the interrupt router, but don't require one */ + ret = uclass_first_device(UCLASS_IRQ, &dev); + if (ret && ret != -ENODEV) + return ret; + /* * When running as an EFI application we are not in control of * interrupts and should leave them alone. diff --git a/arch/x86/cpu/irq.c b/arch/x86/cpu/irq.c index 9b699cf..8f59b23 100644 --- a/arch/x86/cpu/irq.c +++ b/arch/x86/cpu/irq.c @@ -231,13 +231,6 @@ static int create_pirq_routing_table(void) return 0; }
-int pirq_init(void) -{ - struct udevice *dev; - - return uclass_first_device(UCLASS_IRQ, &dev); -} - int irq_router_probe(struct udevice *dev) { int ret; diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c index 1f93f72..736d6b1 100644 --- a/arch/x86/cpu/qemu/qemu.c +++ b/arch/x86/cpu/qemu/qemu.c @@ -93,11 +93,6 @@ int arch_early_init_r(void) return 0; }
-int arch_misc_init(void) -{ - return pirq_init(); -} - #ifdef CONFIG_GENERATE_MP_TABLE int mp_determine_pci_dstirq(int bus, int dev, int func, int pirq) { diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c index 37ce394..f652d99 100644 --- a/arch/x86/cpu/quark/quark.c +++ b/arch/x86/cpu/quark/quark.c @@ -375,7 +375,7 @@ int arch_misc_init(void) mrccache_save(); #endif
- return pirq_init(); + return 0; }
void board_final_cleanup(void) diff --git a/arch/x86/cpu/queensbay/tnc.c b/arch/x86/cpu/queensbay/tnc.c index fb81919..b65906b 100644 --- a/arch/x86/cpu/queensbay/tnc.c +++ b/arch/x86/cpu/queensbay/tnc.c @@ -110,5 +110,5 @@ int arch_misc_init(void) { unprotect_spi_flash();
- return pirq_init(); + return 0; } diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h index 6697da3..74da66e 100644 --- a/arch/x86/include/asm/irq.h +++ b/arch/x86/include/asm/irq.h @@ -65,14 +65,4 @@ struct pirq_routing { */ void cpu_irq_init(void);
-/** - * pirq_init() - Initialize platform PIRQ routing - * - * This initializes the PIRQ routing on the platform and configures all PCI - * devices' interrupt line register to a working IRQ number on the 8259 PIC. - * - * @return 0 if OK, -ve on error - */ -int pirq_init(void); - #endif /* _ARCH_IRQ_H_ */ diff --git a/include/configs/qemu-x86.h b/include/configs/qemu-x86.h index 4258dcb..b0d2ffe 100644 --- a/include/configs/qemu-x86.h +++ b/include/configs/qemu-x86.h @@ -14,7 +14,6 @@ #include <configs/x86-common.h>
#define CONFIG_SYS_MONITOR_LEN (1 << 20) -#define CONFIG_ARCH_MISC_INIT #define CONFIG_ARCH_EARLY_INIT_R
#define CONFIG_PCI_PNP

On Tue, Dec 1, 2015 at 12:47 PM, Simon Glass sjg@chromium.org wrote:
At present interrupt routing is set up from arch_misc_init(). We can do it a little later instead, in interrupt_init().
This removes the manual pirq_init() call. Where the platform does not have an interrupt router defined in its device tree, no error is generated. Some platforms do not have this.
Drop pirq_init() since it is no-longer used.
Signed-off-by: Simon Glass sjg@chromium.org
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On Mon, Dec 14, 2015 at 2:05 PM, Bin Meng bmeng.cn@gmail.com wrote:
On Tue, Dec 1, 2015 at 12:47 PM, Simon Glass sjg@chromium.org wrote:
At present interrupt routing is set up from arch_misc_init(). We can do it a little later instead, in interrupt_init().
This removes the manual pirq_init() call. Where the platform does not have an interrupt router defined in its device tree, no error is generated. Some platforms do not have this.
Drop pirq_init() since it is no-longer used.
Signed-off-by: Simon Glass sjg@chromium.org
Reviewed-by: Bin Meng bmeng.cn@gmail.com
Apply this patch manually on top of dm/next, tested on Crown Bay
Tested-by: Bin Meng bmeng.cn@gmail.com

Most x86 interrupt drivers will want to use the standard PIRQ routing and table setup. Put this code in a common function so it can be used by those drivers that want it.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/cpu/irq.c | 7 ++++++- arch/x86/include/asm/irq.h | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/arch/x86/cpu/irq.c b/arch/x86/cpu/irq.c index 8f59b23..e2feba7 100644 --- a/arch/x86/cpu/irq.c +++ b/arch/x86/cpu/irq.c @@ -231,7 +231,7 @@ static int create_pirq_routing_table(void) return 0; }
-int irq_router_probe(struct udevice *dev) +int irq_router_common_init(struct udevice *dev) { int ret;
@@ -249,6 +249,11 @@ int irq_router_probe(struct udevice *dev) return 0; }
+int irq_router_probe(struct udevice *dev) +{ + return irq_router_common_init(dev); +} + u32 write_pirq_routing_table(u32 addr) { if (!pirq_routing_table) diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h index 74da66e..46e1c31 100644 --- a/arch/x86/include/asm/irq.h +++ b/arch/x86/include/asm/irq.h @@ -65,4 +65,11 @@ struct pirq_routing { */ void cpu_irq_init(void);
+/** + * irq_router_common_init() - Perform common x86 interrupt init + * + * This creates the PIRQ routing table and routes the IRQs + */ +int irq_router_common_init(struct udevice *dev); + #endif /* _ARCH_IRQ_H_ */

On Tue, Dec 1, 2015 at 12:47 PM, Simon Glass sjg@chromium.org wrote:
Most x86 interrupt drivers will want to use the standard PIRQ routing and table setup. Put this code in a common function so it can be used by those drivers that want it.
Signed-off-by: Simon Glass sjg@chromium.org
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On Mon, Dec 14, 2015 at 2:05 PM, Bin Meng bmeng.cn@gmail.com wrote:
On Tue, Dec 1, 2015 at 12:47 PM, Simon Glass sjg@chromium.org wrote:
Most x86 interrupt drivers will want to use the standard PIRQ routing and table setup. Put this code in a common function so it can be used by those drivers that want it.
Signed-off-by: Simon Glass sjg@chromium.org
Reviewed-by: Bin Meng bmeng.cn@gmail.com
Apply this patch manually on top of dm/next, tested on Crown Bay
Tested-by: Bin Meng bmeng.cn@gmail.com

Add a driver for interrupts on quark and move the code currently in cpu_irq_init() into its probe() method.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/cpu/quark/Makefile | 2 +- arch/x86/cpu/quark/irq.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ arch/x86/cpu/quark/quark.c | 25 ----------------------- arch/x86/dts/galileo.dts | 2 +- 4 files changed, 51 insertions(+), 27 deletions(-) create mode 100644 arch/x86/cpu/quark/irq.c
diff --git a/arch/x86/cpu/quark/Makefile b/arch/x86/cpu/quark/Makefile index 8f1d018..6d670d7 100644 --- a/arch/x86/cpu/quark/Makefile +++ b/arch/x86/cpu/quark/Makefile @@ -4,5 +4,5 @@ # SPDX-License-Identifier: GPL-2.0+ #
-obj-y += car.o dram.o msg_port.o quark.o +obj-y += car.o dram.o irq.o msg_port.o quark.o obj-y += mrc.o mrc_util.o hte.o smc.o diff --git a/arch/x86/cpu/quark/irq.c b/arch/x86/cpu/quark/irq.c new file mode 100644 index 0000000..1f8f909 --- /dev/null +++ b/arch/x86/cpu/quark/irq.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com + * Copyright (C) 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <asm/irq.h> +#include <asm/arch/device.h> +#include <asm/arch/quark.h> + +int quark_irq_router_probe(struct udevice *dev) +{ + struct quark_rcba *rcba; + u32 base; + + qrk_pci_read_config_dword(QUARK_LEGACY_BRIDGE, LB_RCBA, &base); + base &= ~MEM_BAR_EN; + rcba = (struct quark_rcba *)base; + + /* + * Route Quark PCI device interrupt pin to PIRQ + * + * Route device#23's INTA/B/C/D to PIRQA/B/C/D + * Route device#20,21's INTA/B/C/D to PIRQE/F/G/H + */ + writew(PIRQC, &rcba->rmu_ir); + writew(PIRQA | (PIRQB << 4) | (PIRQC << 8) | (PIRQD << 12), + &rcba->d23_ir); + writew(PIRQD, &rcba->core_ir); + writew(PIRQE | (PIRQF << 4) | (PIRQG << 8) | (PIRQH << 12), + &rcba->d20d21_ir); + + return irq_router_common_init(dev); +} + +static const struct udevice_id quark_irq_router_ids[] = { + { .compatible = "intel,quark-irq-router" }, + { } +}; + +U_BOOT_DRIVER(quark_irq_router_drv) = { + .name = "quark_intel_irq", + .id = UCLASS_IRQ, + .of_match = quark_irq_router_ids, + .probe = quark_irq_router_probe, +}; diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c index f652d99..3097565 100644 --- a/arch/x86/cpu/quark/quark.c +++ b/arch/x86/cpu/quark/quark.c @@ -7,12 +7,10 @@ #include <common.h> #include <mmc.h> #include <asm/io.h> -#include <asm/irq.h> #include <asm/mrccache.h> #include <asm/mtrr.h> #include <asm/pci.h> #include <asm/post.h> -#include <asm/processor.h> #include <asm/arch/device.h> #include <asm/arch/msg_port.h> #include <asm/arch/quark.h> @@ -341,29 +339,6 @@ int cpu_mmc_init(bd_t *bis) return pci_mmc_init("Quark SDHCI", mmc_supported); }
-void cpu_irq_init(void) -{ - struct quark_rcba *rcba; - u32 base; - - qrk_pci_read_config_dword(QUARK_LEGACY_BRIDGE, LB_RCBA, &base); - base &= ~MEM_BAR_EN; - rcba = (struct quark_rcba *)base; - - /* - * Route Quark PCI device interrupt pin to PIRQ - * - * Route device#23's INTA/B/C/D to PIRQA/B/C/D - * Route device#20,21's INTA/B/C/D to PIRQE/F/G/H - */ - writew(PIRQC, &rcba->rmu_ir); - writew(PIRQA | (PIRQB << 4) | (PIRQC << 8) | (PIRQD << 12), - &rcba->d23_ir); - writew(PIRQD, &rcba->core_ir); - writew(PIRQE | (PIRQF << 4) | (PIRQG << 8) | (PIRQH << 12), - &rcba->d20d21_ir); -} - int arch_misc_init(void) { #ifdef CONFIG_ENABLE_MRC_CACHE diff --git a/arch/x86/dts/galileo.dts b/arch/x86/dts/galileo.dts index 3ee9a33..663d03a 100644 --- a/arch/x86/dts/galileo.dts +++ b/arch/x86/dts/galileo.dts @@ -83,7 +83,7 @@ reg = <0x0000f800 0 0 0 0>;
irq-router { - compatible = "intel,irq-router"; + compatible = "intel,quark-irq-router"; intel,pirq-config = "pci"; intel,pirq-link = <0x60 8>; intel,pirq-mask = <0xdef8>;

On Tue, Dec 1, 2015 at 12:47 PM, Simon Glass sjg@chromium.org wrote:
Add a driver for interrupts on quark and move the code currently in cpu_irq_init() into its probe() method.
Signed-off-by: Simon Glass sjg@chromium.org
Reviewed-by: Bin Meng bmeng.cn@gmail.com

Add a driver for interrupts on queensbay and move the code currently in cpu_irq_init() into its probe() method.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/cpu/queensbay/Makefile | 2 +- arch/x86/cpu/queensbay/irq.c | 65 +++++++++++++++++++++++++++++++++++++++++ arch/x86/cpu/queensbay/tnc.c | 37 ----------------------- arch/x86/dts/crownbay.dts | 2 +- 4 files changed, 67 insertions(+), 39 deletions(-) create mode 100644 arch/x86/cpu/queensbay/irq.c
diff --git a/arch/x86/cpu/queensbay/Makefile b/arch/x86/cpu/queensbay/Makefile index 660f967..af3ffad 100644 --- a/arch/x86/cpu/queensbay/Makefile +++ b/arch/x86/cpu/queensbay/Makefile @@ -4,5 +4,5 @@ # SPDX-License-Identifier: GPL-2.0+ #
-obj-y += fsp_configs.o +obj-y += fsp_configs.o irq.o obj-y += tnc.o topcliff.o diff --git a/arch/x86/cpu/queensbay/irq.c b/arch/x86/cpu/queensbay/irq.c new file mode 100644 index 0000000..44369f7 --- /dev/null +++ b/arch/x86/cpu/queensbay/irq.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2014, Bin Meng bmeng.cn@gmail.com + * Copyright (C) 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/pci.h> +#include <asm/arch/device.h> +#include <asm/arch/tnc.h> + +int queensbay_irq_router_probe(struct udevice *dev) +{ + struct tnc_rcba *rcba; + u32 base; + + base = x86_pci_read_config32(TNC_LPC, LPC_RCBA); + base &= ~MEM_BAR_EN; + rcba = (struct tnc_rcba *)base; + + /* Make sure all internal PCI devices are using INTA */ + writel(INTA, &rcba->d02ip); + writel(INTA, &rcba->d03ip); + writel(INTA, &rcba->d27ip); + writel(INTA, &rcba->d31ip); + writel(INTA, &rcba->d23ip); + writel(INTA, &rcba->d24ip); + writel(INTA, &rcba->d25ip); + writel(INTA, &rcba->d26ip); + + /* + * Route TunnelCreek PCI device interrupt pin to PIRQ + * + * Since PCIe downstream ports received INTx are routed to PIRQ + * A/B/C/D directly and not configurable, we have to route PCIe + * root ports' INTx to PIRQ A/B/C/D as well. For other devices + * on TunneCreek, route them to PIRQ E/F/G/H. + */ + writew(PIRQE, &rcba->d02ir); + writew(PIRQF, &rcba->d03ir); + writew(PIRQG, &rcba->d27ir); + writew(PIRQH, &rcba->d31ir); + writew(PIRQA, &rcba->d23ir); + writew(PIRQB, &rcba->d24ir); + writew(PIRQC, &rcba->d25ir); + writew(PIRQD, &rcba->d26ir); + + return irq_router_common_init(dev); +} + +static const struct udevice_id queensbay_irq_router_ids[] = { + { .compatible = "intel,queensbay-irq-router" }, + { } +}; + +U_BOOT_DRIVER(queensbay_irq_router_drv) = { + .name = "queensbay_intel_irq", + .id = UCLASS_IRQ, + .of_match = queensbay_irq_router_ids, + .probe = queensbay_irq_router_probe, +}; diff --git a/arch/x86/cpu/queensbay/tnc.c b/arch/x86/cpu/queensbay/tnc.c index b65906b..75f7adb 100644 --- a/arch/x86/cpu/queensbay/tnc.c +++ b/arch/x86/cpu/queensbay/tnc.c @@ -69,43 +69,6 @@ int arch_early_init_r(void) return 0; }
-void cpu_irq_init(void) -{ - struct tnc_rcba *rcba; - u32 base; - - base = x86_pci_read_config32(TNC_LPC, LPC_RCBA); - base &= ~MEM_BAR_EN; - rcba = (struct tnc_rcba *)base; - - /* Make sure all internal PCI devices are using INTA */ - writel(INTA, &rcba->d02ip); - writel(INTA, &rcba->d03ip); - writel(INTA, &rcba->d27ip); - writel(INTA, &rcba->d31ip); - writel(INTA, &rcba->d23ip); - writel(INTA, &rcba->d24ip); - writel(INTA, &rcba->d25ip); - writel(INTA, &rcba->d26ip); - - /* - * Route TunnelCreek PCI device interrupt pin to PIRQ - * - * Since PCIe downstream ports received INTx are routed to PIRQ - * A/B/C/D directly and not configurable, we have to route PCIe - * root ports' INTx to PIRQ A/B/C/D as well. For other devices - * on TunneCreek, route them to PIRQ E/F/G/H. - */ - writew(PIRQE, &rcba->d02ir); - writew(PIRQF, &rcba->d03ir); - writew(PIRQG, &rcba->d27ir); - writew(PIRQH, &rcba->d31ir); - writew(PIRQA, &rcba->d23ir); - writew(PIRQB, &rcba->d24ir); - writew(PIRQC, &rcba->d25ir); - writew(PIRQD, &rcba->d26ir); -} - int arch_misc_init(void) { unprotect_spi_flash(); diff --git a/arch/x86/dts/crownbay.dts b/arch/x86/dts/crownbay.dts index 7039332..011f8b5 100644 --- a/arch/x86/dts/crownbay.dts +++ b/arch/x86/dts/crownbay.dts @@ -176,7 +176,7 @@ compatible = "intel,pch7";
irq-router { - compatible = "intel,irq-router"; + compatible = "intel,queensbay-irq-router"; intel,pirq-config = "pci"; intel,pirq-link = <0x60 8>; intel,pirq-mask = <0xcee0>;

On Tue, Dec 1, 2015 at 12:47 PM, Simon Glass sjg@chromium.org wrote:
Add a driver for interrupts on queensbay and move the code currently in cpu_irq_init() into its probe() method.
Signed-off-by: Simon Glass sjg@chromium.org
Reviewed-by: Bin Meng bmeng.cn@gmail.com

There are no callers now. Platforms which need to set up interrupts their own way can implement an interrupt driver. Drop this function.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/cpu/irq.c | 7 ------- arch/x86/include/asm/irq.h | 10 ---------- 2 files changed, 17 deletions(-)
diff --git a/arch/x86/cpu/irq.c b/arch/x86/cpu/irq.c index e2feba7..324866c 100644 --- a/arch/x86/cpu/irq.c +++ b/arch/x86/cpu/irq.c @@ -83,11 +83,6 @@ static inline void fill_irq_info(struct irq_info *slot, int bus, int device, slot->irq[pin - 1].bitmap = irq_router.irq_mask; }
-__weak void cpu_irq_init(void) -{ - return; -} - static int create_pirq_routing_table(void) { const void *blob = gd->fdt_blob; @@ -235,8 +230,6 @@ int irq_router_common_init(struct udevice *dev) { int ret;
- cpu_irq_init(); - ret = create_pirq_routing_table(); if (ret) { debug("Failed to create pirq routing table\n"); diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h index 46e1c31..5b9e673 100644 --- a/arch/x86/include/asm/irq.h +++ b/arch/x86/include/asm/irq.h @@ -56,16 +56,6 @@ struct pirq_routing { #define PIRQ_BITMAP 0xdef8
/** - * cpu_irq_init() - Initialize CPU IRQ routing - * - * This initializes some platform-specific registers related to IRQ routing, - * like configuring internal PCI devices to use which PCI interrupt pin, - * and which PCI interrupt pin is mapped to which PIRQ line. Note on some - * platforms, such IRQ routing might be hard-coded thus cannot configure. - */ -void cpu_irq_init(void); - -/** * irq_router_common_init() - Perform common x86 interrupt init * * This creates the PIRQ routing table and routes the IRQs

On Tue, Dec 1, 2015 at 12:47 PM, Simon Glass sjg@chromium.org wrote:
There are no callers now. Platforms which need to set up interrupts their own way can implement an interrupt driver. Drop this function.
Signed-off-by: Simon Glass sjg@chromium.org
Reviewed-by: Bin Meng bmeng.cn@gmail.com
participants (2)
-
Bin Meng
-
Simon Glass