From patchwork Tue Feb 9 19:47:15 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Helmut Buchsbaum X-Patchwork-Id: 581059 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 7B213140CCA for ; Wed, 10 Feb 2016 06:48:02 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=rv2jH3qA; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932597AbcBITr5 (ORCPT ); Tue, 9 Feb 2016 14:47:57 -0500 Received: from mail-wm0-f68.google.com ([74.125.82.68]:33989 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932353AbcBITri (ORCPT ); Tue, 9 Feb 2016 14:47:38 -0500 Received: by mail-wm0-f68.google.com with SMTP id p63so5382590wmp.1 for ; Tue, 09 Feb 2016 11:47:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=83C3ojMKzQA6jQrZxaYcKwyFhL6gZ9IpedlL+bgCew4=; b=rv2jH3qASwZJGm+efhddf6vo4iRizvf5kC8xP/Xu3RaaUsJWiQMGo3aT59+c7HIzbg aJEA34qVeLlbOVQeVudwyJhQP0hlsdyDq+KGiHLgpAJRFgm8pof0UEhRQ4iTydf4Sl19 +9X4mPiQpFP4PCGpMSE782sDg556eiLQ284CUEXGyWqL1xoGa52oSA6MNFdnVFthZzZv VGw601zclwcOYfmkZFR/ZbllM9rRc2zNgR7DAhwEjaZQ5aLaBdjFj9el3PQGsFqhGhtO VqcdH93hh0uq0o5cTzF4WKdtzAm7hGVwRO55DN2auAkW+PGz+rVZzAwxGjtfKw4Wlmvk au3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=83C3ojMKzQA6jQrZxaYcKwyFhL6gZ9IpedlL+bgCew4=; b=gnsyXyFpC+3MDZkWjrNYBLSLq0FPQZmSHf+aq/HZhd2aKd0WWLM8I4tWMzqp1vq5NM mxuqsmlwh5mG4ETniVnFQNJLy+Y97U6DIYCfY8HjB38kdew/2t4LTP96wYfsjdoKwQHz i1UkBw7miaKRIb4rf8bxFXkv4RRfWvWtApIEiCLu81uvNF9I3nTou8lGobRDHORCmOdh WAlqI8ZEjNsX8nHtygDyF14Of5R9L6cypyFMAkZ+0Iry/adl8Gmc2Rw2z/T0icTeFOsc a+ComZUPPEmFHlIQ+2FVIt58Pen/5yA+73xfgDtmjNZxgvDC65zH3VFgwARqVsP/KbD/ pelg== X-Gm-Message-State: AG10YOTDNt3yk9Q5mwk85aABY8uQ/0bQpYSAFabnko2+YSvRZHi0WrkHjnsbhEdMsvKJaQ== X-Received: by 10.194.61.111 with SMTP id o15mr36267915wjr.104.1455047257334; Tue, 09 Feb 2016 11:47:37 -0800 (PST) Received: from jessie64.at.festo.net ([213.208.155.112]) by smtp.gmail.com with ESMTPSA id r10sm35947476wjz.24.2016.02.09.11.47.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 09 Feb 2016 11:47:36 -0800 (PST) From: Helmut Buchsbaum To: "David S. Miller" , Florian Fainelli , Andrew Lunn , Sergei Shtylyov Cc: netdev@vger.kernel.org, Helmut Buchsbaum Subject: [PATCH v3 3/6] net: phy: spi_ks8995: add support for resetting switch using GPIO Date: Tue, 9 Feb 2016 20:47:15 +0100 Message-Id: <1455047238-111358-4-git-send-email-helmut.buchsbaum@gmail.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1455047238-111358-1-git-send-email-helmut.buchsbaum@gmail.com> References: <1455047238-111358-1-git-send-email-helmut.buchsbaum@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org When using device tree it is no more possible to reset the PHY at board level. Furthermore, doing in the driver allows to power down the switch when it is not used any more. The patch introduces a new optional property "reset-gpios" denoting an appropriate GPIO handle, e.g.: reset-gpios = <&gpio0 46 GPIO_ACTIVE_LOW> Signed-off-by: Helmut Buchsbaum --- drivers/net/phy/spi_ks8995.c | 71 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 9 deletions(-) diff --git a/drivers/net/phy/spi_ks8995.c b/drivers/net/phy/spi_ks8995.c index 2803c8e..04d468f 100644 --- a/drivers/net/phy/spi_ks8995.c +++ b/drivers/net/phy/spi_ks8995.c @@ -18,6 +18,9 @@ #include #include #include +#include +#include +#include #include @@ -120,7 +123,8 @@ static const struct ks8995_chip_params ks8995_chip[] = { }; struct ks8995_pdata { - /* not yet implemented */ + int reset_gpio; + enum of_gpio_flags reset_gpio_flags; }; struct ks8995_switch { @@ -339,6 +343,24 @@ err_out: return err; } +/* ks8995_parse_dt - setup platform data from devicetree + * @ks: pointer to switch instance + * + * Parses supported DT properties and sets up platform data + * accordingly. + */ +static void ks8995_parse_dt(struct ks8995_switch *ks) +{ + struct device_node *np = ks->spi->dev.of_node; + struct ks8995_pdata *pdata = ks->pdata; + + if (!np) + return; + + pdata->reset_gpio = of_get_named_gpio_flags(np, "reset-gpios", 0, + &pdata->reset_gpio_flags); +} + static const struct bin_attribute ks8995_registers_attr = { .attr = { .name = "registers", @@ -352,14 +374,10 @@ static const struct bin_attribute ks8995_registers_attr = { /* ------------------------------------------------------------------------ */ static int ks8995_probe(struct spi_device *spi) { - struct ks8995_switch *ks; - struct ks8995_pdata *pdata; - int err; + struct ks8995_switch *ks; + int err; int variant = spi_get_device_id(spi)->driver_data; - /* Chip description */ - pdata = spi->dev.platform_data; - if (variant >= max_variant) { dev_err(&spi->dev, "bad chip variant %d\n", variant); return -ENODEV; @@ -370,10 +388,42 @@ static int ks8995_probe(struct spi_device *spi) return -ENOMEM; mutex_init(&ks->lock); - ks->pdata = pdata; ks->spi = spi_dev_get(spi); ks->chip = &ks8995_chip[variant]; + if (ks->spi->dev.of_node) { + ks->pdata = devm_kzalloc(&spi->dev, sizeof(*ks->pdata), + GFP_KERNEL); + if (!ks->pdata) + return -ENOMEM; + + ks->pdata->reset_gpio = -1; + + ks8995_parse_dt(ks); + } + + if (!ks->pdata) + ks->pdata = spi->dev.platform_data; + + /* de-assert switch reset */ + if (ks->pdata && gpio_is_valid(ks->pdata->reset_gpio)) { + unsigned long flags; + + flags = (ks->pdata->reset_gpio_flags == OF_GPIO_ACTIVE_LOW ? + GPIOF_ACTIVE_LOW : 0); + + err = devm_gpio_request_one(&spi->dev, + ks->pdata->reset_gpio, + flags, "switch-reset"); + if (err) { + dev_err(&spi->dev, + "failed to get reset-gpios: %d\n", err); + return -EIO; + } + + gpiod_set_value(gpio_to_desc(ks->pdata->reset_gpio), 0); + } + spi_set_drvdata(spi, ks); spi->mode = SPI_MODE_0; @@ -414,11 +464,14 @@ static int ks8995_remove(struct spi_device *spi) sysfs_remove_bin_file(&spi->dev.kobj, &ks->regs_attr); + /* assert reset */ + if (ks->pdata && gpio_is_valid(ks->pdata->reset_gpio)) + gpiod_set_value(gpio_to_desc(ks->pdata->reset_gpio), 1); + return 0; } /* ------------------------------------------------------------------------ */ - static struct spi_driver ks8995_driver = { .driver = { .name = "spi-ks8995",