summaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/xgene-hwmon.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2016-09-09 16:10:45 -0400
committerGuenter Roeck <linux@roeck-us.net>2016-09-09 17:54:53 -0400
commitc7cefce03e691270c0e5e117248e14661e9c9cad (patch)
treeac1c49d2f0d85bbba473455c741fbd47806d20a3 /drivers/hwmon/xgene-hwmon.c
parentc0a4b9ec1b43ebb9d5001e3bf86f58d4ca0ffe18 (diff)
hwmon: (xgene) access mailbox as RAM
The newly added hwmon driver fails to build in an allmodconfig kernel: ERROR: "memblock_is_memory" [drivers/hwmon/xgene-hwmon.ko] undefined! According to comments in the code, the mailbox is a shared memory region, not a set of MMIO registers, so we should use memremap() for mapping it instead of ioremap or acpi_os_ioremap, and pointer dereferences instead of readl/writel. The driver already uses plain kernel pointers, so it's a bit unusual to work with functions that operate on __iomem pointers, and this fixes that part too. I'm using READ_ONCE/WRITE_ONCE here to keep the existing behavior regarding the ordering of the accesses from the CPU, but note that there are no barriers (also unchanged from before). I'm also keeping the endianness behavior, though I'm unsure whether the message data was supposed to be in LE32 format in the first place, it's possible this was meant to be interpreted as a byte stream instead. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Hoan Tran <hotran@apm.com> Tested-by: Hoan Tran <hotran@apm.com> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon/xgene-hwmon.c')
-rw-r--r--drivers/hwmon/xgene-hwmon.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/drivers/hwmon/xgene-hwmon.c b/drivers/hwmon/xgene-hwmon.c
index aa44579a1e5a..9c0dbb8191ad 100644
--- a/drivers/hwmon/xgene-hwmon.c
+++ b/drivers/hwmon/xgene-hwmon.c
@@ -27,6 +27,7 @@
27#include <linux/dma-mapping.h> 27#include <linux/dma-mapping.h>
28#include <linux/hwmon.h> 28#include <linux/hwmon.h>
29#include <linux/hwmon-sysfs.h> 29#include <linux/hwmon-sysfs.h>
30#include <linux/io.h>
30#include <linux/interrupt.h> 31#include <linux/interrupt.h>
31#include <linux/kfifo.h> 32#include <linux/kfifo.h>
32#include <linux/mailbox_controller.h> 33#include <linux/mailbox_controller.h>
@@ -34,7 +35,7 @@
34#include <linux/module.h> 35#include <linux/module.h>
35#include <linux/of.h> 36#include <linux/of.h>
36#include <linux/platform_device.h> 37#include <linux/platform_device.h>
37#include <acpi/acpi_io.h> 38
38#include <acpi/pcc.h> 39#include <acpi/pcc.h>
39 40
40/* SLIMpro message defines */ 41/* SLIMpro message defines */
@@ -126,10 +127,10 @@ static u16 xgene_word_tst_and_clr(u16 *addr, u16 mask)
126{ 127{
127 u16 ret, val; 128 u16 ret, val;
128 129
129 val = readw_relaxed(addr); 130 val = le16_to_cpu(READ_ONCE(*addr));
130 ret = val & mask; 131 ret = val & mask;
131 val &= ~mask; 132 val &= ~mask;
132 writew_relaxed(val, addr); 133 WRITE_ONCE(*addr, cpu_to_le16(val));
133 134
134 return ret; 135 return ret;
135} 136}
@@ -137,7 +138,7 @@ static u16 xgene_word_tst_and_clr(u16 *addr, u16 mask)
137static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg) 138static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg)
138{ 139{
139 struct acpi_pcct_shared_memory *generic_comm_base = ctx->pcc_comm_addr; 140 struct acpi_pcct_shared_memory *generic_comm_base = ctx->pcc_comm_addr;
140 void *ptr = generic_comm_base + 1; 141 u32 *ptr = (void *)(generic_comm_base + 1);
141 int rc, i; 142 int rc, i;
142 u16 val; 143 u16 val;
143 144
@@ -146,21 +147,21 @@ static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg)
146 ctx->resp_pending = true; 147 ctx->resp_pending = true;
147 148
148 /* Write signature for subspace */ 149 /* Write signature for subspace */
149 writel_relaxed(PCC_SIGNATURE_MASK | ctx->mbox_idx, 150 WRITE_ONCE(generic_comm_base->signature,
150 &generic_comm_base->signature); 151 cpu_to_le32(PCC_SIGNATURE_MASK | ctx->mbox_idx));
151 152
152 /* Write to the shared command region */ 153 /* Write to the shared command region */
153 writew_relaxed(MSG_TYPE(msg[0]) | PCCC_GENERATE_DB_INT, 154 WRITE_ONCE(generic_comm_base->command,
154 &generic_comm_base->command); 155 cpu_to_le16(MSG_TYPE(msg[0]) | PCCC_GENERATE_DB_INT));
155 156
156 /* Flip CMD COMPLETE bit */ 157 /* Flip CMD COMPLETE bit */
157 val = readw_relaxed(&generic_comm_base->status); 158 val = le16_to_cpu(READ_ONCE(generic_comm_base->status));
158 val &= ~PCCS_CMD_COMPLETE; 159 val &= ~PCCS_CMD_COMPLETE;
159 writew_relaxed(val, &generic_comm_base->status); 160 WRITE_ONCE(generic_comm_base->status, cpu_to_le16(val));
160 161
161 /* Copy the message to the PCC comm space */ 162 /* Copy the message to the PCC comm space */
162 for (i = 0; i < sizeof(struct slimpro_resp_msg) / 4; i++) 163 for (i = 0; i < sizeof(struct slimpro_resp_msg) / 4; i++)
163 writel_relaxed(msg[i], ptr + i * 4); 164 WRITE_ONCE(ptr[i], cpu_to_le32(msg[i]));
164 165
165 /* Ring the doorbell */ 166 /* Ring the doorbell */
166 rc = mbox_send_message(ctx->mbox_chan, msg); 167 rc = mbox_send_message(ctx->mbox_chan, msg);
@@ -689,9 +690,9 @@ static int xgene_hwmon_probe(struct platform_device *pdev)
689 */ 690 */
690 ctx->comm_base_addr = cppc_ss->base_address; 691 ctx->comm_base_addr = cppc_ss->base_address;
691 if (ctx->comm_base_addr) { 692 if (ctx->comm_base_addr) {
692 ctx->pcc_comm_addr = 693 ctx->pcc_comm_addr = memremap(ctx->comm_base_addr,
693 acpi_os_ioremap(ctx->comm_base_addr, 694 cppc_ss->length,
694 cppc_ss->length); 695 MEMREMAP_WB);
695 } else { 696 } else {
696 dev_err(&pdev->dev, "Failed to get PCC comm region\n"); 697 dev_err(&pdev->dev, "Failed to get PCC comm region\n");
697 rc = -ENODEV; 698 rc = -ENODEV;