Received: by 10.223.164.202 with SMTP id h10csp1308682wrb; Fri, 17 Nov 2017 18:41:33 -0800 (PST) X-Google-Smtp-Source: AGs4zMagyVknyL2fsUu8sVfkgcP+hCAHXn/G7qeMxfKS++rK1bM2/jYhyIdhLQyJmP43LUE0OhC3 X-Received: by 10.99.147.3 with SMTP id b3mr7039230pge.352.1510972893387; Fri, 17 Nov 2017 18:41:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1510972893; cv=none; d=google.com; s=arc-20160816; b=V0NEHmYa0dNxCD7OkPWv8BQo8cghRE8YkyOV5W0f86YtKDyh3zUAbL5186pibl38pt wqkSFXc5ZqbpQjP/GUwcypMnCWeVl3UiDTCDcCsv7kHyA40LKuu+MVAWYg0Hu6on/Uoo voYaSxUIvYz3v5j51hPR7sdDS5tBGuMwGm0iByJ6h80wlnKEfg3OicSsxiQfBBov98+X VpjwnXnVSU+FsXfxzkzfMeLXPPH/riMnAzvfkGwyt6aBeO7bAGN7cUiKftlKf5YCUEw6 TRydpQaxRf20+TF8wXUU/2MTEEd9vwyBpIboaE6z7okYe1HCzE8vP8C2V8TQYaa62HQp EM8Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:references:in-reply-to:date :subject:cc:to:from:arc-authentication-results; bh=FnW+1SzN3KbjYeVY+Brll+eNFTzxm8CFcMpoMCDATcM=; b=wv3CZOj4h024GZwrGjsFKF9dnM/WdFZ/DmUwSPhP0fhXI7Xr9g91391JU6yQRbB9Vb w7ytUgOYkjVaJVVXYiR8zEvxQFi3J4sNhcdNBYhAxqJRse7f2G1xTaJxevRutX2V8YNl 3zvVvqT7LrQKdWsJRuHMVqm6xWggK2yXasCzwQLPy1TuseAPQJLb5zLWUpp6hVHfavk6 dtuBOGKVx4FpYfZfxgZgeodWvIc+caQeMl/4OkOQu4F0Sr10DsEloz+swi7aa8Ici1Ra vxvx66WedA0FqrBuE1RcaulZKugmHF/36ERmxsYVUJss9Ntoxe9ulKMUnwvFy39QHsvS +u1Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ibm.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f81si4174651pfj.30.2017.11.17.18.41.19; Fri, 17 Nov 2017 18:41:33 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ibm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1030285AbdKQTfU (ORCPT + 93 others); Fri, 17 Nov 2017 14:35:20 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:35768 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S935633AbdKQTex (ORCPT ); Fri, 17 Nov 2017 14:34:53 -0500 Received: from pps.filterd (m0098417.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id vAHJYcBB143873 for ; Fri, 17 Nov 2017 14:34:53 -0500 Received: from e13.ny.us.ibm.com (e13.ny.us.ibm.com [129.33.205.203]) by mx0a-001b2d01.pphosted.com with ESMTP id 2ea2ta99cp-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Fri, 17 Nov 2017 14:34:52 -0500 Received: from localhost by e13.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 17 Nov 2017 14:34:52 -0500 Received: from b01cxnp22033.gho.pok.ibm.com (9.57.198.23) by e13.ny.us.ibm.com (146.89.104.200) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 17 Nov 2017 14:34:47 -0500 Received: from b01ledav004.gho.pok.ibm.com (b01ledav004.gho.pok.ibm.com [9.57.199.109]) by b01cxnp22033.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id vAHJYlnw37552310; Fri, 17 Nov 2017 19:34:47 GMT Received: from b01ledav004.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 7AAB911204B; Fri, 17 Nov 2017 14:34:11 -0500 (EST) Received: from oc3016140333.ibm.com (unknown [9.41.174.252]) by b01ledav004.gho.pok.ibm.com (Postfix) with ESMTP id A0551112047; Fri, 17 Nov 2017 14:34:10 -0500 (EST) From: Eddie James To: linux-kernel@vger.kernel.org Cc: gregkh@linuxfoundation.org, devicetree@vger.kernel.org, robh+dt@kernel.org, mark.rutland@arm.com, bradleyb@fuzziesquirrel.com, cbostic@linux.vnet.ibm.com, joel@jms.id.au, eajames@linux.vnet.ibm.com, "Edward A. James" Subject: [PATCH v4 4/4] drivers/fsi: sbefifo: Add in-kernel API Date: Fri, 17 Nov 2017 13:34:34 -0600 X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1510947274-7519-1-git-send-email-eajames@linux.vnet.ibm.com> References: <1510947274-7519-1-git-send-email-eajames@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 17111719-0008-0000-0000-000002A2BED3 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00008084; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000240; SDB=6.00947307; UDB=6.00478259; IPR=6.00727599; BA=6.00005698; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00018068; XFM=3.00000015; UTC=2017-11-17 19:34:50 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17111719-0009-0000-0000-000037571D8D Message-Id: <1510947274-7519-5-git-send-email-eajames@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2017-11-17_06:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1711170263 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: "Edward A. James" Refactor the user interface of the SBEFIFO driver to allow for an in-kernel read/write API. Add exported functions for other drivers to call, and add an include file with those functions. Also parse the device tree for child nodes and create child platform devices accordingly. Signed-off-by: Edward A. James --- drivers/fsi/fsi-sbefifo.c | 137 +++++++++++++++++++++++++++++++++++++------- include/linux/fsi-sbefifo.h | 30 ++++++++++ 2 files changed, 146 insertions(+), 21 deletions(-) create mode 100644 include/linux/fsi-sbefifo.h diff --git a/drivers/fsi/fsi-sbefifo.c b/drivers/fsi/fsi-sbefifo.c index 9970e2d..92947b0 100644 --- a/drivers/fsi/fsi-sbefifo.c +++ b/drivers/fsi/fsi-sbefifo.c @@ -15,12 +15,16 @@ #include #include #include +#include #include #include #include #include #include #include +#include +#include +#include #include #include #include @@ -92,6 +96,7 @@ struct sbefifo_client { struct list_head xfrs; struct sbefifo *dev; struct kref kref; + unsigned long f_flags; }; static DEFINE_IDA(sbefifo_ida); @@ -540,6 +545,7 @@ static int sbefifo_open(struct inode *inode, struct file *file) return -ENOMEM; file->private_data = client; + client->f_flags = file->f_flags; return 0; } @@ -579,10 +585,9 @@ static bool sbefifo_read_ready(struct sbefifo *sbefifo, (xfr && test_bit(SBEFIFO_XFR_COMPLETE, &xfr->flags)); } -static ssize_t sbefifo_read(struct file *file, char __user *buf, size_t len, - loff_t *offset) +static ssize_t sbefifo_read_common(struct sbefifo_client *client, + char __user *ubuf, char *kbuf, size_t len) { - struct sbefifo_client *client = file->private_data; struct sbefifo *sbefifo = client->dev; struct sbefifo_xfr *xfr; size_t n; @@ -591,7 +596,7 @@ static ssize_t sbefifo_read(struct file *file, char __user *buf, size_t len, if ((len >> 2) << 2 != len) return -EINVAL; - if ((file->f_flags & O_NONBLOCK) && !sbefifo_xfr_rsp_pending(client)) + if ((client->f_flags & O_NONBLOCK) && !sbefifo_xfr_rsp_pending(client)) return -EAGAIN; sbefifo_get_client(client); @@ -609,9 +614,13 @@ static ssize_t sbefifo_read(struct file *file, char __user *buf, size_t len, n = min_t(size_t, n, len); - if (copy_to_user(buf, READ_ONCE(client->rbuf.rpos), n)) { - ret = -EFAULT; - goto out; + if (ubuf) { + if (copy_to_user(ubuf, READ_ONCE(client->rbuf.rpos), n)) { + ret = -EFAULT; + goto out; + } + } else { + memcpy(kbuf, READ_ONCE(client->rbuf.rpos), n); } if (sbefifo_buf_readnb(&client->rbuf, n)) { @@ -643,6 +652,14 @@ static ssize_t sbefifo_read(struct file *file, char __user *buf, size_t len, return ret; } +static ssize_t sbefifo_read(struct file *file, char __user *buf, size_t len, + loff_t *offset) +{ + struct sbefifo_client *client = file->private_data; + + return sbefifo_read_common(client, buf, NULL, len); +} + static bool sbefifo_write_ready(struct sbefifo *sbefifo, struct sbefifo_xfr *xfr, struct sbefifo_client *client, size_t *n) @@ -655,10 +672,10 @@ static bool sbefifo_write_ready(struct sbefifo *sbefifo, return READ_ONCE(sbefifo->rc) || (next == xfr && *n); } -static ssize_t sbefifo_write(struct file *file, const char __user *buf, - size_t len, loff_t *offset) +static ssize_t sbefifo_write_common(struct sbefifo_client *client, + const char __user *ubuf, const char *kbuf, + size_t len) { - struct sbefifo_client *client = file->private_data; struct sbefifo *sbefifo = client->dev; struct sbefifo_xfr *xfr; ssize_t ret = 0; @@ -676,7 +693,7 @@ static ssize_t sbefifo_write(struct file *file, const char __user *buf, spin_lock_irq(&sbefifo->lock); xfr = sbefifo_next_xfr(sbefifo); /* next xfr to be executed */ - if ((file->f_flags & O_NONBLOCK) && xfr && n < len) { + if ((client->f_flags & O_NONBLOCK) && xfr && n < len) { spin_unlock_irq(&sbefifo->lock); ret = -EAGAIN; goto out; @@ -717,16 +734,22 @@ static ssize_t sbefifo_write(struct file *file, const char __user *buf, n = min_t(size_t, n, len); - if (copy_from_user(READ_ONCE(client->wbuf.wpos), buf, n)) { - set_bit(SBEFIFO_XFR_CANCEL, &xfr->flags); - sbefifo_get(sbefifo); - if (mod_timer(&sbefifo->poll_timer, jiffies)) - sbefifo_put(sbefifo); - ret = -EFAULT; - goto out; - } + if (ubuf) { + if (copy_from_user(READ_ONCE(client->wbuf.wpos), ubuf, + n)) { + set_bit(SBEFIFO_XFR_CANCEL, &xfr->flags); + sbefifo_get(sbefifo); + if (mod_timer(&sbefifo->poll_timer, jiffies)) + sbefifo_put(sbefifo); + ret = -EFAULT; + goto out; + } - buf += n; + ubuf += n; + } else { + memcpy(READ_ONCE(client->wbuf.wpos), kbuf, n); + kbuf += n; + } sbefifo_buf_wrotenb(&client->wbuf, n); len -= n; @@ -750,6 +773,14 @@ static ssize_t sbefifo_write(struct file *file, const char __user *buf, return ret; } +static ssize_t sbefifo_write(struct file *file, const char __user *buf, + size_t len, loff_t *offset) +{ + struct sbefifo_client *client = file->private_data; + + return sbefifo_write_common(client, buf, NULL, len); +} + static int sbefifo_release(struct inode *inode, struct file *file) { struct sbefifo_client *client = file->private_data; @@ -769,6 +800,56 @@ static int sbefifo_release(struct inode *inode, struct file *file) .release = sbefifo_release, }; +struct sbefifo_client *sbefifo_drv_open(struct device *dev, + unsigned long flags) +{ + struct sbefifo_client *client; + struct sbefifo *sbefifo = dev_get_drvdata(dev); + + if (!sbefifo) + return NULL; + + client = sbefifo_new_client(sbefifo); + if (client) + client->f_flags = flags; + + return client; +} +EXPORT_SYMBOL_GPL(sbefifo_drv_open); + +int sbefifo_drv_read(struct sbefifo_client *client, char *buf, size_t len) +{ + return sbefifo_read_common(client, NULL, buf, len); +} +EXPORT_SYMBOL_GPL(sbefifo_drv_read); + +int sbefifo_drv_write(struct sbefifo_client *client, const char *buf, + size_t len) +{ + return sbefifo_write_common(client, NULL, buf, len); +} +EXPORT_SYMBOL_GPL(sbefifo_drv_write); + +void sbefifo_drv_release(struct sbefifo_client *client) +{ + if (!client) + return; + + sbefifo_put_client(client); +} +EXPORT_SYMBOL_GPL(sbefifo_drv_release); + +static int sbefifo_unregister_child(struct device *dev, void *data) +{ + struct platform_device *child = to_platform_device(dev); + + of_device_unregister(child); + if (dev->of_node) + of_node_clear_flag(dev->of_node, OF_POPULATED); + + return 0; +} + static int sbefifo_request_reset(struct sbefifo *sbefifo) { int ret; @@ -803,8 +884,11 @@ static int sbefifo_probe(struct device *dev) { struct fsi_device *fsi_dev = to_fsi_dev(dev); struct sbefifo *sbefifo; + struct device_node *np; + struct platform_device *child; + char child_name[32]; u32 up, down; - int ret; + int ret, child_idx = 0; dev_dbg(dev, "Found sbefifo device\n"); sbefifo = kzalloc(sizeof(*sbefifo), GFP_KERNEL); @@ -855,6 +939,16 @@ static int sbefifo_probe(struct device *dev) return ret; } + /* create platform devs for dts child nodes (occ, etc) */ + for_each_available_child_of_node(dev->of_node, np) { + snprintf(child_name, sizeof(child_name), "%s-dev%d", + sbefifo->name, child_idx++); + child = of_platform_device_create(np, child_name, dev); + if (!child) + dev_warn(dev, "failed to create child %s dev\n", + child_name); + } + dev_set_drvdata(dev, sbefifo); return 0; @@ -880,6 +974,7 @@ static int sbefifo_remove(struct device *dev) wake_up_all(&sbefifo->wait); misc_deregister(&sbefifo->mdev); + device_for_each_child(dev, NULL, sbefifo_unregister_child); ida_simple_remove(&sbefifo_ida, sbefifo->idx); diff --git a/include/linux/fsi-sbefifo.h b/include/linux/fsi-sbefifo.h new file mode 100644 index 0000000..8e55891 --- /dev/null +++ b/include/linux/fsi-sbefifo.h @@ -0,0 +1,30 @@ +/* + * SBEFIFO FSI Client device driver + * + * Copyright (C) IBM Corporation 2017 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERGCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef LINUX_FSI_SBEFIFO_H +#define LINUX_FSI_SBEFIFO_H + +struct device; +struct sbefifo_client; + +extern struct sbefifo_client *sbefifo_drv_open(struct device *dev, + unsigned long flags); +extern int sbefifo_drv_read(struct sbefifo_client *client, char *buf, + size_t len); +extern int sbefifo_drv_write(struct sbefifo_client *client, const char *buf, + size_t len); +extern void sbefifo_drv_release(struct sbefifo_client *client); + +#endif /* LINUX_FSI_SBEFIFO_H */ -- 1.8.3.1 From 1584691148361577585@xxx Tue Nov 21 15:47:27 +0000 2017 X-GM-THRID: 1584691148361577585 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread