From patchwork Tue May 3 05:04:26 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gavin Shan X-Patchwork-Id: 617749 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3qzTf061QKz9ssP for ; Tue, 3 May 2016 15:06:00 +1000 (AEST) Received: from ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3qzTf05M0VzDqGD for ; Tue, 3 May 2016 15:06:00 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Received: from e23smtp09.au.ibm.com (e23smtp09.au.ibm.com [202.81.31.142]) (using TLSv1.2 with cipher CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3qzTdk62MYzDq6B for ; Tue, 3 May 2016 15:05:46 +1000 (AEST) Received: from localhost by e23smtp09.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 3 May 2016 15:05:45 +1000 Received: from d23dlp02.au.ibm.com (202.81.31.213) by e23smtp09.au.ibm.com (202.81.31.206) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 3 May 2016 15:05:43 +1000 X-IBM-Helo: d23dlp02.au.ibm.com X-IBM-MailFrom: gwshan@linux.vnet.ibm.com X-IBM-RcptTo: skiboot@lists.ozlabs.org Received: from d23relay10.au.ibm.com (d23relay10.au.ibm.com [9.190.26.77]) by d23dlp02.au.ibm.com (Postfix) with ESMTP id 16C182BB0055 for ; Tue, 3 May 2016 15:05:42 +1000 (EST) Received: from d23av03.au.ibm.com (d23av03.au.ibm.com [9.190.234.97]) by d23relay10.au.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u4355Yf66947188 for ; Tue, 3 May 2016 15:05:42 +1000 Received: from d23av03.au.ibm.com (localhost [127.0.0.1]) by d23av03.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id u43559eS023515 for ; Tue, 3 May 2016 15:05:09 +1000 Received: from ozlabs.au.ibm.com (ozlabs.au.ibm.com [9.192.253.14]) by d23av03.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id u43559DM022657; Tue, 3 May 2016 15:05:09 +1000 Received: from bran.ozlabs.ibm.com (haven.au.ibm.com [9.192.254.114]) by ozlabs.au.ibm.com (Postfix) with ESMTP id F17C7A0282; Tue, 3 May 2016 15:04:44 +1000 (AEST) Received: from gwshan (shangw.ozlabs.ibm.com [10.61.2.199]) by bran.ozlabs.ibm.com (Postfix) with ESMTP id C3B94E3A33; Tue, 3 May 2016 15:04:44 +1000 (AEST) Received: by gwshan (Postfix, from userid 1000) id A2D0794268E; Tue, 3 May 2016 15:04:44 +1000 (AEST) From: Gavin Shan To: skiboot@lists.ozlabs.org Date: Tue, 3 May 2016 15:04:26 +1000 Message-Id: <1462251882-12762-2-git-send-email-gwshan@linux.vnet.ibm.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1462251882-12762-1-git-send-email-gwshan@linux.vnet.ibm.com> References: <1462251882-12762-1-git-send-email-gwshan@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16050305-0033-0000-0000-000005BA645F Subject: [Skiboot] [PATCH v10 01/17] hw/p8-i2c: Allow to set timeout X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" When changing power supply status to PCI slot during bootup, which is done through I2C requests, the interrupt stuff isn't working yet and we have to invoke polling timers proactively at fixed interval. Unfortunately, the I2C master's timeout is usually very short and we will encounter master timeout on the first poll at system bootup time. This allows to override the default short timeout of the specified I2C request, to avoid above problem. Signed-off-by: Gavin Shan Reviewed-by: Stewart Smith --- hw/p8-i2c.c | 25 +++++++++++++++++++++++-- include/i2c.h | 9 +++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/hw/p8-i2c.c b/hw/p8-i2c.c index 593eb88..1dc1e30 100644 --- a/hw/p8-i2c.c +++ b/hw/p8-i2c.c @@ -386,10 +386,15 @@ 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 = 0x0ul; + list_del(&req->link); master->state = state_idle; req->result = ret; @@ -973,8 +978,12 @@ static int p8_i2c_start_request(struct p8_i2c_master *master, now = schedule_timer(&master->poller, master->poll_interval); /* Calculate and start timeout */ - tbytes = req->rw_len + req->offset_bytes + 2; - request->timeout = now + tbytes * master->byte_timeout; + if (request->timeout) { + request->timeout += now; + } else { + tbytes = req->rw_len + req->offset_bytes + 2; + request->timeout = now + tbytes * master->byte_timeout; + } /* Start the timeout */ schedule_timer_at(&master->timeout, request->timeout); @@ -1046,6 +1055,15 @@ 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 inline uint32_t p8_i2c_get_bit_rate_divisor(uint32_t lb_freq, uint32_t bus_speed) { @@ -1093,6 +1111,8 @@ static void p8_i2c_timeout(struct timer *t __unused, void *data, uint64_t now) DBG("I2C: Timeout with request not expired\n"); goto exit; } + + request->timeout = 0ul; port = container_of(req->bus, struct p8_i2c_master_port, bus); /* Allright, we have a request and it has timed out ... */ @@ -1372,6 +1392,7 @@ 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; i2c_add_bus(&port->bus); /* Add OPAL properties to the bus node */ diff --git a/include/i2c.h b/include/i2c.h index dea0644..83c6ec5 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -26,6 +26,8 @@ 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); }; /* @@ -80,6 +82,13 @@ 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); +} + /* P8 implementation details */ extern void p8_i2c_init(void); extern void p8_i2c_interrupt(uint32_t chip_id);