Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1475299 > unrolled thread

[PATCH 00/12] Partial MIPS Malta DT conversion

Started byPaul Burton <paul.burton@imgtec.com>
First post2016-09-02 18:00 +0200
Last post2016-09-02 18:30 +0200
Articles 6 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 00/12] Partial MIPS Malta DT conversion Paul Burton <paul.burton@imgtec.com> - 2016-09-02 18:00 +0200
    [PATCH 05/12] MIPS: Malta: Use all available DDR by default Paul Burton <paul.burton@imgtec.com> - 2016-09-02 18:00 +0200
      Re: [PATCH 05/12] MIPS: Malta: Use all available DDR by default kbuild test robot <lkp@intel.com> - 2016-09-03 12:30 +0200
    [PATCH 03/12] irqchip: i8259: Remove unused i8259A_irq_pending Paul Burton <paul.burton@imgtec.com> - 2016-09-02 18:00 +0200
    [PATCH 11/12] power: reset: Add Intel PIIX4 poweroff driver Paul Burton <paul.burton@imgtec.com> - 2016-09-02 18:00 +0200
      Re: [PATCH 11/12] power: reset: Add Intel PIIX4 poweroff driver Sebastian Reichel <sre@kernel.org> - 2016-09-02 18:30 +0200

#1475299 — [PATCH 00/12] Partial MIPS Malta DT conversion

FromPaul Burton <paul.burton@imgtec.com>
Date2016-09-02 18:00 +0200
Subject[PATCH 00/12] Partial MIPS Malta DT conversion
Message-ID<scZ2O-1kr-3@gated-at.bofh.it>
This series begins converting the MIPS Malta board to use device tree to
probe its various devices & peripherals, with the eventual goal of
including Malta support in generic kernels.

In terms of use the only change should be that kernels will
automatically make use of more than 256MB DDR when built for 64 bit, or
32 bit with highmem enabled.

The series leaves Malta with a significant amount less platform code and
thus closer to being ready for inclusion in a generic MIPS kernel.

Applies atop v4.8-rc4.

Paul Burton (12):
  irqchip: i8259: Add domain before mapping parent irq
  irqchip: i8259: Allow platforms to override poll function
  irqchip: i8259: Remove unused i8259A_irq_pending
  MIPS: Malta: Allow PCI devices DMA to lower 2GB physical
  MIPS: Malta: Use all available DDR by default
  MIPS: Malta: Probe interrupt controllers via DT
  MIPS: Malta: Probe RTC via DT
  MIPS: Malta: Probe pflash via DT
  MIPS: Malta: Use syscon-reboot driver to reboot
  MIPS: Malta: Remove custom halt implementation
  power: reset: Add Intel PIIX4 poweroff driver
  MIPS: Malta: Use PIIX4 poweroff driver to power down

 arch/mips/Kconfig                           |   7 +-
 arch/mips/boot/dts/mti/malta.dts            |  93 ++++++++++++++
 arch/mips/configs/malta_defconfig           |   5 +-
 arch/mips/configs/malta_kvm_defconfig       |   5 +-
 arch/mips/configs/malta_kvm_guest_defconfig |   5 +-
 arch/mips/configs/malta_qemu_32r6_defconfig |   3 +
 arch/mips/configs/maltaaprp_defconfig       |   3 +
 arch/mips/configs/maltasmvp_defconfig       |   3 +
 arch/mips/configs/maltasmvp_eva_defconfig   |   3 +
 arch/mips/configs/maltaup_defconfig         |   3 +
 arch/mips/configs/maltaup_xpa_defconfig     |   5 +-
 arch/mips/include/asm/i8259.h               |  12 +-
 arch/mips/mti-malta/Makefile                |   3 -
 arch/mips/mti-malta/malta-dtshim.c          | 187 +++++++++++++++++++++++++++-
 arch/mips/mti-malta/malta-init.c            |  17 ++-
 arch/mips/mti-malta/malta-int.c             |  96 +-------------
 arch/mips/mti-malta/malta-platform.c        |  65 ----------
 arch/mips/mti-malta/malta-pm.c              |  96 --------------
 arch/mips/mti-malta/malta-reset.c           |  47 -------
 drivers/irqchip/irq-i8259.c                 |  30 ++---
 drivers/power/reset/Kconfig                 |   9 ++
 drivers/power/reset/Makefile                |   1 +
 drivers/power/reset/piix4-poweroff.c        | 103 +++++++++++++++
 23 files changed, 452 insertions(+), 349 deletions(-)
 delete mode 100644 arch/mips/mti-malta/malta-pm.c
 delete mode 100644 arch/mips/mti-malta/malta-reset.c
 create mode 100644 drivers/power/reset/piix4-poweroff.c

-- 
2.9.3

[toc] | [next] | [standalone]


#1475305 — [PATCH 05/12] MIPS: Malta: Use all available DDR by default

FromPaul Burton <paul.burton@imgtec.com>
Date2016-09-02 18:00 +0200
Subject[PATCH 05/12] MIPS: Malta: Use all available DDR by default
Message-ID<scZ2Q-1kr-73@gated-at.bofh.it>
In reply to#1475299
Malta boards can have more than 256MB DDR available, but we have
previously only made use of up to 256MB (ie. the DDR accessible via
kseg0) by default, without the user manually specifying mem= kernel
parameters. This patch causes all available DDR, as reported by the
bootloader via the ememsize or memsize environment variables or
optionally on the command line, to be used when possible without the
user needing to manually provide the memory ranges.

Malta now has 2 subtly different memory maps which have to be taken into
account when setting this up. The original memory map (referred to by
the code as v1) has up to 2GB of DDR aliased in both the upper & lower
halves of the 32 bit physical address space, with a 256MB I/O region
obscuring 0x10000000-0x1fffffff only in the lower alias. The revised v2
memory map is flat with up to 4GB DDR starting from 0x0, and the I/O
region obscures 256MB of DDR which becomes inacessible. The memory map
in use is indicated by a register provided by the rocit2 system
controller, which is checked in order to set up the kernels memory
ranges accordingly.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
---

 arch/mips/mti-malta/malta-dtshim.c | 109 +++++++++++++++++++++++++++++++++++--
 1 file changed, 103 insertions(+), 6 deletions(-)

diff --git a/arch/mips/mti-malta/malta-dtshim.c b/arch/mips/mti-malta/malta-dtshim.c
index 151f488..5d37b7e 100644
--- a/arch/mips/mti-malta/malta-dtshim.c
+++ b/arch/mips/mti-malta/malta-dtshim.c
@@ -13,18 +13,63 @@
 #include <linux/libfdt.h>
 #include <linux/of_fdt.h>
 #include <linux/sizes.h>
+#include <asm/addrspace.h>
 #include <asm/bootinfo.h>
 #include <asm/fw/fw.h>
 #include <asm/page.h>
 
+#define ROCIT_REG_BASE			0x1f403000
+#define ROCIT_CONFIG_GEN1		(ROCIT_REG_BASE + 0x04)
+#define  ROCIT_CONFIG_GEN1_MEMMAP_SHIFT	8
+#define  ROCIT_CONFIG_GEN1_MEMMAP_MASK	(0xf << 8)
+
 static unsigned char fdt_buf[16 << 10] __initdata;
 
 /* determined physical memory size, not overridden by command line args	 */
 extern unsigned long physical_memsize;
 
-#define MAX_MEM_ARRAY_ENTRIES 1
+enum mem_map {
+	MEM_MAP_V1 = 0,
+	MEM_MAP_V2,
+};
+
+#define MAX_MEM_ARRAY_ENTRIES 2
+
+static __init int malta_scon(void)
+{
+	int scon = MIPS_REVISION_SCONID;
+
+	if (scon != MIPS_REVISION_SCON_OTHER)
+		return scon;
+
+	switch (MIPS_REVISION_CORID) {
+	case MIPS_REVISION_CORID_QED_RM5261:
+	case MIPS_REVISION_CORID_CORE_LV:
+	case MIPS_REVISION_CORID_CORE_FPGA:
+	case MIPS_REVISION_CORID_CORE_FPGAR2:
+		return MIPS_REVISION_SCON_GT64120;
+
+	case MIPS_REVISION_CORID_CORE_EMUL_BON:
+	case MIPS_REVISION_CORID_BONITO64:
+	case MIPS_REVISION_CORID_CORE_20K:
+		return MIPS_REVISION_SCON_BONITO;
+
+	case MIPS_REVISION_CORID_CORE_MSC:
+	case MIPS_REVISION_CORID_CORE_FPGA2:
+	case MIPS_REVISION_CORID_CORE_24K:
+		return MIPS_REVISION_SCON_SOCIT;
+
+	case MIPS_REVISION_CORID_CORE_FPGA3:
+	case MIPS_REVISION_CORID_CORE_FPGA4:
+	case MIPS_REVISION_CORID_CORE_FPGA5:
+	case MIPS_REVISION_CORID_CORE_EMUL_MSC:
+	default:
+		return MIPS_REVISION_SCON_ROCIT;
+	}
+}
 
-static unsigned __init gen_fdt_mem_array(__be32 *mem_array, unsigned long size)
+static unsigned __init gen_fdt_mem_array(__be32 *mem_array, unsigned long size,
+					 enum mem_map map)
 {
 	unsigned long size_preio;
 	unsigned entries;
@@ -39,11 +84,47 @@ static unsigned __init gen_fdt_mem_array(__be32 *mem_array, unsigned long size)
 		 * DDR but limits it to 2GB.
 		 */
 		mem_array[1] = cpu_to_be32(size);
+		goto done;
+	}
+
+	size_preio = min_t(unsigned long, size, SZ_256M);
+	mem_array[1] = cpu_to_be32(size_preio);
+	size -= size_preio;
+	if (!size)
+		goto done;
+
+	if (map == MEM_MAP_V2) {
+		/*
+		 * We have a flat 32 bit physical memory map with DDR filling
+		 * all 4GB of the memory map, apart from the I/O region which
+		 * obscures 256MB from 0x10000000-0x1fffffff.
+		 *
+		 * Therefore we discard the 256MB behind the I/O region.
+		 */
+		if (size <= SZ_256M)
+			goto done;
+		size -= SZ_256M;
+
+		/* Make use of the memory following the I/O region */
+		entries++;
+		mem_array[2] = cpu_to_be32(PHYS_OFFSET + SZ_512M);
+		mem_array[3] = cpu_to_be32(size);
 	} else {
-		size_preio = min_t(unsigned long, size, SZ_256M);
-		mem_array[1] = cpu_to_be32(size_preio);
+		/*
+		 * We have a 32 bit physical memory map with a 2GB DDR region
+		 * aliased in the upper & lower halves of it. The I/O region
+		 * obscures 256MB from 0x10000000-0x1fffffff in the low alias
+		 * but the DDR it obscures is accessible via the high alias.
+		 *
+		 * Simply access everything beyond the lowest 256MB of DDR using
+		 * the high alias.
+		 */
+		entries++;
+		mem_array[2] = cpu_to_be32(PHYS_OFFSET + SZ_2G + SZ_256M);
+		mem_array[3] = cpu_to_be32(size);
 	}
 
+done:
 	BUG_ON(entries > MAX_MEM_ARRAY_ENTRIES);
 	return entries;
 }
@@ -54,6 +135,8 @@ static void __init append_memory(void *fdt, int root_off)
 	unsigned long memsize;
 	unsigned mem_entries;
 	int i, err, mem_off;
+	enum mem_map mem_map;
+	u32 config;
 	char *var, param_name[10], *var_names[] = {
 		"ememsize", "memsize",
 	};
@@ -106,6 +189,20 @@ static void __init append_memory(void *fdt, int root_off)
 	/* if the user says there's more RAM than we thought, believe them */
 	physical_memsize = max_t(unsigned long, physical_memsize, memsize);
 
+	/* detect the memory map in use */
+	if (malta_scon() == MIPS_REVISION_SCON_ROCIT) {
+		/* ROCit has a register indicating the memory map in use */
+		config = readl((void __iomem *)CKSEG1ADDR(ROCIT_CONFIG_GEN1));
+		mem_map = config & ROCIT_CONFIG_GEN1_MEMMAP_MASK;
+		mem_map >>= ROCIT_CONFIG_GEN1_MEMMAP_SHIFT;
+	} else {
+		/* if not using ROCit, presume the v1 memory map */
+		mem_map = MEM_MAP_V1;
+	}
+	if (mem_map > MEM_MAP_V2)
+		panic("Unsupported physical memory map v%u detected",
+		      (unsigned int)mem_map);
+
 	/* append memory to the DT */
 	mem_off = fdt_add_subnode(fdt, root_off, "memory");
 	if (mem_off < 0)
@@ -115,13 +212,13 @@ static void __init append_memory(void *fdt, int root_off)
 	if (err)
 		panic("Unable to set memory node device_type: %d", err);
 
-	mem_entries = gen_fdt_mem_array(mem_array, physical_memsize);
+	mem_entries = gen_fdt_mem_array(mem_array, physical_memsize, mem_map);
 	err = fdt_setprop(fdt, mem_off, "reg", mem_array,
 			  mem_entries * 2 * sizeof(mem_array[0]));
 	if (err)
 		panic("Unable to set memory regs property: %d", err);
 
-	mem_entries = gen_fdt_mem_array(mem_array, memsize);
+	mem_entries = gen_fdt_mem_array(mem_array, memsize, mem_map);
 	err = fdt_setprop(fdt, mem_off, "linux,usable-memory", mem_array,
 			  mem_entries * 2 * sizeof(mem_array[0]));
 	if (err)
-- 
2.9.3

[toc] | [prev] | [next] | [standalone]


#1475590 — Re: [PATCH 05/12] MIPS: Malta: Use all available DDR by default

Fromkbuild test robot <lkp@intel.com>
Date2016-09-03 12:30 +0200
SubjectRe: [PATCH 05/12] MIPS: Malta: Use all available DDR by default
Message-ID<sdgn0-3VD-5@gated-at.bofh.it>
In reply to#1475305

[Multipart message — attachments visible in raw view] — view raw

Hi Paul,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.8-rc4 next-20160825]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
[Suggest to use git(>=2.9.0) format-patch --base=<commit> (or --base=auto for convenience) to record what (public, well-known) commit your patch series was built on]
[Check https://git-scm.com/docs/git-format-patch for more information]

url:    https://github.com/0day-ci/linux/commits/Paul-Burton/Partial-MIPS-Malta-DT-conversion/20160903-000153
config: mips-malta_kvm_defconfig (attached as .config)
compiler: mipsel-linux-gnu-gcc (Debian 5.4.0-6) 5.4.0 20160609
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=mips 

Note: the linux-review/Paul-Burton/Partial-MIPS-Malta-DT-conversion/20160903-000153 HEAD c8f10f160bc7b6a6b2cd9162137dd9774b018092 builds fine.
      It only hurts bisectibility.

All errors (new ones prefixed by >>):

   arch/mips/mti-malta/malta-dtshim.c: In function 'malta_scon':
>> arch/mips/mti-malta/malta-dtshim.c:40:13: error: 'MIPS_REVISION_SCONID' undeclared (first use in this function)
     int scon = MIPS_REVISION_SCONID;
                ^
   arch/mips/mti-malta/malta-dtshim.c:40:13: note: each undeclared identifier is reported only once for each function it appears in
>> arch/mips/mti-malta/malta-dtshim.c:42:14: error: 'MIPS_REVISION_SCON_OTHER' undeclared (first use in this function)
     if (scon != MIPS_REVISION_SCON_OTHER)
                 ^
>> arch/mips/mti-malta/malta-dtshim.c:45:10: error: 'MIPS_REVISION_CORID' undeclared (first use in this function)
     switch (MIPS_REVISION_CORID) {
             ^
>> arch/mips/mti-malta/malta-dtshim.c:46:7: error: 'MIPS_REVISION_CORID_QED_RM5261' undeclared (first use in this function)
     case MIPS_REVISION_CORID_QED_RM5261:
          ^
>> arch/mips/mti-malta/malta-dtshim.c:47:7: error: 'MIPS_REVISION_CORID_CORE_LV' undeclared (first use in this function)
     case MIPS_REVISION_CORID_CORE_LV:
          ^
>> arch/mips/mti-malta/malta-dtshim.c:48:7: error: 'MIPS_REVISION_CORID_CORE_FPGA' undeclared (first use in this function)
     case MIPS_REVISION_CORID_CORE_FPGA:
          ^
>> arch/mips/mti-malta/malta-dtshim.c:49:7: error: 'MIPS_REVISION_CORID_CORE_FPGAR2' undeclared (first use in this function)
     case MIPS_REVISION_CORID_CORE_FPGAR2:
          ^
>> arch/mips/mti-malta/malta-dtshim.c:50:10: error: 'MIPS_REVISION_SCON_GT64120' undeclared (first use in this function)
      return MIPS_REVISION_SCON_GT64120;
             ^
>> arch/mips/mti-malta/malta-dtshim.c:52:7: error: 'MIPS_REVISION_CORID_CORE_EMUL_BON' undeclared (first use in this function)
     case MIPS_REVISION_CORID_CORE_EMUL_BON:
          ^
>> arch/mips/mti-malta/malta-dtshim.c:53:7: error: 'MIPS_REVISION_CORID_BONITO64' undeclared (first use in this function)
     case MIPS_REVISION_CORID_BONITO64:
          ^
>> arch/mips/mti-malta/malta-dtshim.c:54:7: error: 'MIPS_REVISION_CORID_CORE_20K' undeclared (first use in this function)
     case MIPS_REVISION_CORID_CORE_20K:
          ^
>> arch/mips/mti-malta/malta-dtshim.c:55:10: error: 'MIPS_REVISION_SCON_BONITO' undeclared (first use in this function)
      return MIPS_REVISION_SCON_BONITO;
             ^
>> arch/mips/mti-malta/malta-dtshim.c:57:7: error: 'MIPS_REVISION_CORID_CORE_MSC' undeclared (first use in this function)
     case MIPS_REVISION_CORID_CORE_MSC:
          ^
>> arch/mips/mti-malta/malta-dtshim.c:58:7: error: 'MIPS_REVISION_CORID_CORE_FPGA2' undeclared (first use in this function)
     case MIPS_REVISION_CORID_CORE_FPGA2:
          ^
>> arch/mips/mti-malta/malta-dtshim.c:59:7: error: 'MIPS_REVISION_CORID_CORE_24K' undeclared (first use in this function)
     case MIPS_REVISION_CORID_CORE_24K:
          ^
>> arch/mips/mti-malta/malta-dtshim.c:60:10: error: 'MIPS_REVISION_SCON_SOCIT' undeclared (first use in this function)
      return MIPS_REVISION_SCON_SOCIT;
             ^
>> arch/mips/mti-malta/malta-dtshim.c:62:7: error: 'MIPS_REVISION_CORID_CORE_FPGA3' undeclared (first use in this function)
     case MIPS_REVISION_CORID_CORE_FPGA3:
          ^
>> arch/mips/mti-malta/malta-dtshim.c:63:7: error: 'MIPS_REVISION_CORID_CORE_FPGA4' undeclared (first use in this function)
     case MIPS_REVISION_CORID_CORE_FPGA4:
          ^
>> arch/mips/mti-malta/malta-dtshim.c:64:7: error: 'MIPS_REVISION_CORID_CORE_FPGA5' undeclared (first use in this function)
     case MIPS_REVISION_CORID_CORE_FPGA5:
          ^
>> arch/mips/mti-malta/malta-dtshim.c:65:7: error: 'MIPS_REVISION_CORID_CORE_EMUL_MSC' undeclared (first use in this function)
     case MIPS_REVISION_CORID_CORE_EMUL_MSC:
          ^

vim +/MIPS_REVISION_SCONID +40 arch/mips/mti-malta/malta-dtshim.c

    34	};
    35	
    36	#define MAX_MEM_ARRAY_ENTRIES 2
    37	
    38	static __init int malta_scon(void)
    39	{
  > 40		int scon = MIPS_REVISION_SCONID;
    41	
  > 42		if (scon != MIPS_REVISION_SCON_OTHER)
    43			return scon;
    44	
  > 45		switch (MIPS_REVISION_CORID) {
  > 46		case MIPS_REVISION_CORID_QED_RM5261:
  > 47		case MIPS_REVISION_CORID_CORE_LV:
  > 48		case MIPS_REVISION_CORID_CORE_FPGA:
  > 49		case MIPS_REVISION_CORID_CORE_FPGAR2:
  > 50			return MIPS_REVISION_SCON_GT64120;
    51	
  > 52		case MIPS_REVISION_CORID_CORE_EMUL_BON:
  > 53		case MIPS_REVISION_CORID_BONITO64:
  > 54		case MIPS_REVISION_CORID_CORE_20K:
  > 55			return MIPS_REVISION_SCON_BONITO;
    56	
  > 57		case MIPS_REVISION_CORID_CORE_MSC:
  > 58		case MIPS_REVISION_CORID_CORE_FPGA2:
  > 59		case MIPS_REVISION_CORID_CORE_24K:
  > 60			return MIPS_REVISION_SCON_SOCIT;
    61	
  > 62		case MIPS_REVISION_CORID_CORE_FPGA3:
  > 63		case MIPS_REVISION_CORID_CORE_FPGA4:
  > 64		case MIPS_REVISION_CORID_CORE_FPGA5:
  > 65		case MIPS_REVISION_CORID_CORE_EMUL_MSC:
    66		default:
  > 67			return MIPS_REVISION_SCON_ROCIT;
    68		}
    69	}
    70	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[toc] | [prev] | [next] | [standalone]


#1475306 — [PATCH 03/12] irqchip: i8259: Remove unused i8259A_irq_pending

FromPaul Burton <paul.burton@imgtec.com>
Date2016-09-02 18:00 +0200
Subject[PATCH 03/12] irqchip: i8259: Remove unused i8259A_irq_pending
Message-ID<scZ2Q-1kr-89@gated-at.bofh.it>
In reply to#1475299
The i8259A_irq_pending function is unused. Remove the dead code.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
---

 arch/mips/include/asm/i8259.h |  1 -
 drivers/irqchip/irq-i8259.c   | 18 ------------------
 2 files changed, 19 deletions(-)

diff --git a/arch/mips/include/asm/i8259.h b/arch/mips/include/asm/i8259.h
index b27fcc4..32229c7 100644
--- a/arch/mips/include/asm/i8259.h
+++ b/arch/mips/include/asm/i8259.h
@@ -37,7 +37,6 @@
 
 extern raw_spinlock_t i8259A_lock;
 
-extern int i8259A_irq_pending(unsigned int irq);
 extern void make_8259A_irq(unsigned int irq);
 
 extern void init_i8259_irqs(void);
diff --git a/drivers/irqchip/irq-i8259.c b/drivers/irqchip/irq-i8259.c
index 1f4a344..1aec12c 100644
--- a/drivers/irqchip/irq-i8259.c
+++ b/drivers/irqchip/irq-i8259.c
@@ -95,24 +95,6 @@ static void enable_8259A_irq(struct irq_data *d)
 	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 }
 
-int i8259A_irq_pending(unsigned int irq)
-{
-	unsigned int mask;
-	unsigned long flags;
-	int ret;
-
-	irq -= I8259A_IRQ_BASE;
-	mask = 1 << irq;
-	raw_spin_lock_irqsave(&i8259A_lock, flags);
-	if (irq < 8)
-		ret = inb(PIC_MASTER_CMD) & mask;
-	else
-		ret = inb(PIC_SLAVE_CMD) & (mask >> 8);
-	raw_spin_unlock_irqrestore(&i8259A_lock, flags);
-
-	return ret;
-}
-
 void make_8259A_irq(unsigned int irq)
 {
 	disable_irq_nosync(irq);
-- 
2.9.3

[toc] | [prev] | [next] | [standalone]


#1475310 — [PATCH 11/12] power: reset: Add Intel PIIX4 poweroff driver

FromPaul Burton <paul.burton@imgtec.com>
Date2016-09-02 18:00 +0200
Subject[PATCH 11/12] power: reset: Add Intel PIIX4 poweroff driver
Message-ID<scZ2Q-1kr-97@gated-at.bofh.it>
In reply to#1475299
Add a driver which allows powering off the system via an Intel PIIX4
southbridge, by entering the PIIX4 SOff state. This is useful on the
MIPS Malta development board, where it will power down the FPGA based
board until its ON/NMI button is pressed, or the QEMU implementation of
the MIPS Malta board where it will cause QEMU to exit.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
---

 drivers/power/reset/Kconfig          |   9 +++
 drivers/power/reset/Makefile         |   1 +
 drivers/power/reset/piix4-poweroff.c | 103 +++++++++++++++++++++++++++++++++++
 3 files changed, 113 insertions(+)
 create mode 100644 drivers/power/reset/piix4-poweroff.c

diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index c74c3f6..b27ca50 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -104,6 +104,15 @@ config POWER_RESET_MSM
 	help
 	  Power off and restart support for Qualcomm boards.
 
+config POWER_RESET_PIIX4_POWEROFF
+	tristate "Intel PIIX4 power-off driver"
+	depends on MIPS && PCI
+	help
+	  This driver supports powering off a system using the Intel PIIX4
+	  southbridge, for example the MIPS Malta development board. The
+	  southbridge SOff state is entered in response to a request to
+	  power off the system.
+
 config POWER_RESET_LTC2952
 	bool "LTC2952 PowerPath power-off driver"
 	depends on OF_GPIO
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index 1be307c..11dae3b 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o
 obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o
 obj-$(CONFIG_POWER_RESET_IMX) += imx-snvs-poweroff.o
 obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o
+obj-$(CONFIG_POWER_RESET_PIIX4_POWEROFF) += piix4-poweroff.o
 obj-$(CONFIG_POWER_RESET_LTC2952) += ltc2952-poweroff.o
 obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o
 obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o
diff --git a/drivers/power/reset/piix4-poweroff.c b/drivers/power/reset/piix4-poweroff.c
new file mode 100644
index 0000000..bfa8bea
--- /dev/null
+++ b/drivers/power/reset/piix4-poweroff.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/pm.h>
+
+static struct pci_dev *pm_dev;
+static resource_size_t io_offset;
+
+enum piix4_pm_io_reg {
+	PIIX4_FUNC3IO_PMSTS			= 0x00,
+#define PIIX4_FUNC3IO_PMSTS_PWRBTN_STS		BIT(8)
+	PIIX4_FUNC3IO_PMCNTRL			= 0x04,
+#define PIIX4_FUNC3IO_PMCNTRL_SUS_EN		BIT(13)
+#define PIIX4_FUNC3IO_PMCNTRL_SUS_TYP_SOFF	(0x0 << 10)
+};
+
+#define PIIX4_SUSPEND_MAGIC			0x00120002
+
+static void piix4_poweroff(void)
+{
+	int spec_devid;
+	u16 sts;
+
+	/* Ensure the power button status is clear */
+	while (1) {
+		sts = inw(io_offset + PIIX4_FUNC3IO_PMSTS);
+		if (!(sts & PIIX4_FUNC3IO_PMSTS_PWRBTN_STS))
+			break;
+		outw(sts, io_offset + PIIX4_FUNC3IO_PMSTS);
+	}
+
+	/* Enable entry to suspend */
+	outw(PIIX4_FUNC3IO_PMCNTRL_SUS_TYP_SOFF | PIIX4_FUNC3IO_PMCNTRL_SUS_EN,
+	     io_offset + PIIX4_FUNC3IO_PMCNTRL);
+
+	/* If the special cycle occurs too soon this doesn't work... */
+	mdelay(10);
+
+	/*
+	 * The PIIX4 will enter the suspend state only after seeing a special
+	 * cycle with the correct magic data on the PCI bus. Generate that
+	 * cycle now.
+	 */
+	spec_devid = PCI_DEVID(0, PCI_DEVFN(0x1f, 0x7));
+	pci_bus_write_config_dword(pm_dev->bus, spec_devid, 0,
+				   PIIX4_SUSPEND_MAGIC);
+
+	/* Give the system some time to power down, then error */
+	mdelay(1000);
+	pr_emerg("Unable to poweroff system\n");
+}
+
+static int piix4_poweroff_probe(struct pci_dev *dev,
+				const struct pci_device_id *id)
+{
+	int res, io_region = PCI_BRIDGE_RESOURCES;
+
+	/* Request access to the PIIX4 PM IO registers */
+	res = pci_request_region(dev, io_region, "PIIX4 PM IO registers");
+	if (res) {
+		dev_err(&dev->dev, "failed to request PM IO registers: %d\n",
+			res);
+		return res;
+	}
+
+	pm_dev = dev;
+	io_offset = pci_resource_start(dev, io_region);
+	pm_power_off = piix4_poweroff;
+
+	return 0;
+}
+
+static void piix4_poweroff_remove(struct pci_dev *dev)
+{
+	if (pm_power_off == piix4_poweroff)
+		pm_power_off = NULL;
+}
+
+static const struct pci_device_id piix4_poweroff_ids[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3) },
+	{ 0 },
+};
+
+static struct pci_driver piix4_poweroff_driver = {
+	.name		= "piix4-poweroff",
+	.id_table	= piix4_poweroff_ids,
+	.probe		= piix4_poweroff_probe,
+	.remove		= piix4_poweroff_remove,
+};
+
+module_pci_driver(piix4_poweroff_driver);
+MODULE_AUTHOR("Paul Burton <paul.burton@imgtec.com>");
-- 
2.9.3

[toc] | [prev] | [next] | [standalone]


#1475328 — Re: [PATCH 11/12] power: reset: Add Intel PIIX4 poweroff driver

FromSebastian Reichel <sre@kernel.org>
Date2016-09-02 18:30 +0200
SubjectRe: [PATCH 11/12] power: reset: Add Intel PIIX4 poweroff driver
Message-ID<scZvP-1Ng-3@gated-at.bofh.it>
In reply to#1475310

[Multipart message — attachments visible in raw view] — view raw

Hi Paul,

The driver looks fine to me, just two notes:

On Fri, Sep 02, 2016 at 04:48:57PM +0100, Paul Burton wrote:
> Add a driver which allows powering off the system via an Intel PIIX4
> southbridge, by entering the PIIX4 SOff state. This is useful on the
> MIPS Malta development board, where it will power down the FPGA based
> board until its ON/NMI button is pressed, or the QEMU implementation of
> the MIPS Malta board where it will cause QEMU to exit.
> 
> Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> ---
> 
>  drivers/power/reset/Kconfig          |   9 +++
>  drivers/power/reset/Makefile         |   1 +
>  drivers/power/reset/piix4-poweroff.c | 103 +++++++++++++++++++++++++++++++++++
>  3 files changed, 113 insertions(+)
>  create mode 100644 drivers/power/reset/piix4-poweroff.c
> 
> diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
> index c74c3f6..b27ca50 100644
> --- a/drivers/power/reset/Kconfig
> +++ b/drivers/power/reset/Kconfig
> @@ -104,6 +104,15 @@ config POWER_RESET_MSM
>  	help
>  	  Power off and restart support for Qualcomm boards.
>  
> +config POWER_RESET_PIIX4_POWEROFF
> +	tristate "Intel PIIX4 power-off driver"
> +	depends on MIPS && PCI

depends on PCI
depends on MIPS || COMPILE_TEST

> +	help
> +	  This driver supports powering off a system using the Intel PIIX4
> +	  southbridge, for example the MIPS Malta development board. The
> +	  southbridge SOff state is entered in response to a request to
> +	  power off the system.
> +
>  config POWER_RESET_LTC2952
>  	bool "LTC2952 PowerPath power-off driver"
>  	depends on OF_GPIO
> diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
> index 1be307c..11dae3b 100644
> --- a/drivers/power/reset/Makefile
> +++ b/drivers/power/reset/Makefile
> @@ -10,6 +10,7 @@ obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o
>  obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o
>  obj-$(CONFIG_POWER_RESET_IMX) += imx-snvs-poweroff.o
>  obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o
> +obj-$(CONFIG_POWER_RESET_PIIX4_POWEROFF) += piix4-poweroff.o
>  obj-$(CONFIG_POWER_RESET_LTC2952) += ltc2952-poweroff.o
>  obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o
>  obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o
> diff --git a/drivers/power/reset/piix4-poweroff.c b/drivers/power/reset/piix4-poweroff.c
> new file mode 100644
> index 0000000..bfa8bea
> --- /dev/null
> +++ b/drivers/power/reset/piix4-poweroff.c

[...]

> +
> +module_pci_driver(piix4_poweroff_driver);
> +MODULE_AUTHOR("Paul Burton <paul.burton@imgtec.com>");

missing MODULE_LICENSE()

-- Sebastian

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web