[PATCH linux dev-4.10 15/16] fsi: gpio: Update to upstream
Andrew Jeffery
andrew at aj.id.au
Thu Feb 15 23:36:05 AEDT 2018
Patch was generated against v4.14.
Signed-off-by: Andrew Jeffery <andrew at aj.id.au>
---
drivers/fsi/fsi-master-gpio.c | 97 ++++++++++++++++++-------------------------
1 file changed, 40 insertions(+), 57 deletions(-)
diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c
index 485ecb88b115..b53e7a304891 100644
--- a/drivers/fsi/fsi-master-gpio.c
+++ b/drivers/fsi/fsi-master-gpio.c
@@ -2,14 +2,15 @@
* A FSI master controller, using a simple GPIO bit-banging interface
*/
-#include <linux/platform_device.h>
-#include <linux/gpio/consumer.h>
-#include <linux/module.h>
-#include <linux/of.h>
+#include <linux/crc4.h>
#include <linux/delay.h>
-#include <linux/fsi.h>
#include <linux/device.h>
+#include <linux/fsi.h>
+#include <linux/gpio/consumer.h>
#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
@@ -50,11 +51,10 @@
#define FSI_GPIO_MSG_RESPID_SIZE 2
#define FSI_GPIO_PRIME_SLAVE_CLOCKS 100
-static DEFINE_SPINLOCK(fsi_gpio_cmd_lock); /* lock around fsi commands */
-
struct fsi_master_gpio {
struct fsi_master master;
struct device *dev;
+ spinlock_t cmd_lock; /* Lock for commands */
struct gpio_desc *gpio_clk;
struct gpio_desc *gpio_data;
struct gpio_desc *gpio_trans; /* Voltage translator */
@@ -102,14 +102,12 @@ static void sda_out(struct fsi_master_gpio *master, int value)
static void set_sda_input(struct fsi_master_gpio *master)
{
gpiod_direction_input(master->gpio_data);
- if (master->gpio_trans)
- gpiod_set_value(master->gpio_trans, 0);
+ gpiod_set_value(master->gpio_trans, 0);
}
static void set_sda_output(struct fsi_master_gpio *master, int value)
{
- if (master->gpio_trans)
- gpiod_set_value(master->gpio_trans, 1);
+ gpiod_set_value(master->gpio_trans, 1);
gpiod_direction_output(master->gpio_data, value);
}
@@ -130,7 +128,7 @@ static void serial_in(struct fsi_master_gpio *master, struct fsi_gpio_msg *msg,
clock_toggle(master, 1);
in_bit = sda_in(master);
msg->msg <<= 1;
- msg->msg |= ~in_bit & 0x1; /* Data is negative active */
+ msg->msg |= ~in_bit & 0x1; /* Data is active low */
}
msg->bits += num_bits;
@@ -141,7 +139,7 @@ static void serial_out(struct fsi_master_gpio *master,
const struct fsi_gpio_msg *cmd)
{
uint8_t bit;
- uint64_t msg = ~cmd->msg; /* Data is negative active */
+ uint64_t msg = ~cmd->msg; /* Data is active low */
uint64_t sda_mask = 0x1ULL << (cmd->bits - 1);
uint64_t last_bit = ~0;
int next_bit;
@@ -185,16 +183,17 @@ static void msg_push_crc(struct fsi_gpio_msg *msg)
top = msg->bits & 0x3;
/* start bit, and any non-aligned top bits */
- crc = fsi_crc4(0,
- 1 << top | msg->msg >> (msg->bits - top),
- top + 1);
+ crc = crc4(0, 1 << top | msg->msg >> (msg->bits - top), top + 1);
/* aligned bits */
- crc = fsi_crc4(crc, msg->msg, msg->bits - top);
+ crc = crc4(crc, msg->msg, msg->bits - top);
msg_push_bits(msg, crc, 4);
}
+/*
+ * Encode an Absolute Address command
+ */
static void build_abs_ar_command(struct fsi_gpio_msg *cmd,
uint8_t id, uint32_t addr, size_t size, const void *data)
{
@@ -271,7 +270,7 @@ static int read_one_response(struct fsi_master_gpio *master,
uint8_t data_size, struct fsi_gpio_msg *msgp, uint8_t *tagp)
{
struct fsi_gpio_msg msg;
- uint8_t id, tag;
+ uint8_t tag;
uint32_t crc;
int i;
@@ -283,7 +282,7 @@ static int read_one_response(struct fsi_master_gpio *master,
if (msg.msg)
break;
}
- if (i >= FSI_GPIO_MTOE_COUNT) {
+ if (i == FSI_GPIO_MTOE_COUNT) {
dev_dbg(master->dev,
"Master time out waiting for response\n");
fsi_master_gpio_error(master, FSI_GPIO_MTOE);
@@ -296,12 +295,9 @@ static int read_one_response(struct fsi_master_gpio *master,
/* Read slave ID & response tag */
serial_in(master, &msg, 4);
- id = (msg.msg >> FSI_GPIO_MSG_RESPID_SIZE) & 0x3;
tag = msg.msg & 0x3;
- /* if we have an ACK, and we're expecting data, clock the
- * data in too
- */
+ /* If we have an ACK and we're expecting data, clock the data in too */
if (tag == FSI_GPIO_RESP_ACK && data_size)
serial_in(master, &msg, data_size * 8);
@@ -309,8 +305,8 @@ static int read_one_response(struct fsi_master_gpio *master,
serial_in(master, &msg, FSI_GPIO_CRC_SIZE);
/* we have a whole message now; check CRC */
- crc = fsi_crc4(0, 1, 1);
- crc = fsi_crc4(crc, msg.msg, msg.bits);
+ crc = crc4(0, 1, 1);
+ crc = crc4(crc, msg.msg, msg.bits);
if (crc) {
dev_dbg(master->dev, "ERR response CRC\n");
fsi_master_gpio_error(master, FSI_GPIO_CRC_INVAL);
@@ -336,7 +332,7 @@ static int issue_term(struct fsi_master_gpio *master, uint8_t slave)
echo_delay(master);
rc = read_one_response(master, 0, NULL, &tag);
- if (rc) {
+ if (rc < 0) {
dev_err(master->dev,
"TERM failed; lost communication with slave\n");
return -EIO;
@@ -354,6 +350,7 @@ static int poll_for_response(struct fsi_master_gpio *master,
struct fsi_gpio_msg response, cmd;
int busy_count = 0, rc, i;
uint8_t tag;
+ uint8_t *data_byte = data;
retry:
rc = read_one_response(master, size, &response, &tag);
@@ -369,8 +366,7 @@ static int poll_for_response(struct fsi_master_gpio *master,
val &= (1ull << (size * 8)) - 1;
for (i = 0; i < size; i++) {
- ((uint8_t *)data)[size-i-1] =
- val & 0xff;
+ data_byte[size-i-1] = val;
val >>= 8;
}
}
@@ -418,15 +414,15 @@ static int fsi_master_gpio_xfer(struct fsi_master_gpio *master, uint8_t slave,
unsigned long flags;
int rc;
- spin_lock_irqsave(&fsi_gpio_cmd_lock, flags);
+ spin_lock_irqsave(&master->cmd_lock, flags);
if (master->external_mode) {
- spin_unlock_irqrestore(&fsi_gpio_cmd_lock, flags);
+ spin_unlock_irqrestore(&master->cmd_lock, flags);
return -EBUSY;
}
serial_out(master, cmd);
echo_delay(master);
rc = poll_for_response(master, slave, resp_len, resp);
- spin_unlock_irqrestore(&fsi_gpio_cmd_lock, flags);
+ spin_unlock_irqrestore(&master->cmd_lock, flags);
return rc;
}
@@ -470,9 +466,6 @@ static int fsi_master_gpio_term(struct fsi_master *_master,
return fsi_master_gpio_xfer(master, id, &cmd, 0, NULL);
}
-/*
- * Issue a break command on link
- */
static int fsi_master_gpio_break(struct fsi_master *_master, int link)
{
struct fsi_master_gpio *master = to_fsi_master_gpio(_master);
@@ -483,9 +476,9 @@ static int fsi_master_gpio_break(struct fsi_master *_master, int link)
trace_fsi_master_gpio_break(master);
- spin_lock_irqsave(&fsi_gpio_cmd_lock, flags);
+ spin_lock_irqsave(&master->cmd_lock, flags);
if (master->external_mode) {
- spin_unlock_irqrestore(&fsi_gpio_cmd_lock, flags);
+ spin_unlock_irqrestore(&master->cmd_lock, flags);
return -EBUSY;
}
set_sda_output(master, 1);
@@ -496,7 +489,7 @@ static int fsi_master_gpio_break(struct fsi_master *_master, int link)
echo_delay(master);
sda_out(master, 1);
clock_toggle(master, FSI_POST_BREAK_CLOCKS);
- spin_unlock_irqrestore(&fsi_gpio_cmd_lock, flags);
+ spin_unlock_irqrestore(&master->cmd_lock, flags);
/* Wait for logic reset to take effect */
udelay(200);
@@ -506,12 +499,9 @@ static int fsi_master_gpio_break(struct fsi_master *_master, int link)
static void fsi_master_gpio_init(struct fsi_master_gpio *master)
{
- if (master->gpio_mux)
- gpiod_direction_output(master->gpio_mux, 1);
- if (master->gpio_trans)
- gpiod_direction_output(master->gpio_trans, 1);
- if (master->gpio_enable)
- gpiod_direction_output(master->gpio_enable, 1);
+ gpiod_direction_output(master->gpio_mux, 1);
+ gpiod_direction_output(master->gpio_trans, 1);
+ gpiod_direction_output(master->gpio_enable, 1);
gpiod_direction_output(master->gpio_clk, 1);
gpiod_direction_output(master->gpio_data, 1);
@@ -537,12 +527,12 @@ static int fsi_master_gpio_link_enable(struct fsi_master *_master, int link)
if (link != 0)
return -ENODEV;
- spin_lock_irqsave(&fsi_gpio_cmd_lock, flags);
+ spin_lock_irqsave(&master->cmd_lock, flags);
if (!master->external_mode && master->gpio_enable) {
gpiod_set_value(master->gpio_enable, 1);
rc = 0;
}
- spin_unlock_irqrestore(&fsi_gpio_cmd_lock, flags);
+ spin_unlock_irqrestore(&master->cmd_lock, flags);
return rc;
}
@@ -570,10 +560,10 @@ static ssize_t external_mode_store(struct device *dev,
external_mode = !!val;
- spin_lock_irqsave(&fsi_gpio_cmd_lock, flags);
+ spin_lock_irqsave(&master->cmd_lock, flags);
if (external_mode == master->external_mode) {
- spin_unlock_irqrestore(&fsi_gpio_cmd_lock, flags);
+ spin_unlock_irqrestore(&master->cmd_lock, flags);
return count;
}
@@ -582,7 +572,7 @@ static ssize_t external_mode_store(struct device *dev,
fsi_master_gpio_init_external(master);
else
fsi_master_gpio_init(master);
- spin_unlock_irqrestore(&fsi_gpio_cmd_lock, flags);
+ spin_unlock_irqrestore(&master->cmd_lock, flags);
fsi_master_rescan(&master->master);
@@ -592,10 +582,6 @@ static ssize_t external_mode_store(struct device *dev,
static DEVICE_ATTR(external_mode, 0664,
external_mode_show, external_mode_store);
-static void fsi_master_gpio_release(struct device *dev)
-{
-}
-
static int fsi_master_gpio_probe(struct platform_device *pdev)
{
struct fsi_master_gpio *master;
@@ -608,8 +594,6 @@ static int fsi_master_gpio_probe(struct platform_device *pdev)
master->dev = &pdev->dev;
master->master.dev.parent = master->dev;
- master->master.dev.of_node = of_node_get(dev_of_node(master->dev));
- master->master.dev.release = fsi_master_gpio_release;
gpio = devm_gpiod_get(&pdev->dev, "clock", 0);
if (IS_ERR(gpio)) {
@@ -655,6 +639,7 @@ static int fsi_master_gpio_probe(struct platform_device *pdev)
master->master.send_break = fsi_master_gpio_break;
master->master.link_enable = fsi_master_gpio_link_enable;
platform_set_drvdata(pdev, master);
+ spin_lock_init(&master->cmd_lock);
fsi_master_gpio_init(master);
@@ -662,9 +647,7 @@ static int fsi_master_gpio_probe(struct platform_device *pdev)
if (rc)
return rc;
- fsi_master_register(&master->master);
-
- return 0;
+ return fsi_master_register(&master->master);
}
--
2.14.1
More information about the openbmc
mailing list