[U-Boot] [PATCH v3 0/8] 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.
Changes in v3: - Add new patch to use the IRQ device when setting up the mptable - Add new patch to drop the irq router compatible string
Changes in v2: - Rebase on top of updated SPI flash series
Simon Glass (8): 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 x86: Use the IRQ device when setting up the mptable x86: Drop the irq router compatible string 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 | 48 ++++++++++++++++------------ 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 ++--------- arch/x86/lib/mpspec.c | 14 ++++---- include/configs/qemu-x86.h | 1 - include/dm/uclass-id.h | 1 + include/fdtdec.h | 1 - lib/fdtdec.c | 1 - 18 files changed, 169 insertions(+), 120 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 Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v3: None Changes in v2: None
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 */

On Wed, Jan 20, 2016 at 12:32 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
Changes in v3: None Changes in v2: None
arch/x86/cpu/irq.c | 25 +++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + 2 files changed, 26 insertions(+)
applied to u-boot-x86/master, thanks!

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 Tested-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v3: None Changes in v2: None
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 46111c9..5a7b929 100644 --- a/arch/x86/cpu/qemu/qemu.c +++ b/arch/x86/cpu/qemu/qemu.c @@ -96,11 +96,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 Wed, Jan 20, 2016 at 12:32 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 Tested-by: Bin Meng bmeng.cn@gmail.com
Changes in v3: None Changes in v2: None
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(-)
applied to u-boot-x86/master, thanks!

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 ---
Changes in v3: None Changes in v2: None
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 Wed, Jan 20, 2016 at 12:32 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
Changes in v3: None Changes in v2: None
arch/x86/cpu/irq.c | 7 ++++++- arch/x86/include/asm/irq.h | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-)
applied to u-boot-x86/master, thanks!

Instead of searching for the device tree node, use the IRQ device which has a record of it.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Add new patch to use the IRQ device when setting up the mptable
Changes in v2: None
arch/x86/cpu/irq.c | 16 ++++------------ arch/x86/lib/mpspec.c | 14 +++++++------- 2 files changed, 11 insertions(+), 19 deletions(-)
diff --git a/arch/x86/cpu/irq.c b/arch/x86/cpu/irq.c index e2feba7..d6151e0 100644 --- a/arch/x86/cpu/irq.c +++ b/arch/x86/cpu/irq.c @@ -88,7 +88,7 @@ __weak void cpu_irq_init(void) return; }
-static int create_pirq_routing_table(void) +static int create_pirq_routing_table(struct udevice *dev) { const void *blob = gd->fdt_blob; struct fdt_pci_addr addr; @@ -102,16 +102,8 @@ static int create_pirq_routing_table(void) int i; int ret;
- node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_IRQ_ROUTER); - if (node < 0) { - debug("%s: Cannot find irq router node\n", __func__); - return -EINVAL; - } - - /* TODO(sjg@chromium.org): Drop this when PIRQ is a driver */ - parent = fdt_parent_offset(blob, node); - if (parent < 0) - return -EINVAL; + node = dev->of_offset; + parent = dev->parent->of_offset; ret = fdtdec_get_pci_addr(blob, parent, FDT_PCI_SPACE_CONFIG, "reg", &addr); if (ret) @@ -237,7 +229,7 @@ int irq_router_common_init(struct udevice *dev)
cpu_irq_init();
- ret = create_pirq_routing_table(); + ret = create_pirq_routing_table(dev); if (ret) { debug("Failed to create pirq routing table\n"); return ret; diff --git a/arch/x86/lib/mpspec.c b/arch/x86/lib/mpspec.c index f3ad116..0faa582 100644 --- a/arch/x86/lib/mpspec.c +++ b/arch/x86/lib/mpspec.c @@ -292,19 +292,19 @@ static int mptable_add_intsrc(struct mp_config_table *mc, struct mpc_config_intsrc *intsrc_base; int intsrc_entries = 0; const void *blob = gd->fdt_blob; - int node; + struct udevice *dev; int len, count; const u32 *cell; - int i; + int i, ret;
- /* Get I/O interrupt information from device tree */ - node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_IRQ_ROUTER); - if (node < 0) { + ret = uclass_first_device(UCLASS_IRQ, &dev); + if (ret && ret != -ENODEV) { debug("%s: Cannot find irq router node\n", __func__); - return -ENOENT; + return ret; }
- cell = fdt_getprop(blob, node, "intel,pirq-routing", &len); + /* Get I/O interrupt information from device tree */ + cell = fdt_getprop(blob, dev->of_offset, "intel,pirq-routing", &len); if (!cell) return -ENOENT;

On Wed, Jan 20, 2016 at 12:32 PM, Simon Glass sjg@chromium.org wrote:
Instead of searching for the device tree node, use the IRQ device which has a record of it.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Add new patch to use the IRQ device when setting up the mptable
Changes in v2: None
arch/x86/cpu/irq.c | 16 ++++------------ arch/x86/lib/mpspec.c | 14 +++++++------- 2 files changed, 11 insertions(+), 19 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com Tested-by: Bin Meng bmeng.cn@gmail.com

On Wed, Jan 20, 2016 at 5:28 PM, Bin Meng bmeng.cn@gmail.com wrote:
On Wed, Jan 20, 2016 at 12:32 PM, Simon Glass sjg@chromium.org wrote:
Instead of searching for the device tree node, use the IRQ device which has a record of it.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Add new patch to use the IRQ device when setting up the mptable
Changes in v2: None
arch/x86/cpu/irq.c | 16 ++++------------ arch/x86/lib/mpspec.c | 14 +++++++------- 2 files changed, 11 insertions(+), 19 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com Tested-by: Bin Meng bmeng.cn@gmail.com
applied to u-boot-x86/master, thanks!

We use driver model for this now, so we don't need this string.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Add new patch to drop the irq router compatible string
Changes in v2: None
include/fdtdec.h | 1 - lib/fdtdec.c | 1 - 2 files changed, 2 deletions(-)
diff --git a/include/fdtdec.h b/include/fdtdec.h index 27b350e..285da95 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -164,7 +164,6 @@ enum fdt_compat_id { COMPAT_INTEL_X86_PINCTRL, /* Intel ICH7/9 pin control */ COMPAT_SOCIONEXT_XHCI, /* Socionext UniPhier xHCI */ COMPAT_INTEL_PCH, /* Intel PCH */ - COMPAT_INTEL_IRQ_ROUTER, /* Intel Interrupt Router */ COMPAT_ALTERA_SOCFPGA_DWMAC, /* SoCFPGA Ethernet controller */ COMPAT_ALTERA_SOCFPGA_DWMMC, /* SoCFPGA DWMMC controller */ COMPAT_ALTERA_SOCFPGA_DWC2USB, /* SoCFPGA DWC2 USB controller */ diff --git a/lib/fdtdec.c b/lib/fdtdec.c index b50d105..4b8fc0c 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -69,7 +69,6 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(INTEL_X86_PINCTRL, "intel,x86-pinctrl"), COMPAT(SOCIONEXT_XHCI, "socionext,uniphier-xhci"), COMPAT(COMPAT_INTEL_PCH, "intel,bd82x6x"), - COMPAT(COMPAT_INTEL_IRQ_ROUTER, "intel,irq-router"), COMPAT(ALTERA_SOCFPGA_DWMAC, "altr,socfpga-stmmac"), COMPAT(ALTERA_SOCFPGA_DWMMC, "altr,socfpga-dw-mshc"), COMPAT(ALTERA_SOCFPGA_DWC2USB, "snps,dwc2"),

On Wed, Jan 20, 2016 at 12:32 PM, Simon Glass sjg@chromium.org wrote:
We use driver model for this now, so we don't need this string.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Add new patch to drop the irq router compatible string
Changes in v2: None
include/fdtdec.h | 1 - lib/fdtdec.c | 1 - 2 files changed, 2 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On Wed, Jan 20, 2016 at 5:28 PM, Bin Meng bmeng.cn@gmail.com wrote:
On Wed, Jan 20, 2016 at 12:32 PM, Simon Glass sjg@chromium.org wrote:
We use driver model for this now, so we don't need this string.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Add new patch to drop the irq router compatible string
Changes in v2: None
include/fdtdec.h | 1 - lib/fdtdec.c | 1 - 2 files changed, 2 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com
applied to u-boot-x86/master, thanks!

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 ---
Changes in v3: None Changes in v2: None
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 9d82bb3..a2f5a1f 100644 --- a/arch/x86/dts/galileo.dts +++ b/arch/x86/dts/galileo.dts @@ -84,7 +84,7 @@ compatible = "intel,pch7";
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 Wed, Jan 20, 2016 at 12:32 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
Changes in v3: None Changes in v2: None
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
Tested-by: Bin Meng bmeng.cn@gmail.com

On Wed, Jan 20, 2016 at 5:28 PM, Bin Meng bmeng.cn@gmail.com wrote:
On Wed, Jan 20, 2016 at 12:32 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
Changes in v3: None Changes in v2: None
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
Tested-by: Bin Meng bmeng.cn@gmail.com
applied to u-boot-x86/master, thanks!

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 ---
Changes in v3: None Changes in v2: None
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 2a18be0..d6dd0b4 100644 --- a/arch/x86/dts/crownbay.dts +++ b/arch/x86/dts/crownbay.dts @@ -164,7 +164,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 Wed, Jan 20, 2016 at 12:32 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
Changes in v3: None Changes in v2: None
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
Tested-by: Bin Meng bmeng.cn@gmail.com

Hi Bin,
On 20 January 2016 at 02:28, Bin Meng bmeng.cn@gmail.com wrote:
On Wed, Jan 20, 2016 at 12:32 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
Changes in v3: None Changes in v2: None
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
Tested-by: Bin Meng bmeng.cn@gmail.com
OK I'm pleased this works - thanks for testing it. I'll leave you to apply it.
Regards, Simon

On Wed, Jan 20, 2016 at 5:28 PM, Bin Meng bmeng.cn@gmail.com wrote:
On Wed, Jan 20, 2016 at 12:32 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
Changes in v3: None Changes in v2: None
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
Tested-by: Bin Meng bmeng.cn@gmail.com
applied to u-boot-x86/master, thanks!

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 ---
Changes in v3: None Changes in v2: - Rebase on top of updated SPI flash series
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 d6151e0..0b36ace 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(struct udevice *dev) { const void *blob = gd->fdt_blob; @@ -227,8 +222,6 @@ int irq_router_common_init(struct udevice *dev) { int ret;
- cpu_irq_init(); - ret = create_pirq_routing_table(dev); 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 Wed, Jan 20, 2016 at 12:32 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
Changes in v3: None Changes in v2:
- Rebase on top of updated SPI flash series
arch/x86/cpu/irq.c | 7 ------- arch/x86/include/asm/irq.h | 10 ---------- 2 files changed, 17 deletions(-)
applied to u-boot-x86/master, thanks!
participants (2)
-
Bin Meng
-
Simon Glass