From: tip-bot for Vivien Didelot <vivien.didelot@savoirfairelinux.com>
To: linux-tip-commits@vger.kernel.org
Cc: linux-kernel@vger.kernel.org,
vivien.didelot@savoirfairelinux.com, hpa@zytor.com,
mingo@redhat.com, tglx@linutronix.de, mingo@elte.hu
Subject: [tip:x86/platform] x86/platform: Add TS-5500 base support
Date: Fri, 18 Nov 2011 15:00:54 -0800 [thread overview]
Message-ID: <tip-37f9a16c166c51be114bb5b2ff670ccaa893f978@git.kernel.org> (raw)
In-Reply-To: <1314988224-13162-2-git-send-email-vivien.didelot@savoirfairelinux.com>
Commit-ID: 37f9a16c166c51be114bb5b2ff670ccaa893f978
Gitweb: http://git.kernel.org/tip/37f9a16c166c51be114bb5b2ff670ccaa893f978
Author: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
AuthorDate: Fri, 2 Sep 2011 14:30:21 -0400
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Wed, 12 Oct 2011 17:36:54 +0200
x86/platform: Add TS-5500 base support
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1314988224-13162-2-git-send-email-vivien.didelot@savoirfairelinux.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
Documentation/ABI/testing/sysfs-platform-ts5500 | 46 +++
MAINTAINERS | 5 +
arch/x86/Kconfig | 2 +
arch/x86/platform/Makefile | 1 +
arch/x86/platform/ts5500/Kconfig | 8 +
arch/x86/platform/ts5500/Makefile | 1 +
arch/x86/platform/ts5500/ts5500.c | 332 +++++++++++++++++++++++
7 files changed, 395 insertions(+), 0 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-platform-ts5500 b/Documentation/ABI/testing/sysfs-platform-ts5500
new file mode 100644
index 0000000..a43bb52
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-platform-ts5500
@@ -0,0 +1,46 @@
+What: /sys/devices/platform/ts5500/id
+Date: August 2011
+KernelVersion: 3.0
+Contact: "Savoir-faire Linux, Inc." <kernel-ts@savoirfairelinux.com>
+Description:
+ Product ID of the TS board. TS-5500 ID is 0x60.
+
+What: /sys/devices/platform/ts5500/sram
+Date: August 2011
+KernelVersion: 3.0
+Contact: "Savoir-faire Linux, Inc." <kernel-ts@savoirfairelinux.com>
+Description:
+ Say if the SRAM feature is present. If it is enabled, it will
+ display "1", otherwise "0".
+
+What: /sys/devices/platform/ts5500/ereset
+Date: August 2011
+KernelVersion: 3.0
+Contact: "Savoir-faire Linux, Inc." <kernel-ts@savoirfairelinux.com>
+Description:
+ Say if an external reset is present. If it is present, it will
+ display "1", otherwise "0".
+
+What: /sys/devices/platform/ts5500/jp{1,2,3,4,5,6}
+Date: August 2011
+KernelVersion: 3.0
+Contact: "Savoir-faire Linux, Inc." <kernel-ts@savoirfairelinux.com>
+Description:
+ Show the state of a plugged jumper. If it is present, it will
+ display "1", otherwise "0".
+
+What: /sys/devices/platform/ts5500/adc
+Date: August 2011
+KernelVersion: 3.0
+Contact: "Savoir-faire Linux, Inc." <kernel-ts@savoirfairelinux.com>
+Description:
+ Say if the Analogic to Digital Converter is present. If it is
+ enabled, it will display "1", otherwise "0".
+
+What: /sys/devices/platform/ts5500/rs485
+Date: August 2011
+KernelVersion: 3.0
+Contact: "Savoir-faire Linux, Inc." <kernel-ts@savoirfairelinux.com>
+Description:
+ Say if the RS485 feature is present. If it is enabled, it
+ will display "1", otherwise "0".
diff --git a/MAINTAINERS b/MAINTAINERS
index 5483e0c..ded9e08 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6364,6 +6364,11 @@ W: http://tcp-lp-mod.sourceforge.net/
S: Maintained
F: net/ipv4/tcp_lp.c
+TECHNOLOGIC SYSTEMS TS-5500 MACHINE SUPPORT
+M: Savoir-faire Linux Inc. <ts-kernel@savoirfairelinux.com>
+S: Maintained
+F: arch/x86/platform/ts5500/*
+
TEGRA SUPPORT
M: Colin Cross <ccross@android.com>
M: Olof Johansson <olof@lixom.net>
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 6a47bb2..ec71069 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2064,6 +2064,8 @@ config OLPC_XO15_SCI
- AC adapter status updates
- Battery status updates
+source "arch/x86/platform/ts5500/Kconfig"
+
endif # X86_32
config AMD_NB
diff --git a/arch/x86/platform/Makefile b/arch/x86/platform/Makefile
index 021eee9..1bdc038 100644
--- a/arch/x86/platform/Makefile
+++ b/arch/x86/platform/Makefile
@@ -8,3 +8,4 @@ obj-y += scx200/
obj-y += sfi/
obj-y += visws/
obj-y += uv/
+obj-y += ts5500/
diff --git a/arch/x86/platform/ts5500/Kconfig b/arch/x86/platform/ts5500/Kconfig
new file mode 100644
index 0000000..90c257a
--- /dev/null
+++ b/arch/x86/platform/ts5500/Kconfig
@@ -0,0 +1,8 @@
+config TS5500
+ bool "Technologic Systems TS-5500 Single Board Computer support"
+ depends on MELAN
+ select CHECK_SIGNATURE
+ help
+ Add support for the Technologic Systems TS-5500 platform features.
+
+ If you have a TS-5500, say Y here.
diff --git a/arch/x86/platform/ts5500/Makefile b/arch/x86/platform/ts5500/Makefile
new file mode 100644
index 0000000..0a689a7
--- /dev/null
+++ b/arch/x86/platform/ts5500/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_TS5500) += ts5500.o
diff --git a/arch/x86/platform/ts5500/ts5500.c b/arch/x86/platform/ts5500/ts5500.c
new file mode 100644
index 0000000..d50cd1b1
--- /dev/null
+++ b/arch/x86/platform/ts5500/ts5500.c
@@ -0,0 +1,332 @@
+/*
+ * Technologic Systems TS-5500 board - SBC info layer
+ *
+ * Copyright (c) 2010-2011 Savoir-faire Linux Inc.
+ * Alexandre Savard <alexandre.savard@savoirfairelinux.com>
+ * Jonas Fonseca <jonas.fonseca@savoirfairelinux.com>
+ * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
+ *
+ * Portions originate from ts_sbcinfo.c (c) Technologic Systems
+ * Liberty Young <liberty@embeddedx86.com>
+ *
+ * These functions add sysfs platform entries to display information about
+ * the Technologic Systems TS-5500 Single Board Computer (SBC).
+ *
+ * For further information about sysfs entries, see
+ * Documentation/ABI/testing/sysfs-platform-ts5500
+ */
+
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <asm/processor.h>
+
+/* Hardware info for pre-detection */
+#define AMD_ELAN_FAMILY 4
+#define AMD_ELAN_SC520 9
+
+/* Product code register */
+#define TS5500_PRODUCT_CODE_REG 0x74
+#define TS5500_PRODUCT_CODE 0x60 /* TS-5500 product code */
+
+/* SRAM/RS-485/ADC options, and RS-485 RTS/Automatic RS-485 flags register */
+#define TS5500_SRAM_RS485_ADC_REG 0x75
+#define TS5500_SRAM_OPT 0x01 /* SRAM option */
+#define TS5500_RS485_OPT 0x02 /* RS-485 option */
+#define TS5500_ADC_OPT 0x04 /* A/D converter option */
+#define TS5500_RS485_RTS_MASK 0x40 /* RTS for RS-485 */
+#define TS5500_RS485_AUTO_MASK 0x80 /* Automatic RS-485 */
+
+/* External Reset/Industrial Temperature Range options register */
+#define TS5500_ERESET_ITR_REG 0x76
+#define TS5500_ERESET_OPT 0x01 /* External Reset option */
+#define TS5500_ITR_OPT 0x02 /* Indust. Temp. Range option */
+
+/* LED/Jumpers register */
+#define TS5500_LED_JMPRS_REG 0x77
+#define TS5500_LED_MASK 0x01 /* LED flag */
+#define TS5500_JP1 0x02 /* Automatic CMOS */
+#define TS5500_JP2 0x04 /* Enable Serial Console */
+#define TS5500_JP3 0x08 /* Write Enable Drive A */
+#define TS5500_JP4 0x10 /* Fast Console (115K baud) */
+#define TS5500_JP5 0x20 /* User Jumper */
+#define TS5500_JP6 0x40 /* Console on COM1 (req. JP2) */
+#define TS5500_JP7 0x80 /* Undocumented (Unused) */
+
+/**
+ * struct ts5500_sbc - TS-5500 SBC main structure
+ * @lock: Read/Write mutex.
+ * @board_id: Board name.
+ * @sram: Check SRAM option.
+ * @rs485: Check RS-485 option.
+ * @adc: Check Analogic/Digital converter option.
+ * @ereset: Check External Reset option.
+ * @itr: Check Industrial Temperature Range option.
+ * @jumpers: States of jumpers 1-7.
+ */
+struct ts5500_sbc {
+ struct mutex lock;
+ int board_id;
+ bool sram;
+ bool rs485;
+ bool adc;
+ bool ereset;
+ bool itr;
+ u8 jumpers;
+};
+
+/* Current platform */
+struct ts5500_sbc *ts5500;
+
+/**
+ * ts5500_pre_detect_hw() - check for TS-5500 specific hardware
+ */
+static __init int ts5500_pre_detect_hw(void)
+{
+ /* Check for AMD ElanSC520 Microcontroller */
+ if (cpu_info.x86_vendor != X86_VENDOR_AMD ||
+ cpu_info.x86 != AMD_ELAN_FAMILY ||
+ cpu_info.x86_model != AMD_ELAN_SC520)
+ return -ENODEV;
+
+ return 0;
+}
+
+/* BIOS signatures */
+static struct {
+ const unsigned char *string;
+ const ssize_t offset;
+} signatures[] __initdata = {
+ {"TS-5x00 AMD Elan", 0xb14}
+};
+
+/**
+ * ts5500_bios_signature() - find board signature in BIOS shadow RAM.
+ */
+static __init int ts5500_bios_signature(void)
+{
+ void __iomem *bios = ioremap(0xF0000, 0x10000);
+ int i, ret = 0;
+
+ for (i = 0; i < ARRAY_SIZE(signatures); i++)
+ if (check_signature(bios + signatures[i].offset,
+ signatures[i].string,
+ strlen(signatures[i].string)))
+ goto found;
+ else
+ pr_notice("Technologic Systems BIOS signature "
+ "'%s' not found at offset %zd\n",
+ signatures[i].string, signatures[i].offset);
+ ret = -ENODEV;
+found:
+ iounmap(bios);
+ return ret;
+}
+
+/**
+ * ts5500_detect_config() - detect the TS board
+ * @sbc: Structure where to store the detected board's details.
+ */
+static int ts5500_detect_config(struct ts5500_sbc *sbc)
+{
+ u8 tmp;
+ int ret = 0;
+
+ if (!request_region(TS5500_PRODUCT_CODE_REG, 4, "ts5500"))
+ return -EBUSY;
+
+ mutex_lock(&ts5500->lock);
+ tmp = inb(TS5500_PRODUCT_CODE_REG);
+ if (tmp != TS5500_PRODUCT_CODE) {
+ pr_err("This platform is not a TS-5500 (found ID 0x%x)\n", tmp);
+ ret = -ENODEV;
+ goto error;
+ }
+ sbc->board_id = tmp;
+
+ tmp = inb(TS5500_SRAM_RS485_ADC_REG);
+ ts5500->sram = !!(tmp & TS5500_SRAM_OPT);
+ ts5500->rs485 = !!(tmp & TS5500_RS485_OPT);
+ ts5500->adc = !!(tmp & TS5500_ADC_OPT);
+
+ tmp = inb(TS5500_ERESET_ITR_REG);
+ ts5500->ereset = !!(tmp & TS5500_ERESET_OPT);
+ ts5500->itr = !!(tmp & TS5500_ITR_OPT);
+
+ tmp = inb(TS5500_LED_JMPRS_REG);
+ sbc->jumpers = tmp & 0xFE; /* All bits except the first (LED) */
+
+error:
+ mutex_unlock(&ts5500->lock);
+ release_region(TS5500_PRODUCT_CODE_REG, 4);
+ return ret;
+}
+
+#define TS5500_IS_JP_SET(sbc, jmp) (!!(sbc->jumpers & TS5500_JP##jmp))
+
+static struct platform_device *ts5500_devices[] __initdata = {
+};
+
+static ssize_t ts5500_show_id(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ts5500_sbc *sbc = dev_get_drvdata(dev);
+
+ return sprintf(buf, "0x%x\n", sbc->board_id);
+}
+
+static ssize_t ts5500_show_sram(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ts5500_sbc *sbc = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", sbc->sram);
+}
+
+static ssize_t ts5500_show_rs485(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ts5500_sbc *sbc = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", sbc->rs485);
+}
+
+static ssize_t ts5500_show_adc(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ts5500_sbc *sbc = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", sbc->adc);
+}
+
+static ssize_t ts5500_show_ereset(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct ts5500_sbc *sbc = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", sbc->ereset);
+}
+
+static ssize_t ts5500_show_itr(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct ts5500_sbc *sbc = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", sbc->itr);
+}
+
+#define TS5500_SHOW_JP(jp) \
+ static ssize_t ts5500_show_jp##jp(struct device *dev, \
+ struct device_attribute *attr,\
+ char *buf) \
+ { \
+ struct ts5500_sbc *sbc = dev_get_drvdata(dev); \
+ return sprintf(buf, "%d\n", TS5500_IS_JP_SET(sbc, jp)); \
+ }
+
+TS5500_SHOW_JP(1)
+TS5500_SHOW_JP(2)
+TS5500_SHOW_JP(3)
+TS5500_SHOW_JP(4)
+TS5500_SHOW_JP(5)
+TS5500_SHOW_JP(6)
+
+static DEVICE_ATTR(id, S_IRUGO, ts5500_show_id, NULL);
+static DEVICE_ATTR(sram, S_IRUGO, ts5500_show_sram, NULL);
+static DEVICE_ATTR(rs485, S_IRUGO, ts5500_show_rs485, NULL);
+static DEVICE_ATTR(adc, S_IRUGO, ts5500_show_adc, NULL);
+static DEVICE_ATTR(ereset, S_IRUGO, ts5500_show_ereset, NULL);
+static DEVICE_ATTR(itr, S_IRUGO, ts5500_show_itr, NULL);
+static DEVICE_ATTR(jp1, S_IRUGO, ts5500_show_jp1, NULL);
+static DEVICE_ATTR(jp2, S_IRUGO, ts5500_show_jp2, NULL);
+static DEVICE_ATTR(jp3, S_IRUGO, ts5500_show_jp3, NULL);
+static DEVICE_ATTR(jp4, S_IRUGO, ts5500_show_jp4, NULL);
+static DEVICE_ATTR(jp5, S_IRUGO, ts5500_show_jp5, NULL);
+static DEVICE_ATTR(jp6, S_IRUGO, ts5500_show_jp6, NULL);
+
+static struct attribute *ts5500_attributes[] = {
+ &dev_attr_id.attr,
+ &dev_attr_sram.attr,
+ &dev_attr_rs485.attr,
+ &dev_attr_adc.attr,
+ &dev_attr_ereset.attr,
+ &dev_attr_itr.attr,
+ &dev_attr_jp1.attr,
+ &dev_attr_jp2.attr,
+ &dev_attr_jp3.attr,
+ &dev_attr_jp4.attr,
+ &dev_attr_jp5.attr,
+ &dev_attr_jp6.attr,
+ NULL
+};
+
+static const struct attribute_group ts5500_attr_group = {
+ .attrs = ts5500_attributes
+};
+
+static int __init ts5500_init(void)
+{
+ int ret;
+ struct platform_device *pdev;
+
+ /*
+ * There is no DMI available, or PCI bridge subvendor info,
+ * only the BIOS provides a 16-bit identification call.
+ * It is safer to check for a TS-5500 specific hardware
+ * such as the processor, then find a signature in the BIOS.
+ */
+ ret = ts5500_pre_detect_hw();
+ if (ret)
+ return ret;
+
+ ret = ts5500_bios_signature();
+ if (ret)
+ return ret;
+
+ ts5500 = kzalloc(sizeof(struct ts5500_sbc), GFP_KERNEL);
+ if (!ts5500)
+ return -ENOMEM;
+ mutex_init(&ts5500->lock);
+
+ ret = ts5500_detect_config(ts5500);
+ if (ret)
+ goto release_mem;
+
+ pdev = platform_device_register_simple("ts5500", -1, NULL, 0);
+ if (IS_ERR(pdev)) {
+ ret = PTR_ERR(pdev);
+ goto release_mem;
+ }
+ platform_set_drvdata(pdev, ts5500);
+
+ ret = platform_add_devices(ts5500_devices, ARRAY_SIZE(ts5500_devices));
+ if (ret)
+ goto release_pdev;
+
+ ret = sysfs_create_group(&pdev->dev.kobj,
+ &ts5500_attr_group);
+ if (ret)
+ goto release_pdev;
+
+ return 0;
+
+release_pdev:
+ platform_device_unregister(pdev);
+release_mem:
+ kfree(ts5500);
+
+ return ret;
+}
+postcore_initcall(ts5500_init);
+
+MODULE_AUTHOR("Jonas Fonseca <jonas.fonseca@savoirfairelinux.com>");
+MODULE_AUTHOR("Alexandre Savard <alexandre.savard@savoirfairelinux.com>");
+MODULE_AUTHOR("Vivien Didelot <vivien.didelot@savoirfairelinux.com>");
+MODULE_DESCRIPTION("Technologic Systems TS-5500 Board's platform driver");
+MODULE_LICENSE("GPL");
next prev parent reply other threads:[~2011-11-18 23:01 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-02 18:30 [PATCH v3 0/4] Support for the TS-5500 platform Vivien Didelot
2011-09-02 18:30 ` [PATCH v3 1/4] platform: (TS-5500) add base support Vivien Didelot
2011-11-18 23:00 ` tip-bot for Vivien Didelot [this message]
2011-09-02 18:30 ` [PATCH v3 2/4] platform: (TS-5500) add GPIO support Vivien Didelot
2011-11-18 23:01 ` [tip:x86/platform] x86/platform: Add TS-5500 " tip-bot for Jerome Oufella
2011-09-02 18:30 ` [PATCH v3 3/4] platform: (TS-5500) add LED support Vivien Didelot
2011-11-18 23:02 ` [tip:x86/platform] x86/platform: Add TS-5500 " tip-bot for Jonas Fonseca
2011-09-02 18:30 ` [PATCH v3 4/4] platform: (TS-5500) add ADC support Vivien Didelot
2011-11-18 23:03 ` [tip:x86/platform] x86/platform: Add TS-5500 " tip-bot for Jonas Fonseca
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=tip-37f9a16c166c51be114bb5b2ff670ccaa893f978@git.kernel.org \
--to=vivien.didelot@savoirfairelinux.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=mingo@redhat.com \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.