aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power/reset
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2014-03-17 06:14:34 -0400
committerArnd Bergmann <arnd@arndb.de>2014-03-17 06:14:34 -0400
commitcda88c8be59128da05d7cd58f9ce2754a1416516 (patch)
treeb0af393c68b3d53fcdb100b8cb07af884bd3d4d5 /drivers/power/reset
parentde65ded49e95dbbd685b613a615f6821868e5b33 (diff)
parent200c0a3e404beab02be83e5cbf111d26b9f6ce22 (diff)
Merge tag 'mvebu-drivers-3.15-2' of git://git.infradead.org/linux-mvebu into next/drivers
Merge "mvebu drivers for v3.15" from Jason Cooper: pull request #1: - mvebu mbus - use of_find_matching_node_and_match - rtc - use PTR_ERR_OR_ZERO in isl12057 - work around issue in mv where date returned is 2038 - kirkwood -> mach-mvebu - various Kconfig oneliners to allow building kirkwood in -mvebu/ pull request #2: - reset - re-use qnap-poweroff driver for Synology NASs * tag 'mvebu-drivers-3.15-2' of git://git.infradead.org/linux-mvebu: Power: Reset: Generalize qnap-poweroff to work on Synology devices. drivers: Enable building of Kirkwood drivers for mach-mvebu rtc: mv: reset date if after year 2038 rtc: isl12057: use PTR_ERR_OR_ZERO to fix coccinelle warnings bus: mvebu-mbus: make use of of_find_matching_node_and_match Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/power/reset')
-rw-r--r--drivers/power/reset/qnap-poweroff.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/drivers/power/reset/qnap-poweroff.c b/drivers/power/reset/qnap-poweroff.c
index 37f56f7ee926..a75db7f8a92f 100644
--- a/drivers/power/reset/qnap-poweroff.c
+++ b/drivers/power/reset/qnap-poweroff.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * QNAP Turbo NAS Board power off 2 * QNAP Turbo NAS Board power off. Can also be used on Synology devices.
3 * 3 *
4 * Copyright (C) 2012 Andrew Lunn <andrew@lunn.ch> 4 * Copyright (C) 2012 Andrew Lunn <andrew@lunn.ch>
5 * 5 *
@@ -25,17 +25,43 @@
25 25
26#define UART1_REG(x) (base + ((UART_##x) << 2)) 26#define UART1_REG(x) (base + ((UART_##x) << 2))
27 27
28struct power_off_cfg {
29 u32 baud;
30 char cmd;
31};
32
33static const struct power_off_cfg qnap_power_off_cfg = {
34 .baud = 19200,
35 .cmd = 'A',
36};
37
38static const struct power_off_cfg synology_power_off_cfg = {
39 .baud = 9600,
40 .cmd = '1',
41};
42
43static const struct of_device_id qnap_power_off_of_match_table[] = {
44 { .compatible = "qnap,power-off",
45 .data = &qnap_power_off_cfg,
46 },
47 { .compatible = "synology,power-off",
48 .data = &synology_power_off_cfg,
49 },
50 {}
51};
52MODULE_DEVICE_TABLE(of, qnap_power_off_of_match_table);
53
28static void __iomem *base; 54static void __iomem *base;
29static unsigned long tclk; 55static unsigned long tclk;
56static const struct power_off_cfg *cfg;
30 57
31static void qnap_power_off(void) 58static void qnap_power_off(void)
32{ 59{
33 /* 19200 baud divisor */ 60 const unsigned divisor = ((tclk + (8 * cfg->baud)) / (16 * cfg->baud));
34 const unsigned divisor = ((tclk + (8 * 19200)) / (16 * 19200));
35 61
36 pr_err("%s: triggering power-off...\n", __func__); 62 pr_err("%s: triggering power-off...\n", __func__);
37 63
38 /* hijack UART1 and reset into sane state (19200,8n1) */ 64 /* hijack UART1 and reset into sane state */
39 writel(0x83, UART1_REG(LCR)); 65 writel(0x83, UART1_REG(LCR));
40 writel(divisor & 0xff, UART1_REG(DLL)); 66 writel(divisor & 0xff, UART1_REG(DLL));
41 writel((divisor >> 8) & 0xff, UART1_REG(DLM)); 67 writel((divisor >> 8) & 0xff, UART1_REG(DLM));
@@ -44,16 +70,21 @@ static void qnap_power_off(void)
44 writel(0x00, UART1_REG(FCR)); 70 writel(0x00, UART1_REG(FCR));
45 writel(0x00, UART1_REG(MCR)); 71 writel(0x00, UART1_REG(MCR));
46 72
47 /* send the power-off command 'A' to PIC */ 73 /* send the power-off command to PIC */
48 writel('A', UART1_REG(TX)); 74 writel(cfg->cmd, UART1_REG(TX));
49} 75}
50 76
51static int qnap_power_off_probe(struct platform_device *pdev) 77static int qnap_power_off_probe(struct platform_device *pdev)
52{ 78{
79 struct device_node *np = pdev->dev.of_node;
53 struct resource *res; 80 struct resource *res;
54 struct clk *clk; 81 struct clk *clk;
55 char symname[KSYM_NAME_LEN]; 82 char symname[KSYM_NAME_LEN];
56 83
84 const struct of_device_id *match =
85 of_match_node(qnap_power_off_of_match_table, np);
86 cfg = match->data;
87
57 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 88 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
58 if (!res) { 89 if (!res) {
59 dev_err(&pdev->dev, "Missing resource"); 90 dev_err(&pdev->dev, "Missing resource");
@@ -94,12 +125,6 @@ static int qnap_power_off_remove(struct platform_device *pdev)
94 return 0; 125 return 0;
95} 126}
96 127
97static const struct of_device_id qnap_power_off_of_match_table[] = {
98 { .compatible = "qnap,power-off", },
99 {}
100};
101MODULE_DEVICE_TABLE(of, qnap_power_off_of_match_table);
102
103static struct platform_driver qnap_power_off_driver = { 128static struct platform_driver qnap_power_off_driver = {
104 .probe = qnap_power_off_probe, 129 .probe = qnap_power_off_probe,
105 .remove = qnap_power_off_remove, 130 .remove = qnap_power_off_remove,