Re: [PATCH v8 2/3] mfd: add Gateworks System Controller core driver

2020-04-30 Thread Lee Jones
On Wed, 29 Apr 2020, Tim Harvey wrote:

> On Tue, Apr 28, 2020 at 11:33 PM Lee Jones  wrote:
> >
> > On Tue, 28 Apr 2020, Tim Harvey wrote:
> >
> > > On Tue, Apr 28, 2020 at 2:44 AM Lee Jones  wrote:
> > > >
> > > 
> > > > > +
> > > > > +static int gsc_probe(struct i2c_client *client)
> > > > > +{
> > > > > + struct device *dev = >dev;
> > > > > + struct gsc_dev *gsc;
> > > > > + int ret;
> > > > > + unsigned int reg;
> > > > > +
> > > > > + gsc = devm_kzalloc(dev, sizeof(*gsc), GFP_KERNEL);
> > > > > + if (!gsc)
> > > > > + return -ENOMEM;
> > > > > +
> > > > > + gsc->dev = >dev;
> > > > > + gsc->i2c = client;
> > > > > + i2c_set_clientdata(client, gsc);
> > > > > +
> > > > > + gsc->bus.reg_write = gsc_regmap_regwrite;
> > > > > + gsc->bus.reg_read = gsc_regmap_regread;
> > > >
> > > > Why do you need to store these in ddata?
> > >
> > > Lee,
> > >
> > > Thanks for the review!
> > >
> > > I need the remap_bus* for devm_regmap_init() in the hwmon sub-module 
> > > driver:
> > >
> > > hwmon->regmap = devm_regmap_init(dev, >bus, gsc->i2c_hwmon,
> > > _hwmon_regmap_config);
> > >
> > > Is there something easier I'm missing?
> >
> > This is an odd setup.  I haven't seen one driver registering another
> > driver's Regmap call-backs before, related or otherwise.  Normally the
> > Regmap is setup (initialised) in the parent driver and child drivers
> > just make use of it.  Here it looks like you are registering 2
> > separate Regmaps, but using the same call-backs for both, which seems
> > wrong to me.
> >
> 
> Lee,
> 
> It is perhaps an odd setup. The hwmon sub-device is at a different i2c
> slave address than the other sub-devices. The same callbacks are used
> for reg read/write to take advantage of the retries due to the errata
> resulting in occasional NAK'd register reads.

Then I suggest putting them somewhere shared or exporting them.

Passing pointers to the via ddata sounds a bit batty.

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


Re: [PATCH v8 2/3] mfd: add Gateworks System Controller core driver

2020-04-29 Thread Tim Harvey
On Tue, Apr 28, 2020 at 11:33 PM Lee Jones  wrote:
>
> On Tue, 28 Apr 2020, Tim Harvey wrote:
>
> > On Tue, Apr 28, 2020 at 2:44 AM Lee Jones  wrote:
> > >
> > 
> > > > +
> > > > +static int gsc_probe(struct i2c_client *client)
> > > > +{
> > > > + struct device *dev = >dev;
> > > > + struct gsc_dev *gsc;
> > > > + int ret;
> > > > + unsigned int reg;
> > > > +
> > > > + gsc = devm_kzalloc(dev, sizeof(*gsc), GFP_KERNEL);
> > > > + if (!gsc)
> > > > + return -ENOMEM;
> > > > +
> > > > + gsc->dev = >dev;
> > > > + gsc->i2c = client;
> > > > + i2c_set_clientdata(client, gsc);
> > > > +
> > > > + gsc->bus.reg_write = gsc_regmap_regwrite;
> > > > + gsc->bus.reg_read = gsc_regmap_regread;
> > >
> > > Why do you need to store these in ddata?
> >
> > Lee,
> >
> > Thanks for the review!
> >
> > I need the remap_bus* for devm_regmap_init() in the hwmon sub-module driver:
> >
> > hwmon->regmap = devm_regmap_init(dev, >bus, gsc->i2c_hwmon,
> > _hwmon_regmap_config);
> >
> > Is there something easier I'm missing?
>
> This is an odd setup.  I haven't seen one driver registering another
> driver's Regmap call-backs before, related or otherwise.  Normally the
> Regmap is setup (initialised) in the parent driver and child drivers
> just make use of it.  Here it looks like you are registering 2
> separate Regmaps, but using the same call-backs for both, which seems
> wrong to me.
>

Lee,

It is perhaps an odd setup. The hwmon sub-device is at a different i2c
slave address than the other sub-devices. The same callbacks are used
for reg read/write to take advantage of the retries due to the errata
resulting in occasional NAK'd register reads.

Tim


Re: [PATCH v8 2/3] mfd: add Gateworks System Controller core driver

2020-04-29 Thread Lee Jones
On Tue, 28 Apr 2020, Tim Harvey wrote:

> On Tue, Apr 28, 2020 at 2:44 AM Lee Jones  wrote:
> >
> 
> > > +
> > > +static int gsc_probe(struct i2c_client *client)
> > > +{
> > > + struct device *dev = >dev;
> > > + struct gsc_dev *gsc;
> > > + int ret;
> > > + unsigned int reg;
> > > +
> > > + gsc = devm_kzalloc(dev, sizeof(*gsc), GFP_KERNEL);
> > > + if (!gsc)
> > > + return -ENOMEM;
> > > +
> > > + gsc->dev = >dev;
> > > + gsc->i2c = client;
> > > + i2c_set_clientdata(client, gsc);
> > > +
> > > + gsc->bus.reg_write = gsc_regmap_regwrite;
> > > + gsc->bus.reg_read = gsc_regmap_regread;
> >
> > Why do you need to store these in ddata?
> 
> Lee,
> 
> Thanks for the review!
> 
> I need the remap_bus* for devm_regmap_init() in the hwmon sub-module driver:
> 
> hwmon->regmap = devm_regmap_init(dev, >bus, gsc->i2c_hwmon,
> _hwmon_regmap_config);
> 
> Is there something easier I'm missing?

This is an odd setup.  I haven't seen one driver registering another
driver's Regmap call-backs before, related or otherwise.  Normally the
Regmap is setup (initialised) in the parent driver and child drivers
just make use of it.  Here it looks like you are registering 2
separate Regmaps, but using the same call-backs for both, which seems
wrong to me.

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


Re: [PATCH v8 2/3] mfd: add Gateworks System Controller core driver

2020-04-28 Thread Tim Harvey
On Tue, Apr 28, 2020 at 2:44 AM Lee Jones  wrote:
>

> > +
> > +static int gsc_probe(struct i2c_client *client)
> > +{
> > + struct device *dev = >dev;
> > + struct gsc_dev *gsc;
> > + int ret;
> > + unsigned int reg;
> > +
> > + gsc = devm_kzalloc(dev, sizeof(*gsc), GFP_KERNEL);
> > + if (!gsc)
> > + return -ENOMEM;
> > +
> > + gsc->dev = >dev;
> > + gsc->i2c = client;
> > + i2c_set_clientdata(client, gsc);
> > +
> > + gsc->bus.reg_write = gsc_regmap_regwrite;
> > + gsc->bus.reg_read = gsc_regmap_regread;
>
> Why do you need to store these in ddata?

Lee,

Thanks for the review!

I need the remap_bus* for devm_regmap_init() in the hwmon sub-module driver:

hwmon->regmap = devm_regmap_init(dev, >bus, gsc->i2c_hwmon,
_hwmon_regmap_config);

Is there something easier I'm missing?

Thanks,

Tim


Re: [PATCH v8 2/3] mfd: add Gateworks System Controller core driver

2020-04-28 Thread Lee Jones
On Fri, 27 Mar 2020, Tim Harvey wrote:

> The Gateworks System Controller (GSC) is an I2C slave controller
> implemented with an MSP430 micro-controller whose firmware embeds the
> following features:
>  - I/O expander (16 GPIO's) using PCA955x protocol
>  - Real Time Clock using DS1672 protocol
>  - User EEPROM using AT24 protocol
>  - HWMON using custom protocol
>  - Interrupt controller with tamper detect, user pushbotton
>  - Watchdog controller capable of full board power-cycle
>  - Power Control capable of full board power-cycle
> 
> see http://trac.gateworks.com/wiki/gsc for more details
> 
> Cc: Randy Dunlap 
> Signed-off-by: Tim Harvey 
> ---
> v8:
> - whitespace fixes
> - describe sub-devices in Kconfig
> - add error print for invalid command
> - update copyright
> - use devm_of_platform_populate
> - use probe_new
> - move hwmon's regmap init to hwmon
> 
> v7:
> - remove irq from private data struct
> 
> v6:
> - remove duplicate signature and fix commit log
> 
> v5:
> - simplify powerdown function
> 
> v4:
> - remove hwmon max reg check/define
> - fix powerdown function
> 
> v3:
> - rename gsc->gateworks-gsc
> - remove uncecessary include for linux/mfd/core.h
> - upercase I2C in comments
> - remove i2c debug
> - remove uncecessary comments
> - don't use KBUILD_MODNAME for name
> - remove unnecessary v1/v2/v3 tracking
> - unregister hwmon i2c adapter on remove
> 
> v2:
> - change license comment block style
> - remove COMPILE_TEST (Randy)
> - fixed whitespace issues
> - replaced a printk with dev_err
> ---
>  MAINTAINERS |   8 ++
>  drivers/mfd/Kconfig |  10 ++
>  drivers/mfd/Makefile|   1 +
>  drivers/mfd/gateworks-gsc.c | 288 
> 
>  include/linux/mfd/gsc.h |  73 +++
>  5 files changed, 380 insertions(+)
>  create mode 100644 drivers/mfd/gateworks-gsc.c
>  create mode 100644 include/linux/mfd/gsc.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 56765f5..bb79b60 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -6839,6 +6839,14 @@ F: tools/testing/selftests/futex/
>  F:   tools/perf/bench/futex*
>  F:   Documentation/*futex*
>  
> +GATEWORKS SYSTEM CONTROLLER (GSC) DRIVER
> +M:   Tim Harvey 
> +M:   Robert Jones 
> +S:   Maintained
> +F:   Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml
> +F:   drivers/mfd/gateworks-gsc.c
> +F:   include/linux/mfd/gsc.h
> +
>  GCC PLUGINS
>  M:   Kees Cook 
>  R:   Emese Revfy 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 4209008..d84725a 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -407,6 +407,16 @@ config MFD_EXYNOS_LPASS
> Select this option to enable support for Samsung Exynos Low Power
> Audio Subsystem.
>  
> +config MFD_GATEWORKS_GSC
> + tristate "Gateworks System Controller"
> + depends on (I2C && OF)
> + select MFD_CORE
> + select REGMAP_I2C
> + select REGMAP_IRQ
> + help
> +   Enable support for the Gateworks System Controller found
> +   on Gateworks Single Board Computers.

Please expand on the help section some more.  What is the purpose of
the device?  What sub-devices make up the GSC?  What does this device
driver offer/provide?

>  config MFD_MC13XXX
>   tristate
>   depends on (SPI_MASTER || I2C)
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index aed99f0..c82b442 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -15,6 +15,7 @@ obj-$(CONFIG_MFD_BCM590XX)  += bcm590xx.o
>  obj-$(CONFIG_MFD_BD9571MWV)  += bd9571mwv.o
>  obj-$(CONFIG_MFD_CROS_EC_DEV)+= cros_ec_dev.o
>  obj-$(CONFIG_MFD_EXYNOS_LPASS)   += exynos-lpass.o
> +obj-$(CONFIG_MFD_GATEWORKS_GSC)  += gateworks-gsc.o
>  
>  obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
>  obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o
> diff --git a/drivers/mfd/gateworks-gsc.c b/drivers/mfd/gateworks-gsc.c
> new file mode 100644
> index ..020e1e1
> --- /dev/null
> +++ b/drivers/mfd/gateworks-gsc.c
> @@ -0,0 +1,288 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * The Gateworks System Controller (GSC) is a multi-function
> + * device designed for use in Gateworks Single Board Computers.
> + * The control interface is I2C, with an interrupt. The device supports
> + * system functions such as pushbutton monitoring, multiple ADC's for
> + * voltage and temperature, fan controller, and watchdog monitor.

Looks like good information for the help.

> + * Copyright (C) 2020 Gateworks Corporation
> + */

Nit: '\n' here.

> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +/*
> + * The GSC suffers from an errata where occasionally during
> + * ADC cycles the chip can NAK I2C transactions. To ensure we have reliable
> + * register access we place retries around register access.
> + */
> +#define I2C_RETRIES  3
> +
> +static int gsc_regmap_regwrite(void *context, unsigned int