2012-10-26 09:06:58

by Florian Fainelli

[permalink] [raw]
Subject: [PATCH 0/3] x86: ce4100 fixes and improvements

Hi all,

This patch serie contains shutdown/reboot fixes for the CE4100 platform as
well as a PCI controller fix for devices without an interrupt line.

Florian Fainelli (3):
x86: ce4100: implement pm_poweroff
x86: ce4100: force reboot method to be KBD
x86: ce4100: fixup PCI configuration register access for devices
without interrupts

arch/x86/pci/ce4100.c | 13 +++++++++++++
arch/x86/platform/ce4100/ce4100.c | 10 ++++++++++
2 files changed, 23 insertions(+)

--
1.7.10.4


2012-10-26 09:07:05

by Florian Fainelli

[permalink] [raw]
Subject: [PATCH 3/3] x86: ce4100: fixup PCI configuration register access for devices without interrupts

From: Maxime Bizon <[email protected]>

Some CE4100 devices such as the:
- DFX module (01:0b.7)
- entertainment encryption device (01:10.0)
- multimedia controller (01:12.0)

do not have a device interrupt at all. This patch fixes the PCI controller
code to declare the missing PCI configuration register space, as well as a
fixup method for forcing the interrupt pin to be 0 for these devices. This is
required to ensure that pci drivers matching on these devices will be able to
honor the various PCI subsystem calls touching the configuration space.

Signed-off-by: Florian Fainelli <[email protected]>
---
arch/x86/pci/ce4100.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/arch/x86/pci/ce4100.c b/arch/x86/pci/ce4100.c
index 41bd2a2..b914e20 100644
--- a/arch/x86/pci/ce4100.c
+++ b/arch/x86/pci/ce4100.c
@@ -115,6 +115,16 @@ static void sata_revid_read(struct sim_dev_reg *reg, u32 *value)
reg_read(reg, value);
}

+static void reg_noirq_read(struct sim_dev_reg *reg, u32 *value)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&pci_config_lock, flags);
+ /* force interrupt pin value to 0 */
+ *value = reg->sim_reg.value & 0xfff00ff;
+ raw_spin_unlock_irqrestore(&pci_config_lock, flags);
+}
+
static struct sim_dev_reg bus1_fixups[] = {
DEFINE_REG(2, 0, 0x10, (16*MB), reg_init, reg_read, reg_write)
DEFINE_REG(2, 0, 0x14, (256), reg_init, reg_read, reg_write)
@@ -144,6 +154,7 @@ static struct sim_dev_reg bus1_fixups[] = {
DEFINE_REG(11, 5, 0x10, (64*KB), reg_init, reg_read, reg_write)
DEFINE_REG(11, 6, 0x10, (256), reg_init, reg_read, reg_write)
DEFINE_REG(11, 7, 0x10, (64*KB), reg_init, reg_read, reg_write)
+ DEFINE_REG(11, 7, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
DEFINE_REG(12, 0, 0x10, (128*KB), reg_init, reg_read, reg_write)
DEFINE_REG(12, 0, 0x14, (256), reg_init, reg_read, reg_write)
DEFINE_REG(12, 1, 0x10, (1024), reg_init, reg_read, reg_write)
@@ -161,8 +172,10 @@ static struct sim_dev_reg bus1_fixups[] = {
DEFINE_REG(16, 0, 0x10, (64*KB), reg_init, reg_read, reg_write)
DEFINE_REG(16, 0, 0x14, (64*MB), reg_init, reg_read, reg_write)
DEFINE_REG(16, 0, 0x18, (64*MB), reg_init, reg_read, reg_write)
+ DEFINE_REG(16, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
DEFINE_REG(17, 0, 0x10, (128*KB), reg_init, reg_read, reg_write)
DEFINE_REG(18, 0, 0x10, (1*KB), reg_init, reg_read, reg_write)
+ DEFINE_REG(18, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
};

static void __init init_sim_regs(void)
--
1.7.10.4

2012-10-26 09:07:01

by Florian Fainelli

[permalink] [raw]
Subject: [PATCH 1/3] x86: ce4100: implement pm_poweroff

The CE4100 platform is currently missing a proper pm_poweroff implementation
leading to poweroff making the CPU spin forever and the CE4100 platform does
not enter a low-power mode where the external Power Management Unit can
properly power off the system. Power off on this platform is implemented pretty
much like reboot, by writing to the SoC built-in 8051 microcontroller mapped at
I/O port 0xcf9, the value 0x4.

Signed-off-by: Florian Fainelli <[email protected]>
---
arch/x86/platform/ce4100/ce4100.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c
index 4c61b52..74f8774 100644
--- a/arch/x86/platform/ce4100/ce4100.c
+++ b/arch/x86/platform/ce4100/ce4100.c
@@ -27,6 +27,11 @@ static int ce4100_i8042_detect(void)
return 0;
}

+static void ce4100_power_off(void)
+{
+ outb(0x4, 0xcf9);
+}
+
#ifdef CONFIG_SERIAL_8250

static unsigned int mem_serial_in(struct uart_port *p, int offset)
@@ -143,4 +148,6 @@ void __init x86_ce4100_early_setup(void)
x86_init.pci.init_irq = sdv_pci_init;
x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck;
#endif
+
+ pm_power_off = ce4100_power_off;
}
--
1.7.10.4

2012-10-26 09:09:14

by Florian Fainelli

[permalink] [raw]
Subject: [PATCH 2/3] x86: ce4100: force reboot method to be KBD

From: Maxime Bizon <[email protected]>

The default reboot is via ACPI for this platform, and the CEFDK bootloader
actually supports this, but will issue a system power off instead of a real
reboot. Setting the reboot method to be KBD instead of ACPI ensures proper
system reboot.

Signed-off-by: Florian Fainelli <[email protected]>
---
arch/x86/platform/ce4100/ce4100.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c
index 74f8774..8c9ed9a 100644
--- a/arch/x86/platform/ce4100/ce4100.c
+++ b/arch/x86/platform/ce4100/ce4100.c
@@ -21,6 +21,7 @@
#include <asm/i8259.h>
#include <asm/io.h>
#include <asm/io_apic.h>
+#include <asm/emergency-restart.h>

static int ce4100_i8042_detect(void)
{
@@ -144,6 +145,8 @@ void __init x86_ce4100_early_setup(void)
x86_init.mpparse.find_smp_config = x86_init_noop;
x86_init.pci.init = ce4100_pci_init;

+ reboot_type = BOOT_KBD;
+
#ifdef CONFIG_X86_IO_APIC
x86_init.pci.init_irq = sdv_pci_init;
x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck;
--
1.7.10.4

2012-10-26 09:30:33

by Ingo Molnar

[permalink] [raw]
Subject: Re: [PATCH 1/3] x86: ce4100: implement pm_poweroff


* Florian Fainelli <[email protected]> wrote:

> The CE4100 platform is currently missing a proper pm_poweroff implementation
> leading to poweroff making the CPU spin forever and the CE4100 platform does
> not enter a low-power mode where the external Power Management Unit can
> properly power off the system. Power off on this platform is implemented pretty
> much like reboot, by writing to the SoC built-in 8051 microcontroller mapped at
> I/O port 0xcf9, the value 0x4.
>
> Signed-off-by: Florian Fainelli <[email protected]>
> ---
> arch/x86/platform/ce4100/ce4100.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c
> index 4c61b52..74f8774 100644
> --- a/arch/x86/platform/ce4100/ce4100.c
> +++ b/arch/x86/platform/ce4100/ce4100.c
> @@ -27,6 +27,11 @@ static int ce4100_i8042_detect(void)
> return 0;
> }
>
> +static void ce4100_power_off(void)
> +{
> + outb(0x4, 0xcf9);

Would be nice to precede this function with something like:

/*
* Power off on this platform is implemented pretty
* much like reboot, by writing to the SoC built-in
* 8051 microcontroller mapped at I/O port 0xcf9,
* the magic value 0x4:
*/
static void ce4100_power_off(void)
{
outb(0x4, 0xcf9);
...

As arguably such comments are even more useful in the code than
in a changelog.

Thanks,

Ingo

2012-10-26 09:32:18

by Ingo Molnar

[permalink] [raw]
Subject: Re: [PATCH 2/3] x86: ce4100: force reboot method to be KBD


* Florian Fainelli <[email protected]> wrote:

> From: Maxime Bizon <[email protected]>
>
> The default reboot is via ACPI for this platform, and the CEFDK bootloader
> actually supports this, but will issue a system power off instead of a real
> reboot. Setting the reboot method to be KBD instead of ACPI ensures proper
> system reboot.
>
> Signed-off-by: Florian Fainelli <[email protected]>
> ---
> arch/x86/platform/ce4100/ce4100.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c
> index 74f8774..8c9ed9a 100644
> --- a/arch/x86/platform/ce4100/ce4100.c
> +++ b/arch/x86/platform/ce4100/ce4100.c
> @@ -21,6 +21,7 @@
> #include <asm/i8259.h>
> #include <asm/io.h>
> #include <asm/io_apic.h>
> +#include <asm/emergency-restart.h>
>
> static int ce4100_i8042_detect(void)
> {
> @@ -144,6 +145,8 @@ void __init x86_ce4100_early_setup(void)
> x86_init.mpparse.find_smp_config = x86_init_noop;
> x86_init.pci.init = ce4100_pci_init;
>
> + reboot_type = BOOT_KBD;

Here too put a minimal comment into the code:

/*
* The system default is ACPI reboot, but that powers
* off on CE4100 so the use KBD reset instead:
*/
reboot_type = BOOT_KBD;

Thanks,

Ingo

2012-10-26 11:32:21

by Florian Fainelli

[permalink] [raw]
Subject: [PATCH 1/3 v2] x86: ce4100: implement pm_poweroff

The CE4100 platform is currently missing a proper pm_poweroff implementation
leading to poweroff making the CPU spin forever and the CE4100 platform does
not enter a low-power mode where the external Power Management Unit can
properly power off the system. Power off on this platform is implemented pretty
much like reboot, by writing to the SoC built-in 8051 microcontroller mapped at
I/O port 0xcf9, the value 0x4.

Signed-off-by: Florian Fainelli <[email protected]>
---
Changes since v1:
- added a more detail comment about how the power off method works internally

arch/x86/platform/ce4100/ce4100.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)

diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c
index 4c61b52..5de16e3 100644
--- a/arch/x86/platform/ce4100/ce4100.c
+++ b/arch/x86/platform/ce4100/ce4100.c
@@ -27,6 +27,18 @@ static int ce4100_i8042_detect(void)
return 0;
}

+/*
+ * The CE4100 platform has an internal 8051 Microcontroller which is
+ * responsible for signaling to the external Power Management Unit the
+ * intention to reset, reboot or power off the system. This 8051 device has
+ * its command register mapped at I/O port 0xcf9 and the value 0x4 is used
+ * to power off the system.
+ */
+static void ce4100_power_off(void)
+{
+ outb(0x4, 0xcf9);
+}
+
#ifdef CONFIG_SERIAL_8250

static unsigned int mem_serial_in(struct uart_port *p, int offset)
@@ -143,4 +155,6 @@ void __init x86_ce4100_early_setup(void)
x86_init.pci.init_irq = sdv_pci_init;
x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck;
#endif
+
+ pm_power_off = ce4100_power_off;
}
--
1.7.10.4

2012-10-26 11:32:19

by Florian Fainelli

[permalink] [raw]
Subject: [PATCH 0/3 v2] x86: ce4100 fixes and improvements

Hi all,

This patch serie contains shutdown/reboot fixes for the CE4100 platform as
well as a PCI controller fix for devices without an interrupt line.

Changes since v1:
- added more comment to the pm_poweroff and reboot method fixup

Florian Fainelli (3):
x86: ce4100: implement pm_poweroff
x86: ce4100: force reboot method to be KBD
x86: ce4100: fixup PCI configuration register access for devices
without interrupts

arch/x86/pci/ce4100.c | 13 +++++++++++++
arch/x86/platform/ce4100/ce4100.c | 24 ++++++++++++++++++++++++
2 files changed, 37 insertions(+)

--
1.7.10.4

2012-10-26 11:32:42

by Florian Fainelli

[permalink] [raw]
Subject: [PATCH 2/3 v2] x86: ce4100: force reboot method to be KBD

From: Maxime Bizon <[email protected]>

The default reboot is via ACPI for this platform, and the CEFDK bootloader
actually supports this, but will issue a system power off instead of a real
reboot. Setting the reboot method to be KBD instead of ACPI ensures proper
system reboot.

Signed-off-by: Florian Fainelli <[email protected]>
---
Changes since v1:
- added comment to explain why KBD reboot method is to be used

arch/x86/platform/ce4100/ce4100.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c
index 5de16e3..92525cb 100644
--- a/arch/x86/platform/ce4100/ce4100.c
+++ b/arch/x86/platform/ce4100/ce4100.c
@@ -21,6 +21,7 @@
#include <asm/i8259.h>
#include <asm/io.h>
#include <asm/io_apic.h>
+#include <asm/emergency-restart.h>

static int ce4100_i8042_detect(void)
{
@@ -151,6 +152,15 @@ void __init x86_ce4100_early_setup(void)
x86_init.mpparse.find_smp_config = x86_init_noop;
x86_init.pci.init = ce4100_pci_init;

+ /*
+ * By default, the reboot method is ACPI which is supported by the
+ * CE4100 bootloader CEFDK using FADT.ResetReg Address and ResetValue
+ * the bootloader will however issue a system power off instead of
+ * reboot. By using BOOT_KBD we ensure proper system reboot as
+ * expected.
+ */
+ reboot_type = BOOT_KBD;
+
#ifdef CONFIG_X86_IO_APIC
x86_init.pci.init_irq = sdv_pci_init;
x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck;
--
1.7.10.4

2012-10-26 11:32:57

by Florian Fainelli

[permalink] [raw]
Subject: [PATCH 3/3] x86: ce4100: fixup PCI configuration register access for devices without interrupts

From: Maxime Bizon <[email protected]>

Some CE4100 devices such as the:
- DFX module (01:0b.7)
- entertainment encryption device (01:10.0)
- multimedia controller (01:12.0)

do not have a device interrupt at all. This patch fixes the PCI controller
code to declare the missing PCI configuration register space, as well as a
fixup method for forcing the interrupt pin to be 0 for these devices. This is
required to ensure that pci drivers matching on these devices will be able to
honor the various PCI subsystem calls touching the configuration space.

Signed-off-by: Florian Fainelli <[email protected]>
---
arch/x86/pci/ce4100.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/arch/x86/pci/ce4100.c b/arch/x86/pci/ce4100.c
index 41bd2a2..b914e20 100644
--- a/arch/x86/pci/ce4100.c
+++ b/arch/x86/pci/ce4100.c
@@ -115,6 +115,16 @@ static void sata_revid_read(struct sim_dev_reg *reg, u32 *value)
reg_read(reg, value);
}

+static void reg_noirq_read(struct sim_dev_reg *reg, u32 *value)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&pci_config_lock, flags);
+ /* force interrupt pin value to 0 */
+ *value = reg->sim_reg.value & 0xfff00ff;
+ raw_spin_unlock_irqrestore(&pci_config_lock, flags);
+}
+
static struct sim_dev_reg bus1_fixups[] = {
DEFINE_REG(2, 0, 0x10, (16*MB), reg_init, reg_read, reg_write)
DEFINE_REG(2, 0, 0x14, (256), reg_init, reg_read, reg_write)
@@ -144,6 +154,7 @@ static struct sim_dev_reg bus1_fixups[] = {
DEFINE_REG(11, 5, 0x10, (64*KB), reg_init, reg_read, reg_write)
DEFINE_REG(11, 6, 0x10, (256), reg_init, reg_read, reg_write)
DEFINE_REG(11, 7, 0x10, (64*KB), reg_init, reg_read, reg_write)
+ DEFINE_REG(11, 7, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
DEFINE_REG(12, 0, 0x10, (128*KB), reg_init, reg_read, reg_write)
DEFINE_REG(12, 0, 0x14, (256), reg_init, reg_read, reg_write)
DEFINE_REG(12, 1, 0x10, (1024), reg_init, reg_read, reg_write)
@@ -161,8 +172,10 @@ static struct sim_dev_reg bus1_fixups[] = {
DEFINE_REG(16, 0, 0x10, (64*KB), reg_init, reg_read, reg_write)
DEFINE_REG(16, 0, 0x14, (64*MB), reg_init, reg_read, reg_write)
DEFINE_REG(16, 0, 0x18, (64*MB), reg_init, reg_read, reg_write)
+ DEFINE_REG(16, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
DEFINE_REG(17, 0, 0x10, (128*KB), reg_init, reg_read, reg_write)
DEFINE_REG(18, 0, 0x10, (1*KB), reg_init, reg_read, reg_write)
+ DEFINE_REG(18, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
};

static void __init init_sim_regs(void)
--
1.7.10.4

2012-10-26 14:58:24

by Ingo Molnar

[permalink] [raw]
Subject: Re: [PATCH 2/3 v2] x86: ce4100: force reboot method to be KBD


* Florian Fainelli <[email protected]> wrote:

> From: Maxime Bizon <[email protected]>

> Signed-off-by: Florian Fainelli <[email protected]>

The SOB from Maxime is missing?

Thanks,

Ingo

2012-10-29 13:41:50

by Florian Fainelli

[permalink] [raw]
Subject: [PATCH 3/3 v3] x86: ce4100: fixup PCI configuration register access for devices without interrupts

From: Maxime Bizon <[email protected]>

Some CE4100 devices such as the:
- DFX module (01:0b.7)
- entertainment encryption device (01:10.0)
- multimedia controller (01:12.0)

do not have a device interrupt at all. This patch fixes the PCI controller
code to declare the missing PCI configuration register space, as well as a
fixup method for forcing the interrupt pin to be 0 for these devices. This is
required to ensure that pci drivers matching on these devices will be able to
honor the various PCI subsystem calls touching the configuration space.

Signed-off-by: Maxime Bizon <[email protected]>
Signed-off-by: Florian Fainelli <[email protected]>
Acked-by: Sebastian Andrzej Siewior <[email protected]>
---
arch/x86/pci/ce4100.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/arch/x86/pci/ce4100.c b/arch/x86/pci/ce4100.c
index 41bd2a2..b914e20 100644
--- a/arch/x86/pci/ce4100.c
+++ b/arch/x86/pci/ce4100.c
@@ -115,6 +115,16 @@ static void sata_revid_read(struct sim_dev_reg *reg, u32 *value)
reg_read(reg, value);
}

+static void reg_noirq_read(struct sim_dev_reg *reg, u32 *value)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&pci_config_lock, flags);
+ /* force interrupt pin value to 0 */
+ *value = reg->sim_reg.value & 0xfff00ff;
+ raw_spin_unlock_irqrestore(&pci_config_lock, flags);
+}
+
static struct sim_dev_reg bus1_fixups[] = {
DEFINE_REG(2, 0, 0x10, (16*MB), reg_init, reg_read, reg_write)
DEFINE_REG(2, 0, 0x14, (256), reg_init, reg_read, reg_write)
@@ -144,6 +154,7 @@ static struct sim_dev_reg bus1_fixups[] = {
DEFINE_REG(11, 5, 0x10, (64*KB), reg_init, reg_read, reg_write)
DEFINE_REG(11, 6, 0x10, (256), reg_init, reg_read, reg_write)
DEFINE_REG(11, 7, 0x10, (64*KB), reg_init, reg_read, reg_write)
+ DEFINE_REG(11, 7, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
DEFINE_REG(12, 0, 0x10, (128*KB), reg_init, reg_read, reg_write)
DEFINE_REG(12, 0, 0x14, (256), reg_init, reg_read, reg_write)
DEFINE_REG(12, 1, 0x10, (1024), reg_init, reg_read, reg_write)
@@ -161,8 +172,10 @@ static struct sim_dev_reg bus1_fixups[] = {
DEFINE_REG(16, 0, 0x10, (64*KB), reg_init, reg_read, reg_write)
DEFINE_REG(16, 0, 0x14, (64*MB), reg_init, reg_read, reg_write)
DEFINE_REG(16, 0, 0x18, (64*MB), reg_init, reg_read, reg_write)
+ DEFINE_REG(16, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
DEFINE_REG(17, 0, 0x10, (128*KB), reg_init, reg_read, reg_write)
DEFINE_REG(18, 0, 0x10, (1*KB), reg_init, reg_read, reg_write)
+ DEFINE_REG(18, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
};

static void __init init_sim_regs(void)
--
1.7.10.4

2012-10-29 13:41:48

by Florian Fainelli

[permalink] [raw]
Subject: [PATCH 2/3 v3] x86: ce4100: force reboot method to be KBD

From: Maxime Bizon <[email protected]>

The default reboot is via ACPI for this platform, and the CEFDK bootloader
actually supports this, but will issue a system power off instead of a real
reboot. Setting the reboot method to be KBD instead of ACPI ensures proper
system reboot.

Acked-by: Sebastian Andrzej Siewior <[email protected]>
Signed-off-by: Maxime Bizon <[email protected]>
Signed-off-by: Florian Fainelli <[email protected]>
---
arch/x86/platform/ce4100/ce4100.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c
index 5de16e3..92525cb 100644
--- a/arch/x86/platform/ce4100/ce4100.c
+++ b/arch/x86/platform/ce4100/ce4100.c
@@ -21,6 +21,7 @@
#include <asm/i8259.h>
#include <asm/io.h>
#include <asm/io_apic.h>
+#include <asm/emergency-restart.h>

static int ce4100_i8042_detect(void)
{
@@ -151,6 +152,15 @@ void __init x86_ce4100_early_setup(void)
x86_init.mpparse.find_smp_config = x86_init_noop;
x86_init.pci.init = ce4100_pci_init;

+ /*
+ * By default, the reboot method is ACPI which is supported by the
+ * CE4100 bootloader CEFDK using FADT.ResetReg Address and ResetValue
+ * the bootloader will however issue a system power off instead of
+ * reboot. By using BOOT_KBD we ensure proper system reboot as
+ * expected.
+ */
+ reboot_type = BOOT_KBD;
+
#ifdef CONFIG_X86_IO_APIC
x86_init.pci.init_irq = sdv_pci_init;
x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck;
--
1.7.10.4

2012-10-29 13:41:47

by Florian Fainelli

[permalink] [raw]
Subject: [PATCH 1/3 v3] x86: ce4100: implement pm_poweroff

The CE4100 platform is currently missing a proper pm_poweroff implementation
leading to poweroff making the CPU spin forever and the CE4100 platform does
not enter a low-power mode where the external Power Management Unit can
properly power off the system. Power off on this platform is implemented pretty
much like reboot, by writing to the SoC built-in 8051 microcontroller mapped at
I/O port 0xcf9, the value 0x4.

Acked-by: Sebastian Andrzej Siewior <[email protected]>
Signed-off-by: Florian Fainelli <[email protected]>
---
arch/x86/platform/ce4100/ce4100.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)

diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c
index 4c61b52..5de16e3 100644
--- a/arch/x86/platform/ce4100/ce4100.c
+++ b/arch/x86/platform/ce4100/ce4100.c
@@ -27,6 +27,18 @@ static int ce4100_i8042_detect(void)
return 0;
}

+/*
+ * The CE4100 platform has an internal 8051 Microcontroller which is
+ * responsible for signaling to the external Power Management Unit the
+ * intention to reset, reboot or power off the system. This 8051 device has
+ * its command register mapped at I/O port 0xcf9 and the value 0x4 is used
+ * to power off the system.
+ */
+static void ce4100_power_off(void)
+{
+ outb(0x4, 0xcf9);
+}
+
#ifdef CONFIG_SERIAL_8250

static unsigned int mem_serial_in(struct uart_port *p, int offset)
@@ -143,4 +155,6 @@ void __init x86_ce4100_early_setup(void)
x86_init.pci.init_irq = sdv_pci_init;
x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck;
#endif
+
+ pm_power_off = ce4100_power_off;
}
--
1.7.10.4

2012-10-29 13:42:32

by Florian Fainelli

[permalink] [raw]
Subject: [PATCH 0/3 v3] x86: ce4100 fixes and improvements

Hi all,

This patch serie contains shutdown/reboot fixes for the CE4100 platform as
well as a PCI controller fix for devices without an interrupt line.

Changes since v2:
- added Sebastian's Acked-by
- added Maxime's missing Signed-off-by

Changes since v1:
- added more comment to the pm_poweroff and reboot method fixup

Florian Fainelli (3):
x86: ce4100: implement pm_poweroff
x86: ce4100: force reboot method to be KBD
x86: ce4100: fixup PCI configuration register access for devices
without interrupts

arch/x86/pci/ce4100.c | 13 +++++++++++++
arch/x86/platform/ce4100/ce4100.c | 24 ++++++++++++++++++++++++
2 files changed, 37 insertions(+)

--
1.7.10.4

2012-10-30 12:26:00

by Florian Fainelli

[permalink] [raw]
Subject: [tip:x86/urgent] x86/ce4100: Fix pm_poweroff

Commit-ID: f49f4ab95c301dbccad0efe85296d908b8ae7ad4
Gitweb: http://git.kernel.org/tip/f49f4ab95c301dbccad0efe85296d908b8ae7ad4
Author: Florian Fainelli <[email protected]>
AuthorDate: Mon, 29 Oct 2012 14:40:18 +0100
Committer: Ingo Molnar <[email protected]>
CommitDate: Tue, 30 Oct 2012 10:16:46 +0100

x86/ce4100: Fix pm_poweroff

The CE4100 platform is currently missing a proper pm_poweroff
implementation leading to poweroff making the CPU spin forever
and the CE4100 platform does not enter a low-power mode where
the external Power Management Unit can properly power off the
system. Power off on this platform is implemented pretty much
like reboot, by writing to the SoC built-in 8051 microcontroller
mapped at I/O port 0xcf9, the value 0x4.

Signed-off-by: Florian Fainelli <[email protected]>
Acked-by: Sebastian Andrzej Siewior <[email protected]>
Cc: [email protected]
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
---
arch/x86/platform/ce4100/ce4100.c | 14 ++++++++++++++
1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c
index 4c61b52..5de16e3 100644
--- a/arch/x86/platform/ce4100/ce4100.c
+++ b/arch/x86/platform/ce4100/ce4100.c
@@ -27,6 +27,18 @@ static int ce4100_i8042_detect(void)
return 0;
}

+/*
+ * The CE4100 platform has an internal 8051 Microcontroller which is
+ * responsible for signaling to the external Power Management Unit the
+ * intention to reset, reboot or power off the system. This 8051 device has
+ * its command register mapped at I/O port 0xcf9 and the value 0x4 is used
+ * to power off the system.
+ */
+static void ce4100_power_off(void)
+{
+ outb(0x4, 0xcf9);
+}
+
#ifdef CONFIG_SERIAL_8250

static unsigned int mem_serial_in(struct uart_port *p, int offset)
@@ -143,4 +155,6 @@ void __init x86_ce4100_early_setup(void)
x86_init.pci.init_irq = sdv_pci_init;
x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck;
#endif
+
+ pm_power_off = ce4100_power_off;
}

2012-10-30 12:27:01

by Maxime Bizon

[permalink] [raw]
Subject: [tip:x86/urgent] x86/ce4100: Fix reboot by forcing the reboot method to be KBD

Commit-ID: d7959916026aaae60e1878ae33c7503b2cc4471d
Gitweb: http://git.kernel.org/tip/d7959916026aaae60e1878ae33c7503b2cc4471d
Author: Maxime Bizon <[email protected]>
AuthorDate: Mon, 29 Oct 2012 14:40:19 +0100
Committer: Ingo Molnar <[email protected]>
CommitDate: Tue, 30 Oct 2012 10:16:46 +0100

x86/ce4100: Fix reboot by forcing the reboot method to be KBD

The default reboot is via ACPI for this platform, and the CEFDK
bootloader actually supports this, but will issue a system power
off instead of a real reboot. Setting the reboot method to be
KBD instead of ACPI ensures proper system reboot.

Acked-by: Sebastian Andrzej Siewior <[email protected]>
Signed-off-by: Maxime Bizon <[email protected]>
Signed-off-by: Florian Fainelli <[email protected]>
Cc: [email protected]
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
---
arch/x86/platform/ce4100/ce4100.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c
index 5de16e3..92525cb 100644
--- a/arch/x86/platform/ce4100/ce4100.c
+++ b/arch/x86/platform/ce4100/ce4100.c
@@ -21,6 +21,7 @@
#include <asm/i8259.h>
#include <asm/io.h>
#include <asm/io_apic.h>
+#include <asm/emergency-restart.h>

static int ce4100_i8042_detect(void)
{
@@ -151,6 +152,15 @@ void __init x86_ce4100_early_setup(void)
x86_init.mpparse.find_smp_config = x86_init_noop;
x86_init.pci.init = ce4100_pci_init;

+ /*
+ * By default, the reboot method is ACPI which is supported by the
+ * CE4100 bootloader CEFDK using FADT.ResetReg Address and ResetValue
+ * the bootloader will however issue a system power off instead of
+ * reboot. By using BOOT_KBD we ensure proper system reboot as
+ * expected.
+ */
+ reboot_type = BOOT_KBD;
+
#ifdef CONFIG_X86_IO_APIC
x86_init.pci.init_irq = sdv_pci_init;
x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck;

2012-10-30 12:27:59

by Maxime Bizon

[permalink] [raw]
Subject: [tip:x86/urgent] x86/ce4100: Fix PCI configuration register access for devices without interrupts

Commit-ID: 37aeec36220c39f1b2e7118287d951fd9cfdd6b7
Gitweb: http://git.kernel.org/tip/37aeec36220c39f1b2e7118287d951fd9cfdd6b7
Author: Maxime Bizon <[email protected]>
AuthorDate: Mon, 29 Oct 2012 14:40:20 +0100
Committer: Ingo Molnar <[email protected]>
CommitDate: Tue, 30 Oct 2012 10:16:47 +0100

x86/ce4100: Fix PCI configuration register access for devices without interrupts

Some CE4100 devices such as the:

- DFX module (01:0b.7)
- entertainment encryption device (01:10.0)
- multimedia controller (01:12.0)

do not have a device interrupt at all.

This patch fixes the PCI controller code to declare the missing
PCI configuration register space, as well as a fixup method for
forcing the interrupt pin to be 0 for these devices. This is
required to ensure that pci drivers matching on these devices
will be able to honor the various PCI subsystem calls touching
the configuration space.

Signed-off-by: Maxime Bizon <[email protected]>
Signed-off-by: Florian Fainelli <[email protected]>
Acked-by: Sebastian Andrzej Siewior <[email protected]>
Cc: [email protected]
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
---
arch/x86/pci/ce4100.c | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/arch/x86/pci/ce4100.c b/arch/x86/pci/ce4100.c
index 41bd2a2..b914e20 100644
--- a/arch/x86/pci/ce4100.c
+++ b/arch/x86/pci/ce4100.c
@@ -115,6 +115,16 @@ static void sata_revid_read(struct sim_dev_reg *reg, u32 *value)
reg_read(reg, value);
}

+static void reg_noirq_read(struct sim_dev_reg *reg, u32 *value)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&pci_config_lock, flags);
+ /* force interrupt pin value to 0 */
+ *value = reg->sim_reg.value & 0xfff00ff;
+ raw_spin_unlock_irqrestore(&pci_config_lock, flags);
+}
+
static struct sim_dev_reg bus1_fixups[] = {
DEFINE_REG(2, 0, 0x10, (16*MB), reg_init, reg_read, reg_write)
DEFINE_REG(2, 0, 0x14, (256), reg_init, reg_read, reg_write)
@@ -144,6 +154,7 @@ static struct sim_dev_reg bus1_fixups[] = {
DEFINE_REG(11, 5, 0x10, (64*KB), reg_init, reg_read, reg_write)
DEFINE_REG(11, 6, 0x10, (256), reg_init, reg_read, reg_write)
DEFINE_REG(11, 7, 0x10, (64*KB), reg_init, reg_read, reg_write)
+ DEFINE_REG(11, 7, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
DEFINE_REG(12, 0, 0x10, (128*KB), reg_init, reg_read, reg_write)
DEFINE_REG(12, 0, 0x14, (256), reg_init, reg_read, reg_write)
DEFINE_REG(12, 1, 0x10, (1024), reg_init, reg_read, reg_write)
@@ -161,8 +172,10 @@ static struct sim_dev_reg bus1_fixups[] = {
DEFINE_REG(16, 0, 0x10, (64*KB), reg_init, reg_read, reg_write)
DEFINE_REG(16, 0, 0x14, (64*MB), reg_init, reg_read, reg_write)
DEFINE_REG(16, 0, 0x18, (64*MB), reg_init, reg_read, reg_write)
+ DEFINE_REG(16, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
DEFINE_REG(17, 0, 0x10, (128*KB), reg_init, reg_read, reg_write)
DEFINE_REG(18, 0, 0x10, (1*KB), reg_init, reg_read, reg_write)
+ DEFINE_REG(18, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
};

static void __init init_sim_regs(void)