Skip to content

Commit

Permalink
core/i2c: Move the timeout field into i2c_request
Browse files Browse the repository at this point in the history
Currently to set a per-request timeout you need to use
i2c_req_set_timeout() which is a wrapper for a per-bus method that sets the
actual timeout. This design doesn't make a whole lot of sense, so move
the timeout field into the generic i2c_request structure and set the
timeout to be set using that.

Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
  • Loading branch information
oohal authored and stewartsmith committed Sep 18, 2018
1 parent 1317448 commit eb146fa
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 46 deletions.
3 changes: 2 additions & 1 deletion core/i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,12 +208,13 @@ int i2c_request_send(int bus_id, int dev_addr, int read_write,
req->rw_buf = (void*) buf;
req->rw_len = buflen;
req->completion = i2c_sync_request_complete;
req->timeout = timeout;
ud.done = false;
req->user_data = &ud;

for (retries = 0; retries <= MAX_NACK_RETRIES; retries++) {
waited = 0;
i2c_set_req_timeout(req, timeout);

i2c_queue_req(req);

do {
Expand Down
28 changes: 4 additions & 24 deletions hw/p8-i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,12 +378,10 @@ static int p8_i2c_enable_irqs(struct p8_i2c_master *master)
static void p8_i2c_reset_timeout(struct p8_i2c_master *master,
struct i2c_request *req)
{
struct p8_i2c_request *request;
uint64_t now = mftb();

master->last_update = now;
request = container_of(req, struct p8_i2c_request, req);
schedule_timer_at(&master->timeout, now + request->timeout);
schedule_timer_at(&master->timeout, now + req->timeout);
}

static int p8_i2c_prog_watermark(struct p8_i2c_master *master)
Expand Down Expand Up @@ -446,14 +444,10 @@ static int p8_i2c_prog_mode(struct p8_i2c_master_port *port, bool enhanced_mode)
static void p8_i2c_complete_request(struct p8_i2c_master *master,
struct i2c_request *req, int ret)
{
struct p8_i2c_request *request =
container_of(req, struct p8_i2c_request, req);

/* We only complete the current top level request */
assert(req == list_top(&master->req_list, struct i2c_request, link));

cancel_timer_async(&master->timeout);
request->timeout = 0ul;

list_del(&req->link);
master->state = state_idle;
Expand Down Expand Up @@ -830,7 +824,6 @@ static void p8_i2c_status_cmd_completion(struct p8_i2c_master *master,
static void p8_i2c_check_status(struct p8_i2c_master *master)
{
struct p8_i2c_master_port *port;
struct p8_i2c_request *request;
uint64_t status, deadline, now;
struct i2c_request *req;
int rc;
Expand Down Expand Up @@ -872,8 +865,7 @@ static void p8_i2c_check_status(struct p8_i2c_master *master)
port = container_of(req->bus, struct p8_i2c_master_port, bus);
now = mftb();

request = container_of(req, struct p8_i2c_request, req);
deadline = master->last_update + request->timeout;
deadline = master->last_update + req->timeout;

if (status & I2C_STAT_ANY_ERR)
p8_i2c_status_error(port, req, status & I2C_STAT_ANY_ERR, now);
Expand Down Expand Up @@ -1060,8 +1052,6 @@ static int p8_i2c_start_request(struct p8_i2c_master *master,
struct i2c_request *req)
{
struct p8_i2c_master_port *port;
struct p8_i2c_request *request =
container_of(req, struct p8_i2c_request, req);
uint64_t cmd, poll_interval;
int64_t rc;

Expand Down Expand Up @@ -1203,8 +1193,8 @@ static int p8_i2c_start_request(struct p8_i2c_master *master,
schedule_timer(&master->poller, poll_interval);

/* If we don't have a user-set timeout then use the master's default */
if (!request->timeout)
request->timeout = port->byte_timeout;
if (!req->timeout)
req->timeout = port->byte_timeout;

/* Start the timeout */
p8_i2c_reset_timeout(master, req);
Expand Down Expand Up @@ -1315,15 +1305,6 @@ static void p8_i2c_free_request(struct i2c_request *req)
free(request);
}

static void p8_i2c_set_request_timeout(struct i2c_request *req,
uint64_t duration)
{
struct p8_i2c_request *request =
container_of(req, struct p8_i2c_request, req);

request->timeout = msecs_to_tb(duration);
}

static uint64_t p8_i2c_run_request(struct i2c_request *req)
{
struct i2c_bus *bus = req->bus;
Expand Down Expand Up @@ -1653,7 +1634,6 @@ static void p8_i2c_init_one(struct dt_node *i2cm, enum p8_i2c_master_type type)
port->bus.queue_req = p8_i2c_queue_request;
port->bus.alloc_req = p8_i2c_alloc_request;
port->bus.free_req = p8_i2c_free_request;
port->bus.set_req_timeout = p8_i2c_set_request_timeout;
port->bus.run_req = p8_i2c_run_request;

timeout_ms = dt_prop_get_u32_def(i2cm_port, "timeout-ms",
Expand Down
10 changes: 1 addition & 9 deletions include/i2c.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ struct i2c_bus {
int (*queue_req)(struct i2c_request *req);
struct i2c_request *(*alloc_req)(struct i2c_bus *bus);
void (*free_req)(struct i2c_request *req);
void (*set_req_timeout)(struct i2c_request *req,
uint64_t duration);
uint64_t (*run_req)(struct i2c_request *req);
int (*check_quirk)(void *data, struct i2c_request *req, int *rc);
void *check_quirk_data;
Expand Down Expand Up @@ -65,6 +63,7 @@ struct i2c_request {
int rc, struct i2c_request *req);
void *user_data; /* Client data */
int retries;
uint64_t timeout;
};

/* Generic i2c */
Expand All @@ -86,13 +85,6 @@ static inline int i2c_queue_req(struct i2c_request *req)
return req->bus->queue_req(req);
}

static inline void i2c_set_req_timeout(struct i2c_request *req,
uint64_t duration)
{
if (req->bus->set_req_timeout)
req->bus->set_req_timeout(req, duration);
}

static inline uint64_t i2c_run_req(struct i2c_request *req)
{
if (req->bus->run_req)
Expand Down
24 changes: 12 additions & 12 deletions platforms/ibm-fsp/firenze-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ static int64_t firenze_pci_slot_freset(struct pci_slot *slot)
{
struct firenze_pci_slot *plat_slot = slot->data;
uint8_t *pval, presence = 1;
uint32_t timeout;

switch (slot->state) {
case FIRENZE_PCI_SLOT_NORMAL:
Expand Down Expand Up @@ -461,10 +462,9 @@ static int64_t firenze_pci_slot_freset(struct pci_slot *slot)
pci_slot_set_state(slot,
FIRENZE_PCI_SLOT_FRESET_WAIT_RSP);
if (pci_slot_has_flags(slot, PCI_SLOT_FLAG_BOOTUP))
i2c_set_req_timeout(plat_slot->req,
FIRENZE_PCI_I2C_TIMEOUT);
plat_slot->req->timeout = FIRENZE_PCI_I2C_TIMEOUT;
else
i2c_set_req_timeout(plat_slot->req, 0ul);
plat_slot->req->timeout = 0ul;
i2c_queue_req(plat_slot->req);
return pci_slot_set_sm_timeout(slot,
msecs_to_tb(FIRENZE_PCI_SLOT_DELAY));
Expand Down Expand Up @@ -503,10 +503,11 @@ static int64_t firenze_pci_slot_freset(struct pci_slot *slot)
FIRENZE_PCI_SLOT_FRESET_WAIT_RSP);

if (pci_slot_has_flags(slot, PCI_SLOT_FLAG_BOOTUP))
i2c_set_req_timeout(plat_slot->req,
FIRENZE_PCI_I2C_TIMEOUT);
timeout = FIRENZE_PCI_I2C_TIMEOUT;
else
i2c_set_req_timeout(plat_slot->req, 0ul);
timeout = 0ul;
plat_slot->req->timeout = timeout;

i2c_queue_req(plat_slot->req);
return pci_slot_set_sm_timeout(slot,
msecs_to_tb(FIRENZE_PCI_SLOT_DELAY));
Expand All @@ -531,10 +532,9 @@ static int64_t firenze_pci_slot_freset(struct pci_slot *slot)
FIRENZE_PCI_SLOT_FRESET_WAIT_RSP);

if (pci_slot_has_flags(slot, PCI_SLOT_FLAG_BOOTUP))
i2c_set_req_timeout(plat_slot->req,
FIRENZE_PCI_I2C_TIMEOUT);
plat_slot->req->timeout = FIRENZE_PCI_I2C_TIMEOUT;
else
i2c_set_req_timeout(plat_slot->req, 0ul);
plat_slot->req->timeout = 0ul;
i2c_queue_req(plat_slot->req);
return pci_slot_set_sm_timeout(slot,
msecs_to_tb(FIRENZE_PCI_SLOT_DELAY));
Expand Down Expand Up @@ -687,9 +687,9 @@ static int64_t firenze_pci_slot_set_power_state(struct pci_slot *slot,
}

if (pci_slot_has_flags(slot, PCI_SLOT_FLAG_BOOTUP))
i2c_set_req_timeout(plat_slot->req, FIRENZE_PCI_I2C_TIMEOUT);
plat_slot->req->timeout = FIRENZE_PCI_I2C_TIMEOUT;
else
i2c_set_req_timeout(plat_slot->req, 0ul);
plat_slot->req->timeout = 0ul;
i2c_queue_req(plat_slot->req);

return OPAL_ASYNC_COMPLETION;
Expand Down Expand Up @@ -754,7 +754,7 @@ static int64_t firenze_pci_slot_fixup_one_reg(struct pci_slot *slot,
*(uint8_t *)(req->rw_buf) = 0;
}
pci_slot_set_state(slot, FIRENZE_PCI_SLOT_FRESET_WAIT_RSP);
i2c_set_req_timeout(req, FIRENZE_PCI_I2C_TIMEOUT);
req->timeout = FIRENZE_PCI_I2C_TIMEOUT;
i2c_queue_req(plat_slot->req);

while (retries-- > 0) {
Expand Down

0 comments on commit eb146fa

Please sign in to comment.