From: Colin Foster <colin.foster@in-advantage.com>
To: Lee Jones <lee.jones@linaro.org>
Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-gpio@vger.kernel.org,
Vladimir Oltean <vladimir.oltean@nxp.com>,
Rob Herring <robh+dt@kernel.org>,
Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
Andrew Lunn <andrew@lunn.ch>,
Heiner Kallweit <hkallweit1@gmail.com>,
Russell King <linux@armlinux.org.uk>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Lars Povlsen <lars.povlsen@microchip.com>,
Steen Hegelund <Steen.Hegelund@microchip.com>,
UNGLinuxDriver@microchip.com,
Linus Walleij <linus.walleij@linaro.org>,
Wolfram Sang <wsa@kernel.org>,
Terry Bowman <terry.bowman@amd.com>,
Andy Shevchenko <andy.shevchenko@gmail.com>,
katie.morris@in-advantage.com
Subject: Re: [PATCH v13 net-next 9/9] mfd: ocelot: add support for the vsc7512 chip via spi
Date: Tue, 19 Jul 2022 10:49:03 -0700 [thread overview]
Message-ID: <Ytbuj6qfUj1NOitS@euler> (raw)
In-Reply-To: <YtVrtOHy3lAeKCRH@google.com>
On Mon, Jul 18, 2022 at 03:18:28PM +0100, Lee Jones wrote:
> On Tue, 05 Jul 2022, Colin Foster wrote:
>
> > +MODULE_IMPORT_NS(MFD_OCELOT_SPI);
> > diff --git a/drivers/mfd/ocelot-spi.c b/drivers/mfd/ocelot-spi.c
> > new file mode 100644
> > index 000000000000..0c1c5215c706
> > --- /dev/null
> > +++ b/drivers/mfd/ocelot-spi.c
> > @@ -0,0 +1,317 @@
> > +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> > +/*
> > + * SPI core driver for the Ocelot chip family.
> > + *
> > + * This driver will handle everything necessary to allow for communication over
> > + * SPI to the VSC7511, VSC7512, VSC7513 and VSC7514 chips. The main functions
> > + * are to prepare the chip's SPI interface for a specific bus speed, and a host
> > + * processor's endianness. This will create and distribute regmaps for any
> > + * children.
> > + *
> > + * Copyright 2021, 2022 Innovative Advantage Inc.
> > + *
> > + * Author: Colin Foster <colin.foster@in-advantage.com>
> > + */
> > +
> > +#include <linux/ioport.h>
> > +#include <linux/kconfig.h>
> > +#include <linux/module.h>
> > +#include <linux/regmap.h>
> > +#include <linux/spi/spi.h>
> > +
> > +#include <asm/byteorder.h>
> > +
> > +#include "ocelot.h"
> > +
> > +#define REG_DEV_CPUORG_IF_CTRL 0x0000
> > +#define REG_DEV_CPUORG_IF_CFGSTAT 0x0004
> > +
> > +#define CFGSTAT_IF_NUM_VCORE (0 << 24)
> > +#define CFGSTAT_IF_NUM_VRAP (1 << 24)
> > +#define CFGSTAT_IF_NUM_SI (2 << 24)
> > +#define CFGSTAT_IF_NUM_MIIM (3 << 24)
> > +
> > +#define VSC7512_DEVCPU_ORG_RES_START 0x71000000
> > +#define VSC7512_DEVCPU_ORG_RES_SIZE 0x38
> > +
> > +#define VSC7512_CHIP_REGS_RES_START 0x71070000
> > +#define VSC7512_CHIP_REGS_RES_SIZE 0x14
> > +
> > +struct spi_device;
>
> Why not just #include?
I mis-understood this to mean drivers/mfd/ocelot-spi.c when it meant
drivers/mfd/ocelot.h. Thanks.
https://patchwork.kernel.org/project/netdevbpf/patch/20220701192609.3970317-10-colin.foster@in-advantage.com/#24921057
"""
You missed a lot of forward declarations that are used in this file.
Like
struct spi_device;
"""
> > +static int ocelot_spi_regmap_bus_read(void *context,
> > + const void *reg, size_t reg_size,
> > + void *val, size_t val_size)
> > +{
> > + struct ocelot_ddata *ddata = context;
> > + struct spi_transfer tx, padding, rx;
> > + struct spi_device *spi = ddata->spi;
> > + struct spi_message msg;
> > +
> > + spi = ddata->spi;
>
> Drop this line.
Yes - and actually since I'm removing ddata->spi altogether it'll become
to_spi_device(ddata->dev) (obviously without the double-assignment that
you're pointing out here)
>
> > + spi_message_init(&msg);
> > +
> > + memset(&tx, 0, sizeof(tx));
> > +
> > + tx.tx_buf = reg;
> > + tx.len = reg_size;
> > +
> > + spi_message_add_tail(&tx, &msg);
> > +
> > + if (ddata->spi_padding_bytes) {
> > + memset(&padding, 0, sizeof(padding));
> > +
> > + padding.len = ddata->spi_padding_bytes;
> > + padding.tx_buf = ddata->dummy_buf;
> > + padding.dummy_data = 1;
> > +
> > + spi_message_add_tail(&padding, &msg);
> > + }
> > +
> > + memset(&rx, 0, sizeof(rx));
> > + rx.rx_buf = val;
> > + rx.len = val_size;
> > +
> > + spi_message_add_tail(&rx, &msg);
> > +
> > + return spi_sync(spi, &msg);
> > +}
> > +
> > +static int ocelot_spi_regmap_bus_write(void *context, const void *data,
> > + size_t count)
> > +{
> > + struct ocelot_ddata *ddata = context;
> > + struct spi_device *spi = ddata->spi;
As above, I'm changing to to_spi_device(ddata->dev)
> > +
> > + return spi_write(spi, data, count);
> > +}
> > +
> > +static const struct regmap_bus ocelot_spi_regmap_bus = {
> > + .write = ocelot_spi_regmap_bus_write,
> > + .read = ocelot_spi_regmap_bus_read,
> > +};
> > +
> > +struct regmap *
> > +ocelot_spi_init_regmap(struct device *dev, const struct resource *res)
>
> One line, along with all the others.
>
> > +{
> > + struct ocelot_ddata *ddata = dev_get_drvdata(dev);
> > + struct regmap_config regmap_config;
> > +
> > + memcpy(®map_config, &ocelot_spi_regmap_config,
> > + sizeof(regmap_config));
> > +
> > + regmap_config.name = res->name;
> > + regmap_config.max_register = res->end - res->start;
> > + regmap_config.reg_base = res->start;
> > +
> > + return devm_regmap_init(dev, &ocelot_spi_regmap_bus, ddata,
> > + ®map_config);
> > +}
> > +EXPORT_SYMBOL_NS(ocelot_spi_init_regmap, MFD_OCELOT_SPI);
> > +
> > +static int ocelot_spi_probe(struct spi_device *spi)
> > +{
> > + struct device *dev = &spi->dev;
> > + struct ocelot_ddata *ddata;
> > + struct regmap *r;
> > + int err;
> > +
> > + ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
> > + if (!ddata)
> > + return -ENOMEM;
> > +
> > + ddata->dev = dev;
>
> How are you fetching ddata if you don't already have 'dev'?
I don't think I fully understand this question...
Are you saying ddata doesn't need a dev instance? So instead of:
devm_regmap_init(dev, &bus, ddata, ®map_config);
It could be:
devm_regmap_init(dev, &bus, dev, ®map_config);
In that case, the context into ocelot_spi_regmap_bus_{read,write} would
be dev, instead of ddata.
Then I get ddata from device via:
static int ocelot_spi_regmap_bus_write(void *context,...)
{
struct device *dev = context;
struct ocelot_ddata *ddata = dev_get_drvdata(dev);
struct spi_device *spi = to_spi_device(dev);
/* ddata isn't actually needed for bus_write, just making a point */
...
}
I haven't tested this yet, but I think this is what you're suggesting.
So now I've removed both spi and dev from the ddata struct (as I mention
below). Cool.
>
> > + dev_set_drvdata(dev, ddata);
>
> This should use the spi_* variant.
Agreed.
>
> > + if (spi->max_speed_hz <= 500000) {
> > + ddata->spi_padding_bytes = 0;
> > + } else {
> > + /*
> > + * Calculation taken from the manual for IF_CFGSTAT:IF_CFG.
> > + * Register access time is 1us, so we need to configure and send
> > + * out enough padding bytes between the read request and data
> > + * transmission that lasts at least 1 microsecond.
> > + */
> > + ddata->spi_padding_bytes = 1 +
> > + (spi->max_speed_hz / 1000000 + 2) / 8;
> > +
> > + ddata->dummy_buf = devm_kzalloc(dev, ddata->spi_padding_bytes,
> > + GFP_KERNEL);
> > + if (!ddata->dummy_buf)
> > + return -ENOMEM;
> > + }
> > +
> > + ddata->spi = spi;
>
> If you have 'spi' you definitely do not need 'dev'.
>
> You can derive one from the other.
Good point. As I implied above, I'm dropping "spi" from the ddata struct
and will recover spi from to_spi_device(dev)
That does some nice things like removes "struct spi_device" from
drivers/mfd/ocelot.h
> > + spi->bits_per_word = 8;
> > +
> > + err = spi_setup(spi);
> > + if (err < 0)
> > + return dev_err_probe(&spi->dev, err,
> > + "Error performing SPI setup\n");
> > +
> > + r = ocelot_spi_init_regmap(dev, &vsc7512_dev_cpuorg_resource);
> > + if (IS_ERR(r))
> > + return PTR_ERR(r);
> > +
> > + ddata->cpuorg_regmap = r;
> > +
> > + r = ocelot_spi_init_regmap(dev, &vsc7512_gcb_resource);
> > + if (IS_ERR(r))
> > + return PTR_ERR(r);
> > +
> > + ddata->gcb_regmap = r;
> > +
> > + /*
> > + * The chip must be set up for SPI before it gets initialized and reset.
> > + * This must be done before calling init, and after a chip reset is
> > + * performed.
> > + */
> > + err = ocelot_spi_initialize(dev);
> > + if (err)
> > + return dev_err_probe(dev, err, "Error initializing SPI bus\n");
> > +
> > + err = ocelot_chip_reset(dev);
> > + if (err)
> > + return dev_err_probe(dev, err, "Error resetting device\n");
> > +
> > + /*
> > + * A chip reset will clear the SPI configuration, so it needs to be done
> > + * again before we can access any registers
> > + */
> > + err = ocelot_spi_initialize(dev);
> > + if (err)
> > + return dev_err_probe(dev, err,
> > + "Error initializing SPI bus after reset\n");
> > +
> > + err = ocelot_core_init(dev);
> > + if (err < 0)
> > + return dev_err_probe(dev, err,
> > + "Error initializing Ocelot core\n");
> > +
> > + return 0;
> > +}
> > +
> > +static const struct spi_device_id ocelot_spi_ids[] = {
> > + { "vsc7512", 0 },
> > + { }
> > +};
> > +
> > +static const struct of_device_id ocelot_spi_of_match[] = {
> > + { .compatible = "mscc,vsc7512" },
> > + { }
> > +};
> > +MODULE_DEVICE_TABLE(of, ocelot_spi_of_match);
> > +
> > +static struct spi_driver ocelot_spi_driver = {
> > + .driver = {
> > + .name = "ocelot-soc",
> > + .of_match_table = ocelot_spi_of_match,
> > + },
> > + .id_table = ocelot_spi_ids,
> > + .probe = ocelot_spi_probe,
> > +};
> > +module_spi_driver(ocelot_spi_driver);
> > +
> > +MODULE_DESCRIPTION("SPI Controlled Ocelot Chip Driver");
> > +MODULE_AUTHOR("Colin Foster <colin.foster@in-advantage.com>");
> > +MODULE_LICENSE("Dual MIT/GPL");
> > +MODULE_IMPORT_NS(MFD_OCELOT);
> > diff --git a/drivers/mfd/ocelot.h b/drivers/mfd/ocelot.h
> > new file mode 100644
> > index 000000000000..c86bd6990a3c
> > --- /dev/null
> > +++ b/drivers/mfd/ocelot.h
> > @@ -0,0 +1,34 @@
> > +/* SPDX-License-Identifier: GPL-2.0 OR MIT */
> > +/* Copyright 2021, 2022 Innovative Advantage Inc. */
> > +
> > +#include <asm/byteorder.h>
> > +
> > +struct device;
> > +struct spi_device;
> > +struct regmap;
> > +struct resource;
> > +
> > +struct ocelot_ddata {
> > + struct device *dev;
> > + struct regmap *gcb_regmap;
> > + struct regmap *cpuorg_regmap;
> > + int spi_padding_bytes;
> > + struct spi_device *spi;
> > + void *dummy_buf;
> > +};
>
> This looks like it deserves a doc header.
Will do!
>
> > +int ocelot_chip_reset(struct device *dev);
> > +int ocelot_core_init(struct device *dev);
> > +
> > +/* SPI-specific routines that won't be necessary for other interfaces */
> > +struct regmap *ocelot_spi_init_regmap(struct device *dev,
> > + const struct resource *res);
> > +
> > +#define OCELOT_SPI_BYTE_ORDER_LE 0x00000000
> > +#define OCELOT_SPI_BYTE_ORDER_BE 0x81818181
> > +
> > +#ifdef __LITTLE_ENDIAN
> > +#define OCELOT_SPI_BYTE_ORDER OCELOT_SPI_BYTE_ORDER_LE
> > +#else
> > +#define OCELOT_SPI_BYTE_ORDER OCELOT_SPI_BYTE_ORDER_BE
> > +#endif
>
> --
> Lee Jones [李琼斯]
> Principal Technical Lead - Developer Services
> Linaro.org │ Open source software for Arm SoCs
> Follow Linaro: Facebook | Twitter | Blog
next prev parent reply other threads:[~2022-07-19 17:49 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-05 20:47 [PATCH v13 net-next 0/9] add support for VSC7512 control over SPI Colin Foster
2022-07-05 20:47 ` [PATCH v13 net-next 1/9] mfd: ocelot: add helper to get regmap from a resource Colin Foster
2022-07-09 18:56 ` Vladimir Oltean
2022-07-05 20:47 ` [PATCH v13 net-next 2/9] net: mdio: mscc-miim: add ability to be used in a non-mmio configuration Colin Foster
2022-07-09 18:57 ` Vladimir Oltean
2022-07-11 18:22 ` Jakub Kicinski
2022-07-05 20:47 ` [PATCH v13 net-next 3/9] pinctrl: ocelot: allow pinctrl-ocelot to be loaded as a module Colin Foster
2022-07-05 20:47 ` [PATCH v13 net-next 4/9] pinctrl: ocelot: add ability to be used in a non-mmio configuration Colin Foster
2022-07-09 18:59 ` Vladimir Oltean
2022-07-11 8:20 ` Linus Walleij
2022-07-05 20:47 ` [PATCH v13 net-next 5/9] pinctrl: microchip-sgpio: allow sgpio driver to be used as a module Colin Foster
2022-07-05 20:47 ` [PATCH v13 net-next 6/9] pinctrl: microchip-sgpio: add ability to be used in a non-mmio configuration Colin Foster
2022-07-09 18:58 ` Vladimir Oltean
2022-07-11 8:19 ` Linus Walleij
2022-07-05 20:47 ` [PATCH v13 net-next 7/9] resource: add define macro for register address resources Colin Foster
2022-07-09 19:00 ` Vladimir Oltean
2022-07-05 20:47 ` [PATCH v13 net-next 8/9] dt-bindings: mfd: ocelot: add bindings for VSC7512 Colin Foster
2022-07-11 13:25 ` Vladimir Oltean
2022-07-05 20:47 ` [PATCH v13 net-next 9/9] mfd: ocelot: add support for the vsc7512 chip via spi Colin Foster
2022-07-11 13:27 ` Vladimir Oltean
2022-07-18 14:18 ` Lee Jones
2022-07-18 16:24 ` Colin Foster
2022-07-19 17:49 ` Colin Foster [this message]
2022-07-20 8:19 ` Lee Jones
2022-07-09 3:09 ` [PATCH v13 net-next 0/9] add support for VSC7512 control over SPI Jakub Kicinski
2022-07-11 7:51 ` Lee Jones
2022-07-11 18:21 ` Jakub Kicinski
2022-07-12 2:10 ` Colin Foster
2022-07-12 22:08 ` Vladimir Oltean
2022-07-15 16:57 ` Colin Foster
2022-07-18 8:14 ` Lee Jones
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Ytbuj6qfUj1NOitS@euler \
--to=colin.foster@in-advantage.com \
--cc=Steen.Hegelund@microchip.com \
--cc=UNGLinuxDriver@microchip.com \
--cc=andrew@lunn.ch \
--cc=andy.shevchenko@gmail.com \
--cc=davem@davemloft.net \
--cc=devicetree@vger.kernel.org \
--cc=edumazet@google.com \
--cc=hkallweit1@gmail.com \
--cc=katie.morris@in-advantage.com \
--cc=krzysztof.kozlowski+dt@linaro.org \
--cc=kuba@kernel.org \
--cc=lars.povlsen@microchip.com \
--cc=lee.jones@linaro.org \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=robh+dt@kernel.org \
--cc=terry.bowman@amd.com \
--cc=vladimir.oltean@nxp.com \
--cc=wsa@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).