* [PATCH 0/2] ARM: orion5x: Move micon code to a MFD driver
@ 2016-12-29 0:01 Florian Fainelli
2016-12-29 0:01 ` [PATCH 1/2] mfd: micon: Add Buffalo Kurobox Pro, Terastation II Pro/Live driver Florian Fainelli
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Florian Fainelli @ 2016-12-29 0:01 UTC (permalink / raw)
To: linux-arm-kernel
Cc: lee.jones, linux, gregory.clement, andrew, jason, linux-kernel,
Florian Fainelli
Hi all,
This patch series removes some duplicate code between the Kurobox and the
Terastation Pro 2 since they both use the same on-board microcontroller (micon)
attached to their UART1 for system restart.
Future patches will add support for the LEDs, temperature, FAN that the micro
controller provides.
Florian Fainelli (2):
mfd: micon: Add Buffalo Kurobox Pro, Terastation II Pro/Live driver
ARM: orion5x: Utilize micon MFD driver
arch/arm/mach-orion5x/Kconfig | 4 +
arch/arm/mach-orion5x/kurobox_pro-setup.c | 149 +++---------------
arch/arm/mach-orion5x/terastation_pro2-setup.c | 149 +++---------------
drivers/mfd/Kconfig | 8 +
drivers/mfd/Makefile | 2 +
drivers/mfd/micon.c | 204 +++++++++++++++++++++++++
include/linux/platform_data/micon.h | 10 ++
7 files changed, 264 insertions(+), 262 deletions(-)
create mode 100644 drivers/mfd/micon.c
create mode 100644 include/linux/platform_data/micon.h
--
2.9.3
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] mfd: micon: Add Buffalo Kurobox Pro, Terastation II Pro/Live driver
2016-12-29 0:01 [PATCH 0/2] ARM: orion5x: Move micon code to a MFD driver Florian Fainelli
@ 2016-12-29 0:01 ` Florian Fainelli
2017-01-04 11:22 ` Lee Jones
2016-12-29 0:01 ` [PATCH 2/2] ARM: orion5x: Utilize micon MFD driver Florian Fainelli
2017-01-02 21:24 ` [PATCH 0/2] ARM: orion5x: Move micon code to a " Andrew Lunn
2 siblings, 1 reply; 7+ messages in thread
From: Florian Fainelli @ 2016-12-29 0:01 UTC (permalink / raw)
To: linux-arm-kernel
Cc: lee.jones, linux, gregory.clement, andrew, jason, linux-kernel,
Florian Fainelli
This driver is currently only used to reboot the devices, but the
microcontroller hanging off UART1 on the Buffalo Kurobox Pro and
Terastation II Pro/Live is capable of a lot more than that, which we
will support in subsequent patches. For now, just add the reboot
functionality to make the kernel reboot correctly.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/mfd/Kconfig | 8 ++
drivers/mfd/Makefile | 2 +
drivers/mfd/micon.c | 204 ++++++++++++++++++++++++++++++++++++
include/linux/platform_data/micon.h | 10 ++
4 files changed, 224 insertions(+)
create mode 100644 drivers/mfd/micon.c
create mode 100644 include/linux/platform_data/micon.h
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 4ce3b6f11830..e7df3d29351c 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -352,6 +352,14 @@ config MFD_MX25_TSADC
i.MX25 processors. They consist of a conversion queue for general
purpose ADC and a queue for Touchscreens.
+config MFD_MICON
+ bool "Buffalo Kurobox Pro/Terastation II Pro/Live MCU interface"
+ depends on PLAT_ORION
+ help
+ Enables support for the UART1 attached micro controller on Buffalo
+ Kurobox Pro and Terastation II Pro/Live NAS devices. Used for
+ machine restart.
+
config MFD_HI6421_PMIC
tristate "HiSilicon Hi6421 PMU/Codec IC"
depends on OF
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index dda4d4f73ad7..61a226878129 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -94,6 +94,8 @@ obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o
obj-$(CONFIG_MFD_MC13XXX_SPI) += mc13xxx-spi.o
obj-$(CONFIG_MFD_MC13XXX_I2C) += mc13xxx-i2c.o
+obj-$(CONFIG_MFD_MICON) += micon.o
+
obj-$(CONFIG_MFD_CORE) += mfd-core.o
obj-$(CONFIG_EZX_PCAP) += ezx-pcap.o
diff --git a/drivers/mfd/micon.c b/drivers/mfd/micon.c
new file mode 100644
index 000000000000..fe56abdc0160
--- /dev/null
+++ b/drivers/mfd/micon.c
@@ -0,0 +1,204 @@
+/*
+ * Buffalo Kurobox/Terastation Pro II specific power off method via
+ * UART1-attached microcontroller
+ *
+ * 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/kernel.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/micon.h>
+#include <linux/serial_reg.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+
+struct micon_priv {
+ struct device *dev;
+ void __iomem *base;
+ int tclk;
+ struct notifier_block nb;
+};
+
+#define UART1_REG(x) ((UART_##x) << 2)
+
+static int miconread(struct micon_priv *priv, unsigned char *buf, int count)
+{
+ int i;
+ int timeout;
+
+ for (i = 0; i < count; i++) {
+ timeout = 10;
+
+ while (!(readl(priv->base + UART1_REG(LSR)) & UART_LSR_DR)) {
+ if (--timeout == 0)
+ break;
+ udelay(1000);
+ }
+
+ if (timeout == 0)
+ break;
+ buf[i] = readl(priv->base + UART1_REG(RX));
+ }
+
+ /* return read bytes */
+ return i;
+}
+
+static int miconwrite(struct micon_priv *priv, const unsigned char *buf,
+ int count)
+{
+ int i = 0;
+
+ while (count--) {
+ while (!(readl(priv->base + UART1_REG(LSR)) & UART_LSR_THRE))
+ barrier();
+ writel(buf[i++], priv->base + UART1_REG(TX));
+ }
+
+ return 0;
+}
+
+static int miconsend(struct micon_priv *priv, const unsigned char *data,
+ int count)
+{
+ int i;
+ unsigned char checksum = 0;
+ unsigned char recv_buf[40];
+ unsigned char send_buf[40];
+ unsigned char correct_ack[3];
+ int retry = 2;
+
+ /* Generate checksum */
+ for (i = 0; i < count; i++)
+ checksum -= data[i];
+
+ do {
+ /* Send data */
+ miconwrite(priv, data, count);
+
+ /* send checksum */
+ miconwrite(priv, &checksum, 1);
+
+ if (miconread(priv, recv_buf, sizeof(recv_buf)) <= 3) {
+ dev_err(priv->dev, ">%s: receive failed.\n", __func__);
+
+ /* send preamble to clear the receive buffer */
+ memset(&send_buf, 0xff, sizeof(send_buf));
+ miconwrite(priv, send_buf, sizeof(send_buf));
+
+ /* make dummy reads */
+ mdelay(100);
+ miconread(priv, recv_buf, sizeof(recv_buf));
+ } else {
+ /* Generate expected ack */
+ correct_ack[0] = 0x01;
+ correct_ack[1] = data[1];
+ correct_ack[2] = 0x00;
+
+ /* checksum Check */
+ if ((recv_buf[0] + recv_buf[1] + recv_buf[2] +
+ recv_buf[3]) & 0xFF) {
+ dev_err(priv->dev, ">%s: Checksum Error : "
+ "Received data[%02x, %02x, %02x, %02x]"
+ "\n", __func__, recv_buf[0],
+ recv_buf[1], recv_buf[2], recv_buf[3]);
+ } else {
+ /* Check Received Data */
+ if (correct_ack[0] == recv_buf[0] &&
+ correct_ack[1] == recv_buf[1] &&
+ correct_ack[2] == recv_buf[2]) {
+ /* Interval for next command */
+ mdelay(10);
+
+ /* Receive ACK */
+ return 0;
+ }
+ }
+ /* Received NAK or illegal Data */
+ dev_err(priv->dev, ">%s: Error : NAK or Illegal Data "
+ "Received\n", __func__);
+ }
+ } while (retry--);
+
+ /* Interval for next command */
+ mdelay(10);
+
+ return -1;
+}
+
+static int restart_handler(struct notifier_block *this,
+ unsigned long code, void *cmd)
+{
+ struct micon_priv *priv = container_of(this, struct micon_priv, nb);
+
+ const unsigned char watchdogkill[] = {0x01, 0x35, 0x00};
+ const unsigned char shutdownwait[] = {0x00, 0x0c};
+ const unsigned char poweroff[] = {0x00, 0x06};
+ /* 38400 baud divisor */
+ unsigned int divisor = ((priv->tclk + (8 * 38400)) / (16 * 38400));
+
+ if (code != SYS_DOWN && code != SYS_HALT)
+ return NOTIFY_DONE;
+
+ dev_info(priv->dev, "%s: triggering power-off...\n", __func__);
+
+ /* hijack uart1 and reset into sane state (38400,8n1,even parity) */
+ writel(0x83, priv->base + UART1_REG(LCR));
+ writel(divisor & 0xff, priv->base + UART1_REG(DLL));
+ writel((divisor >> 8) & 0xff, priv->base + UART1_REG(DLM));
+ writel(0x1b, priv->base + UART1_REG(LCR));
+ writel(0x00, priv->base + UART1_REG(IER));
+ writel(0x07, priv->base + UART1_REG(FCR));
+ writel(0x00, priv->base + UART1_REG(MCR));
+
+ /* Send the commands to shutdown the Terastation Pro II */
+ miconsend(priv, watchdogkill, sizeof(watchdogkill));
+ miconsend(priv, shutdownwait, sizeof(shutdownwait));
+ miconsend(priv, poweroff, sizeof(poweroff));
+
+ return NOTIFY_DONE;
+}
+
+static int micon_probe(struct platform_device *pdev)
+{
+ struct micon_platform_data *pdata = pdev->dev.platform_data;
+ struct micon_priv *priv;
+ struct resource *r;
+ int ret;
+
+ if (!pdata)
+ return -ENODEV;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->dev = &pdev->dev;
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ /* Don't request exclusive access since 8250 may also utilize this
+ * resource
+ */
+ priv->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
+ if (IS_ERR(priv->base))
+ return -ENOMEM;
+
+ priv->tclk = pdata->tclk;
+
+ priv->nb.notifier_call = restart_handler;
+
+ return register_reboot_notifier(&priv->nb);
+}
+
+static struct platform_driver micon_driver = {
+ .probe = micon_probe,
+ .driver = {
+ .name = MICON_NAME,
+ },
+};
+builtin_platform_driver(micon_driver);
diff --git a/include/linux/platform_data/micon.h b/include/linux/platform_data/micon.h
new file mode 100644
index 000000000000..67dbaad5dfaa
--- /dev/null
+++ b/include/linux/platform_data/micon.h
@@ -0,0 +1,10 @@
+#ifndef __MICON_PDATA_H
+#define __MICON_PDATA_H
+
+#define MICON_NAME "micon"
+
+struct micon_platform_data {
+ int tclk;
+};
+
+#endif /* __MICON_PDATA_H */
--
2.9.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/2] ARM: orion5x: Utilize micon MFD driver
2016-12-29 0:01 [PATCH 0/2] ARM: orion5x: Move micon code to a MFD driver Florian Fainelli
2016-12-29 0:01 ` [PATCH 1/2] mfd: micon: Add Buffalo Kurobox Pro, Terastation II Pro/Live driver Florian Fainelli
@ 2016-12-29 0:01 ` Florian Fainelli
2017-01-02 21:24 ` [PATCH 0/2] ARM: orion5x: Move micon code to a " Andrew Lunn
2 siblings, 0 replies; 7+ messages in thread
From: Florian Fainelli @ 2016-12-29 0:01 UTC (permalink / raw)
To: linux-arm-kernel
Cc: lee.jones, linux, gregory.clement, andrew, jason, linux-kernel,
Florian Fainelli
Convert the Kurobox Pro and Terastation Pro II/Live machines to utilize
the MFD_MICON driver which currently provides reboot support, but will
later be extended to support LEDs, buttons, FAN control and temperature.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
arch/arm/mach-orion5x/Kconfig | 4 +
arch/arm/mach-orion5x/kurobox_pro-setup.c | 149 +++----------------------
arch/arm/mach-orion5x/terastation_pro2-setup.c | 149 +++----------------------
3 files changed, 40 insertions(+), 262 deletions(-)
diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig
index 633442ad4e4c..1146181280d0 100644
--- a/arch/arm/mach-orion5x/Kconfig
+++ b/arch/arm/mach-orion5x/Kconfig
@@ -51,6 +51,8 @@ config MACH_RD88F5182_DT
config MACH_KUROBOX_PRO
bool "KuroBox Pro"
select I2C_BOARDINFO if I2C
+ select MFD_CORE
+ select MFD_MICON
help
Say 'Y' here if you want your kernel to support the
KuroBox Pro platform.
@@ -71,6 +73,8 @@ config MACH_TS209
QNAP TS-109/TS-209 platform.
config MACH_TERASTATION_PRO2
+ select MFD_CORE
+ select MFD_MICON
bool "Buffalo Terastation Pro II/Live"
help
Say 'Y' here if you want your kernel to support the
diff --git a/arch/arm/mach-orion5x/kurobox_pro-setup.c b/arch/arm/mach-orion5x/kurobox_pro-setup.c
index 9dc3f59bed9c..b1c27c93b4c5 100644
--- a/arch/arm/mach-orion5x/kurobox_pro-setup.c
+++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c
@@ -24,6 +24,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
#include <linux/platform_data/mtd-orion_nand.h>
+#include <linux/platform_data/micon.h>
#include "common.h"
#include "mpp.h"
#include "orion5x.h"
@@ -180,136 +181,23 @@ static struct mv_sata_platform_data kurobox_pro_sata_data = {
/*****************************************************************************
* Kurobox Pro specific power off method via UART1-attached microcontroller
****************************************************************************/
+struct resource kurobox_pro_micon_res = {
+ .start = UART1_PHYS_BASE,
+ .end = UART1_PHYS_BASE + 0x100,
+ .flags = IORESOURCE_MEM,
+};
-#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2))
-
-static int kurobox_pro_miconread(unsigned char *buf, int count)
-{
- int i;
- int timeout;
-
- for (i = 0; i < count; i++) {
- timeout = 10;
-
- while (!(readl(UART1_REG(LSR)) & UART_LSR_DR)) {
- if (--timeout == 0)
- break;
- udelay(1000);
- }
-
- if (timeout == 0)
- break;
- buf[i] = readl(UART1_REG(RX));
- }
-
- /* return read bytes */
- return i;
-}
-
-static int kurobox_pro_miconwrite(const unsigned char *buf, int count)
-{
- int i = 0;
-
- while (count--) {
- while (!(readl(UART1_REG(LSR)) & UART_LSR_THRE))
- barrier();
- writel(buf[i++], UART1_REG(TX));
- }
-
- return 0;
-}
-
-static int kurobox_pro_miconsend(const unsigned char *data, int count)
-{
- int i;
- unsigned char checksum = 0;
- unsigned char recv_buf[40];
- unsigned char send_buf[40];
- unsigned char correct_ack[3];
- int retry = 2;
-
- /* Generate checksum */
- for (i = 0; i < count; i++)
- checksum -= data[i];
-
- do {
- /* Send data */
- kurobox_pro_miconwrite(data, count);
-
- /* send checksum */
- kurobox_pro_miconwrite(&checksum, 1);
-
- if (kurobox_pro_miconread(recv_buf, sizeof(recv_buf)) <= 3) {
- printk(KERN_ERR ">%s: receive failed.\n", __func__);
-
- /* send preamble to clear the receive buffer */
- memset(&send_buf, 0xff, sizeof(send_buf));
- kurobox_pro_miconwrite(send_buf, sizeof(send_buf));
-
- /* make dummy reads */
- mdelay(100);
- kurobox_pro_miconread(recv_buf, sizeof(recv_buf));
- } else {
- /* Generate expected ack */
- correct_ack[0] = 0x01;
- correct_ack[1] = data[1];
- correct_ack[2] = 0x00;
-
- /* checksum Check */
- if ((recv_buf[0] + recv_buf[1] + recv_buf[2] +
- recv_buf[3]) & 0xFF) {
- printk(KERN_ERR ">%s: Checksum Error : "
- "Received data[%02x, %02x, %02x, %02x]"
- "\n", __func__, recv_buf[0],
- recv_buf[1], recv_buf[2], recv_buf[3]);
- } else {
- /* Check Received Data */
- if (correct_ack[0] == recv_buf[0] &&
- correct_ack[1] == recv_buf[1] &&
- correct_ack[2] == recv_buf[2]) {
- /* Interval for next command */
- mdelay(10);
-
- /* Receive ACK */
- return 0;
- }
- }
- /* Received NAK or illegal Data */
- printk(KERN_ERR ">%s: Error : NAK or Illegal Data "
- "Received\n", __func__);
- }
- } while (retry--);
-
- /* Interval for next command */
- mdelay(10);
+static struct micon_platform_data kurobox_pro_micon_pdata;
- return -1;
-}
-
-static void kurobox_pro_power_off(void)
-{
- const unsigned char watchdogkill[] = {0x01, 0x35, 0x00};
- const unsigned char shutdownwait[] = {0x00, 0x0c};
- const unsigned char poweroff[] = {0x00, 0x06};
- /* 38400 baud divisor */
- const unsigned divisor = ((orion5x_tclk + (8 * 38400)) / (16 * 38400));
-
- pr_info("%s: triggering power-off...\n", __func__);
-
- /* hijack uart1 and reset into sane state (38400,8n1,even parity) */
- writel(0x83, UART1_REG(LCR));
- writel(divisor & 0xff, UART1_REG(DLL));
- writel((divisor >> 8) & 0xff, UART1_REG(DLM));
- writel(0x1b, UART1_REG(LCR));
- writel(0x00, UART1_REG(IER));
- writel(0x07, UART1_REG(FCR));
- writel(0x00, UART1_REG(MCR));
-
- /* Send the commands to shutdown the Kurobox Pro */
- kurobox_pro_miconsend(watchdogkill, sizeof(watchdogkill)) ;
- kurobox_pro_miconsend(shutdownwait, sizeof(shutdownwait)) ;
- kurobox_pro_miconsend(poweroff, sizeof(poweroff));
-}
+static struct platform_device kurobox_pro_micon = {
+ .name = MICON_NAME,
+ .id = -1,
+ .dev = {
+ .platform_data = &kurobox_pro_micon_pdata,
+ },
+ .resource = &kurobox_pro_micon_res,
+ .num_resources = 1,
+};
/*****************************************************************************
* General Setup
@@ -364,6 +252,8 @@ static void __init kurobox_pro_init(void)
KUROBOX_PRO_NOR_BOOT_BASE,
KUROBOX_PRO_NOR_BOOT_SIZE);
platform_device_register(&kurobox_pro_nor_flash);
+ kurobox_pro_micon_pdata.tclk = orion5x_tclk;
+ platform_device_register(&kurobox_pro_micon);
if (machine_is_kurobox_pro()) {
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_TARGET(0),
@@ -374,9 +264,6 @@ static void __init kurobox_pro_init(void)
}
i2c_register_board_info(0, &kurobox_pro_i2c_rtc, 1);
-
- /* register Kurobox Pro specific power-off method */
- pm_power_off = kurobox_pro_power_off;
}
#ifdef CONFIG_MACH_KUROBOX_PRO
diff --git a/arch/arm/mach-orion5x/terastation_pro2-setup.c b/arch/arm/mach-orion5x/terastation_pro2-setup.c
index deb5e29ac669..7493f64388d6 100644
--- a/arch/arm/mach-orion5x/terastation_pro2-setup.c
+++ b/arch/arm/mach-orion5x/terastation_pro2-setup.c
@@ -19,6 +19,7 @@
#include <linux/mv643xx_eth.h>
#include <linux/i2c.h>
#include <linux/serial_reg.h>
+#include <linux/platform_data/micon.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
@@ -159,136 +160,23 @@ static struct i2c_board_info __initdata tsp2_i2c_rtc = {
* Terastation Pro II specific power off method via UART1-attached
* microcontroller
****************************************************************************/
+struct resource tsp2_micon_res = {
+ .start = UART1_PHYS_BASE,
+ .end = UART1_PHYS_BASE + 0x100,
+ .flags = IORESOURCE_MEM,
+};
-#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2))
-
-static int tsp2_miconread(unsigned char *buf, int count)
-{
- int i;
- int timeout;
-
- for (i = 0; i < count; i++) {
- timeout = 10;
-
- while (!(readl(UART1_REG(LSR)) & UART_LSR_DR)) {
- if (--timeout == 0)
- break;
- udelay(1000);
- }
-
- if (timeout == 0)
- break;
- buf[i] = readl(UART1_REG(RX));
- }
-
- /* return read bytes */
- return i;
-}
-
-static int tsp2_miconwrite(const unsigned char *buf, int count)
-{
- int i = 0;
-
- while (count--) {
- while (!(readl(UART1_REG(LSR)) & UART_LSR_THRE))
- barrier();
- writel(buf[i++], UART1_REG(TX));
- }
-
- return 0;
-}
-
-static int tsp2_miconsend(const unsigned char *data, int count)
-{
- int i;
- unsigned char checksum = 0;
- unsigned char recv_buf[40];
- unsigned char send_buf[40];
- unsigned char correct_ack[3];
- int retry = 2;
-
- /* Generate checksum */
- for (i = 0; i < count; i++)
- checksum -= data[i];
-
- do {
- /* Send data */
- tsp2_miconwrite(data, count);
-
- /* send checksum */
- tsp2_miconwrite(&checksum, 1);
-
- if (tsp2_miconread(recv_buf, sizeof(recv_buf)) <= 3) {
- printk(KERN_ERR ">%s: receive failed.\n", __func__);
-
- /* send preamble to clear the receive buffer */
- memset(&send_buf, 0xff, sizeof(send_buf));
- tsp2_miconwrite(send_buf, sizeof(send_buf));
-
- /* make dummy reads */
- mdelay(100);
- tsp2_miconread(recv_buf, sizeof(recv_buf));
- } else {
- /* Generate expected ack */
- correct_ack[0] = 0x01;
- correct_ack[1] = data[1];
- correct_ack[2] = 0x00;
-
- /* checksum Check */
- if ((recv_buf[0] + recv_buf[1] + recv_buf[2] +
- recv_buf[3]) & 0xFF) {
- printk(KERN_ERR ">%s: Checksum Error : "
- "Received data[%02x, %02x, %02x, %02x]"
- "\n", __func__, recv_buf[0],
- recv_buf[1], recv_buf[2], recv_buf[3]);
- } else {
- /* Check Received Data */
- if (correct_ack[0] == recv_buf[0] &&
- correct_ack[1] == recv_buf[1] &&
- correct_ack[2] == recv_buf[2]) {
- /* Interval for next command */
- mdelay(10);
-
- /* Receive ACK */
- return 0;
- }
- }
- /* Received NAK or illegal Data */
- printk(KERN_ERR ">%s: Error : NAK or Illegal Data "
- "Received\n", __func__);
- }
- } while (retry--);
-
- /* Interval for next command */
- mdelay(10);
+static struct micon_platform_data tsp2_micon_pdata;
- return -1;
-}
-
-static void tsp2_power_off(void)
-{
- const unsigned char watchdogkill[] = {0x01, 0x35, 0x00};
- const unsigned char shutdownwait[] = {0x00, 0x0c};
- const unsigned char poweroff[] = {0x00, 0x06};
- /* 38400 baud divisor */
- const unsigned divisor = ((orion5x_tclk + (8 * 38400)) / (16 * 38400));
-
- pr_info("%s: triggering power-off...\n", __func__);
-
- /* hijack uart1 and reset into sane state (38400,8n1,even parity) */
- writel(0x83, UART1_REG(LCR));
- writel(divisor & 0xff, UART1_REG(DLL));
- writel((divisor >> 8) & 0xff, UART1_REG(DLM));
- writel(0x1b, UART1_REG(LCR));
- writel(0x00, UART1_REG(IER));
- writel(0x07, UART1_REG(FCR));
- writel(0x00, UART1_REG(MCR));
-
- /* Send the commands to shutdown the Terastation Pro II */
- tsp2_miconsend(watchdogkill, sizeof(watchdogkill)) ;
- tsp2_miconsend(shutdownwait, sizeof(shutdownwait)) ;
- tsp2_miconsend(poweroff, sizeof(poweroff));
-}
+static struct platform_device tsp2_micon = {
+ .name = MICON_NAME,
+ .id = -1,
+ .dev = {
+ .platform_data = &tsp2_micon_pdata,
+ },
+ .resource = &tsp2_micon_res,
+ .num_resources = 1,
+};
/*****************************************************************************
* General Setup
@@ -334,6 +222,8 @@ static void __init tsp2_init(void)
TSP2_NOR_BOOT_BASE,
TSP2_NOR_BOOT_SIZE);
platform_device_register(&tsp2_nor_flash);
+ tsp2_micon_pdata.tclk = orion5x_tclk;
+ platform_device_register(&tsp2_micon);
orion5x_ehci0_init();
orion5x_eth_init(&tsp2_eth_data);
@@ -351,9 +241,6 @@ static void __init tsp2_init(void)
if (tsp2_i2c_rtc.irq == 0)
pr_warn("tsp2_init: failed to get RTC IRQ\n");
i2c_register_board_info(0, &tsp2_i2c_rtc, 1);
-
- /* register Terastation Pro II specific power-off method */
- pm_power_off = tsp2_power_off;
}
MACHINE_START(TERASTATION_PRO2, "Buffalo Terastation Pro II/Live")
--
2.9.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 0/2] ARM: orion5x: Move micon code to a MFD driver
2016-12-29 0:01 [PATCH 0/2] ARM: orion5x: Move micon code to a MFD driver Florian Fainelli
2016-12-29 0:01 ` [PATCH 1/2] mfd: micon: Add Buffalo Kurobox Pro, Terastation II Pro/Live driver Florian Fainelli
2016-12-29 0:01 ` [PATCH 2/2] ARM: orion5x: Utilize micon MFD driver Florian Fainelli
@ 2017-01-02 21:24 ` Andrew Lunn
2 siblings, 0 replies; 7+ messages in thread
From: Andrew Lunn @ 2017-01-02 21:24 UTC (permalink / raw)
To: Florian Fainelli
Cc: linux-arm-kernel, lee.jones, linux, gregory.clement, jason, linux-kernel
On Wed, Dec 28, 2016 at 04:01:35PM -0800, Florian Fainelli wrote:
> Hi all,
>
> This patch series removes some duplicate code between the Kurobox and the
> Terastation Pro 2 since they both use the same on-board microcontroller (micon)
> attached to their UART1 for system restart.
>
> Future patches will add support for the LEDs, temperature, FAN that the micro
> controller provides.
Hi Florian
Are you coordinating with Roger Shimizu <rogershimizu@gmail.com>. He
has a conflicting patchset doing something similar/different.
Andrew
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] mfd: micon: Add Buffalo Kurobox Pro, Terastation II Pro/Live driver
2016-12-29 0:01 ` [PATCH 1/2] mfd: micon: Add Buffalo Kurobox Pro, Terastation II Pro/Live driver Florian Fainelli
@ 2017-01-04 11:22 ` Lee Jones
2017-01-05 2:26 ` Florian Fainelli
0 siblings, 1 reply; 7+ messages in thread
From: Lee Jones @ 2017-01-04 11:22 UTC (permalink / raw)
To: Florian Fainelli
Cc: linux-arm-kernel, linux, gregory.clement, andrew, jason, linux-kernel
On Wed, 28 Dec 2016, Florian Fainelli wrote:
> This driver is currently only used to reboot the devices, but the
> microcontroller hanging off UART1 on the Buffalo Kurobox Pro and
> Terastation II Pro/Live is capable of a lot more than that, which we
> will support in subsequent patches. For now, just add the reboot
> functionality to make the kernel reboot correctly.
This is not an MFD driver. You have written a UART driver.
Please relocate it to drivers/char/tty/serial.
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
> drivers/mfd/Kconfig | 8 ++
> drivers/mfd/Makefile | 2 +
> drivers/mfd/micon.c | 204 ++++++++++++++++++++++++++++++++++++
> include/linux/platform_data/micon.h | 10 ++
> 4 files changed, 224 insertions(+)
> create mode 100644 drivers/mfd/micon.c
> create mode 100644 include/linux/platform_data/micon.h
>
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 4ce3b6f11830..e7df3d29351c 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -352,6 +352,14 @@ config MFD_MX25_TSADC
> i.MX25 processors. They consist of a conversion queue for general
> purpose ADC and a queue for Touchscreens.
>
> +config MFD_MICON
> + bool "Buffalo Kurobox Pro/Terastation II Pro/Live MCU interface"
> + depends on PLAT_ORION
> + help
> + Enables support for the UART1 attached micro controller on Buffalo
> + Kurobox Pro and Terastation II Pro/Live NAS devices. Used for
> + machine restart.
> +
> config MFD_HI6421_PMIC
> tristate "HiSilicon Hi6421 PMU/Codec IC"
> depends on OF
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index dda4d4f73ad7..61a226878129 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -94,6 +94,8 @@ obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o
> obj-$(CONFIG_MFD_MC13XXX_SPI) += mc13xxx-spi.o
> obj-$(CONFIG_MFD_MC13XXX_I2C) += mc13xxx-i2c.o
>
> +obj-$(CONFIG_MFD_MICON) += micon.o
> +
> obj-$(CONFIG_MFD_CORE) += mfd-core.o
>
> obj-$(CONFIG_EZX_PCAP) += ezx-pcap.o
> diff --git a/drivers/mfd/micon.c b/drivers/mfd/micon.c
> new file mode 100644
> index 000000000000..fe56abdc0160
> --- /dev/null
> +++ b/drivers/mfd/micon.c
> @@ -0,0 +1,204 @@
> +/*
> + * Buffalo Kurobox/Terastation Pro II specific power off method via
> + * UART1-attached microcontroller
> + * 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/kernel.h>
> +#include <linux/io.h>
> +#include <linux/delay.h>
> +#include <linux/platform_device.h>
> +#include <linux/platform_data/micon.h>
> +#include <linux/serial_reg.h>
> +#include <linux/notifier.h>
> +#include <linux/reboot.h>
> +
> +struct micon_priv {
> + struct device *dev;
> + void __iomem *base;
> + int tclk;
> + struct notifier_block nb;
> +};
> +
> +#define UART1_REG(x) ((UART_##x) << 2)
> +
> +static int miconread(struct micon_priv *priv, unsigned char *buf, int count)
> +{
> + int i;
> + int timeout;
> +
> + for (i = 0; i < count; i++) {
> + timeout = 10;
> +
> + while (!(readl(priv->base + UART1_REG(LSR)) & UART_LSR_DR)) {
> + if (--timeout == 0)
> + break;
> + udelay(1000);
> + }
> +
> + if (timeout == 0)
> + break;
> + buf[i] = readl(priv->base + UART1_REG(RX));
> + }
> +
> + /* return read bytes */
> + return i;
> +}
> +
> +static int miconwrite(struct micon_priv *priv, const unsigned char *buf,
> + int count)
> +{
> + int i = 0;
> +
> + while (count--) {
> + while (!(readl(priv->base + UART1_REG(LSR)) & UART_LSR_THRE))
> + barrier();
> + writel(buf[i++], priv->base + UART1_REG(TX));
> + }
> +
> + return 0;
> +}
> +
> +static int miconsend(struct micon_priv *priv, const unsigned char *data,
> + int count)
> +{
> + int i;
> + unsigned char checksum = 0;
> + unsigned char recv_buf[40];
> + unsigned char send_buf[40];
> + unsigned char correct_ack[3];
> + int retry = 2;
> +
> + /* Generate checksum */
> + for (i = 0; i < count; i++)
> + checksum -= data[i];
> +
> + do {
> + /* Send data */
> + miconwrite(priv, data, count);
> +
> + /* send checksum */
> + miconwrite(priv, &checksum, 1);
> +
> + if (miconread(priv, recv_buf, sizeof(recv_buf)) <= 3) {
> + dev_err(priv->dev, ">%s: receive failed.\n", __func__);
> +
> + /* send preamble to clear the receive buffer */
> + memset(&send_buf, 0xff, sizeof(send_buf));
> + miconwrite(priv, send_buf, sizeof(send_buf));
> +
> + /* make dummy reads */
> + mdelay(100);
> + miconread(priv, recv_buf, sizeof(recv_buf));
> + } else {
> + /* Generate expected ack */
> + correct_ack[0] = 0x01;
> + correct_ack[1] = data[1];
> + correct_ack[2] = 0x00;
> +
> + /* checksum Check */
> + if ((recv_buf[0] + recv_buf[1] + recv_buf[2] +
> + recv_buf[3]) & 0xFF) {
> + dev_err(priv->dev, ">%s: Checksum Error : "
> + "Received data[%02x, %02x, %02x, %02x]"
> + "\n", __func__, recv_buf[0],
> + recv_buf[1], recv_buf[2], recv_buf[3]);
> + } else {
> + /* Check Received Data */
> + if (correct_ack[0] == recv_buf[0] &&
> + correct_ack[1] == recv_buf[1] &&
> + correct_ack[2] == recv_buf[2]) {
> + /* Interval for next command */
> + mdelay(10);
> +
> + /* Receive ACK */
> + return 0;
> + }
> + }
> + /* Received NAK or illegal Data */
> + dev_err(priv->dev, ">%s: Error : NAK or Illegal Data "
> + "Received\n", __func__);
> + }
> + } while (retry--);
> +
> + /* Interval for next command */
> + mdelay(10);
> +
> + return -1;
> +}
> +
> +static int restart_handler(struct notifier_block *this,
> + unsigned long code, void *cmd)
> +{
> + struct micon_priv *priv = container_of(this, struct micon_priv, nb);
> +
> + const unsigned char watchdogkill[] = {0x01, 0x35, 0x00};
> + const unsigned char shutdownwait[] = {0x00, 0x0c};
> + const unsigned char poweroff[] = {0x00, 0x06};
> + /* 38400 baud divisor */
> + unsigned int divisor = ((priv->tclk + (8 * 38400)) / (16 * 38400));
> +
> + if (code != SYS_DOWN && code != SYS_HALT)
> + return NOTIFY_DONE;
> +
> + dev_info(priv->dev, "%s: triggering power-off...\n", __func__);
> +
> + /* hijack uart1 and reset into sane state (38400,8n1,even parity) */
> + writel(0x83, priv->base + UART1_REG(LCR));
> + writel(divisor & 0xff, priv->base + UART1_REG(DLL));
> + writel((divisor >> 8) & 0xff, priv->base + UART1_REG(DLM));
> + writel(0x1b, priv->base + UART1_REG(LCR));
> + writel(0x00, priv->base + UART1_REG(IER));
> + writel(0x07, priv->base + UART1_REG(FCR));
> + writel(0x00, priv->base + UART1_REG(MCR));
> +
> + /* Send the commands to shutdown the Terastation Pro II */
> + miconsend(priv, watchdogkill, sizeof(watchdogkill));
> + miconsend(priv, shutdownwait, sizeof(shutdownwait));
> + miconsend(priv, poweroff, sizeof(poweroff));
> +
> + return NOTIFY_DONE;
> +}
> +
> +static int micon_probe(struct platform_device *pdev)
> +{
> + struct micon_platform_data *pdata = pdev->dev.platform_data;
> + struct micon_priv *priv;
> + struct resource *r;
> + int ret;
> +
> + if (!pdata)
> + return -ENODEV;
> +
> + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + priv->dev = &pdev->dev;
> + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +
> + /* Don't request exclusive access since 8250 may also utilize this
> + * resource
> + */
> + priv->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
> + if (IS_ERR(priv->base))
> + return -ENOMEM;
> +
> + priv->tclk = pdata->tclk;
> +
> + priv->nb.notifier_call = restart_handler;
> +
> + return register_reboot_notifier(&priv->nb);
> +}
> +
> +static struct platform_driver micon_driver = {
> + .probe = micon_probe,
> + .driver = {
> + .name = MICON_NAME,
> + },
> +};
> +builtin_platform_driver(micon_driver);
> diff --git a/include/linux/platform_data/micon.h b/include/linux/platform_data/micon.h
> new file mode 100644
> index 000000000000..67dbaad5dfaa
> --- /dev/null
> +++ b/include/linux/platform_data/micon.h
> @@ -0,0 +1,10 @@
> +#ifndef __MICON_PDATA_H
> +#define __MICON_PDATA_H
> +
> +#define MICON_NAME "micon"
> +
> +struct micon_platform_data {
> + int tclk;
> +};
> +
> +#endif /* __MICON_PDATA_H */
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] mfd: micon: Add Buffalo Kurobox Pro, Terastation II Pro/Live driver
2017-01-04 11:22 ` Lee Jones
@ 2017-01-05 2:26 ` Florian Fainelli
2017-01-05 7:45 ` Lee Jones
0 siblings, 1 reply; 7+ messages in thread
From: Florian Fainelli @ 2017-01-05 2:26 UTC (permalink / raw)
To: Lee Jones
Cc: linux-arm-kernel, linux, gregory.clement, andrew, jason, linux-kernel
Le 01/04/17 à 03:22, Lee Jones a écrit :
> On Wed, 28 Dec 2016, Florian Fainelli wrote:
>
>> This driver is currently only used to reboot the devices, but the
>> microcontroller hanging off UART1 on the Buffalo Kurobox Pro and
>> Terastation II Pro/Live is capable of a lot more than that, which we
>> will support in subsequent patches. For now, just add the reboot
>> functionality to make the kernel reboot correctly.
>
> This is not an MFD driver. You have written a UART driver.
>
> Please relocate it to drivers/char/tty/serial.
Not that simple, and as explained in the cover letter the UART attached
micro controller can do a lot more than just reboot the machine, but
someone else is working on the driver, so this patch series can be ignored.
--
Florian
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] mfd: micon: Add Buffalo Kurobox Pro, Terastation II Pro/Live driver
2017-01-05 2:26 ` Florian Fainelli
@ 2017-01-05 7:45 ` Lee Jones
0 siblings, 0 replies; 7+ messages in thread
From: Lee Jones @ 2017-01-05 7:45 UTC (permalink / raw)
To: Florian Fainelli
Cc: linux-arm-kernel, linux, gregory.clement, andrew, jason, linux-kernel
On Wed, 04 Jan 2017, Florian Fainelli wrote:
> Le 01/04/17 à 03:22, Lee Jones a écrit :
> > On Wed, 28 Dec 2016, Florian Fainelli wrote:
> >
> >> This driver is currently only used to reboot the devices, but the
> >> microcontroller hanging off UART1 on the Buffalo Kurobox Pro and
> >> Terastation II Pro/Live is capable of a lot more than that, which we
> >> will support in subsequent patches. For now, just add the reboot
> >> functionality to make the kernel reboot correctly.
> >
> > This is not an MFD driver. You have written a UART driver.
> >
> > Please relocate it to drivers/char/tty/serial.
>
> Not that simple, and as explained in the cover letter the UART attached
> micro controller can do a lot more than just reboot the machine, but
That's fine. This is precisely why we have MFD. But the core (MFD)
driver should only conduct set-up of shared resources, registration of
child devices and maybe some shared functionality required by >1 child
device. All child device (i.e. UART) capability should be handled by
the child drivers.
> someone else is working on the driver, so this patch series can be ignored.
Okay.
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2017-01-05 7:41 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-29 0:01 [PATCH 0/2] ARM: orion5x: Move micon code to a MFD driver Florian Fainelli
2016-12-29 0:01 ` [PATCH 1/2] mfd: micon: Add Buffalo Kurobox Pro, Terastation II Pro/Live driver Florian Fainelli
2017-01-04 11:22 ` Lee Jones
2017-01-05 2:26 ` Florian Fainelli
2017-01-05 7:45 ` Lee Jones
2016-12-29 0:01 ` [PATCH 2/2] ARM: orion5x: Utilize micon MFD driver Florian Fainelli
2017-01-02 21:24 ` [PATCH 0/2] ARM: orion5x: Move micon code to a " Andrew Lunn
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).