* Re: [PATCH v2 20/20] cpufreq: Return zero on success in boost sw setting
From: Rafael J. Wysocki @ 2020-05-15 15:58 UTC (permalink / raw)
To: Sergey.Semin, Thomas Bogendoerfer, Rafael J. Wysocki,
Viresh Kumar, Ulf Hansson, Matthias Kaehlcke
Cc: Serge Semin, Alexey Malahov, Paul Burton, Ralf Baechle,
Arnd Bergmann, Rob Herring, linux-mips, devicetree, stable,
Frederic Weisbecker, Ingo Molnar, Yue Hu, linux-pm, linux-kernel
In-Reply-To: <20200506174238.15385-21-Sergey.Semin@baikalelectronics.ru>
On 5/6/2020 7:42 PM, Sergey.Semin@baikalelectronics.ru wrote:
> From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
>
> Recent commit e61a41256edf ("cpufreq: dev_pm_qos_update_request() can
> return 1 on success") fixed a problem when active policies traverse
> was falsely stopped due to invalidly treating the non-zero return value
> from freq_qos_update_request() method as an error. Yes, that function
> can return positive values if the requested update actually took place.
> The current problem is that the returned value is then passed to the
> return cell of the cpufreq_boost_set_sw() (set_boost callback) method.
> This value is then also analyzed for being non-zero, which is also
> treated as having an error. As a result during the boost activation
> we'll get an error returned while having the QOS frequency update
> successfully performed. Fix this by returning a negative value from the
> cpufreq_boost_set_sw() if actual error was encountered and zero
> otherwise treating any positive values as the successful operations
> completion.
>
> Fixes: 18c49926c4bf ("cpufreq: Add QoS requests for userspace constraints")
> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> Cc: Paul Burton <paulburton@kernel.org>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: linux-mips@vger.kernel.org
> Cc: devicetree@vger.kernel.org
> Cc: stable@vger.kernel.org
> ---
> drivers/cpufreq/cpufreq.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index 045f9fe157ce..5870cdca88cf 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -2554,7 +2554,7 @@ static int cpufreq_boost_set_sw(int state)
> break;
> }
>
> - return ret;
> + return ret < 0 ? ret : 0;
> }
>
> int cpufreq_boost_trigger_state(int state)
IMO it is better to update the caller of this function to handle the
positive value possibly returned by it correctly.
Thanks!
^ permalink raw reply
* Re: [PATCHv1 03/19] power: supply: core: add manufacture date properties
From: Emil Velikov @ 2020-05-15 16:01 UTC (permalink / raw)
To: Sebastian Reichel; +Cc: linux-pm, devicetree, linux-kernel, kernel
In-Reply-To: <20200515151408.vbj75fag6ya5g2bq@earth.universe>
On 2020/05/15, Sebastian Reichel wrote:
> Hi,
>
> On Fri, May 15, 2020 at 03:47:32PM +0100, Emil Velikov wrote:
> > On 2020/05/13, Sebastian Reichel wrote:
> > > Some smart batteries store their manufacture date, which is
> > > useful to identify the battery and/or to know about the cell
> > > quality.
> > >
> > Have you considered exposing this as a single file? Say following
> > the ISO8601 format - YYYY-MM-DD.
>
> Yes. My initial implementation was exactly that. The thing is, that
> I suspect some fuel gauge implementations may only expose the year
> or just year + month. I chose 3 files, since receiving 'YYYY-MM'
> instead of full ISO code might be more unexpected than not having
> the DAY file available. But I don't have a strong opinion on this.
>
Fwiw the ISO 8601 allows for YYYY-MM, although you're spot on. Having
the three fields separate makes perfect sense.
Thanks
Emil
^ permalink raw reply
* [PATCHv3 0/2] coresight: etm4x: Add support to skip trace unit power up
From: Sai Prakash Ranjan @ 2020-05-15 16:22 UTC (permalink / raw)
To: Mathieu Poirier, Suzuki K Poulose, Mike Leach, devicetree,
Rob Herring
Cc: Stephen Boyd, Leo Yan, linux-arm-kernel, linux-kernel,
linux-arm-msm, Tingwei Zhang, coresight, Sai Prakash Ranjan
This series adds support to skip powering up of trace unit on systems
with an errata which stops CPU watchdog counter when power up bit is
set (TRCPDCR.PU = 1). Setting this bit is not required on Qualcomm
Technologies Inc. chipsets where this errata exists since the ETMs
are in the same power domain as their respective CPU cores.
Changes since v2:
* Fix checkpatch warning for 80 characters.
Changes since v1:
* Use qcom,skip-power-up for naming as suggested by Mathieu.
* Have check for DT property in initialization as per Mathieu.
* Reword description for property as per Mathieu.
* Split up dt-binding patch as checkpatch complains.
Tingwei Zhang (2):
coresight: etm4x: Add support to skip trace unit power up
dt-bindings: arm: coresight: Add support to skip trace unit power up
.../devicetree/bindings/arm/coresight.txt | 7 +++++
drivers/hwtracing/coresight/coresight-etm4x.c | 27 ++++++++++++-------
drivers/hwtracing/coresight/coresight-etm4x.h | 3 +++
3 files changed, 27 insertions(+), 10 deletions(-)
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply
* [PATCHv3 1/2] coresight: etm4x: Add support to skip trace unit power up
From: Sai Prakash Ranjan @ 2020-05-15 16:22 UTC (permalink / raw)
To: Mathieu Poirier, Suzuki K Poulose, Mike Leach, devicetree,
Rob Herring
Cc: Stephen Boyd, Leo Yan, linux-arm-kernel, linux-kernel,
linux-arm-msm, Tingwei Zhang, coresight, Sai Prakash Ranjan
In-Reply-To: <cover.1589558615.git.saiprakash.ranjan@codeaurora.org>
From: Tingwei Zhang <tingwei@codeaurora.org>
On some Qualcomm Technologies Inc. SoCs like SC7180, there
exists a hardware errata where the APSS (Application Processor
SubSystem)/CPU watchdog counter is stopped when the trace unit
power up ETM register is set (TRCPDCR.PU = 1). Since the ETMs
share the same power domain as that of respective CPU cores,
they are powered on when the CPU core is powered on. So we can
skip powering up of trace unit after checking for this errata
via new property called "qcom,skip-power-up".
Signed-off-by: Tingwei Zhang <tingwei@codeaurora.org>
Co-developed-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Signed-off-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
---
drivers/hwtracing/coresight/coresight-etm4x.c | 27 ++++++++++++-------
drivers/hwtracing/coresight/coresight-etm4x.h | 3 +++
2 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index fb0f5f4f3a91..c16532e1e968 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -196,12 +196,14 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
writel_relaxed(config->vmid_mask0, drvdata->base + TRCVMIDCCTLR0);
writel_relaxed(config->vmid_mask1, drvdata->base + TRCVMIDCCTLR1);
- /*
- * Request to keep the trace unit powered and also
- * emulation of powerdown
- */
- writel_relaxed(readl_relaxed(drvdata->base + TRCPDCR) | TRCPDCR_PU,
- drvdata->base + TRCPDCR);
+ if (!drvdata->skip_power_up) {
+ /*
+ * Request to keep the trace unit powered and also
+ * emulation of powerdown
+ */
+ writel_relaxed(readl_relaxed(drvdata->base + TRCPDCR) |
+ TRCPDCR_PU, drvdata->base + TRCPDCR);
+ }
/* Enable the trace unit */
writel_relaxed(1, drvdata->base + TRCPRGCTLR);
@@ -476,10 +478,12 @@ static void etm4_disable_hw(void *info)
CS_UNLOCK(drvdata->base);
- /* power can be removed from the trace unit now */
- control = readl_relaxed(drvdata->base + TRCPDCR);
- control &= ~TRCPDCR_PU;
- writel_relaxed(control, drvdata->base + TRCPDCR);
+ if (!drvdata->skip_power_up) {
+ /* power can be removed from the trace unit now */
+ control = readl_relaxed(drvdata->base + TRCPDCR);
+ control &= ~TRCPDCR_PU;
+ writel_relaxed(control, drvdata->base + TRCPDCR);
+ }
control = readl_relaxed(drvdata->base + TRCPRGCTLR);
@@ -1429,6 +1433,9 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
return -ENOMEM;
}
+ if (fwnode_property_present(dev_fwnode(dev), "qcom,skip-power-up"))
+ drvdata->skip_power_up = true;
+
/* Validity for the resource is already checked by the AMBA core */
base = devm_ioremap_resource(dev, res);
if (IS_ERR(base))
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
index 4a695bf90582..72c9a55e67df 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -407,6 +407,8 @@ struct etmv4_save_state {
* @config: structure holding configuration parameters.
* @save_state: State to be preserved across power loss
* @state_needs_restore: True when there is context to restore after PM exit
+ * @skip_power_up: Indicates if an implementation can skip powering up
+ * the trace unit.
*/
struct etmv4_drvdata {
void __iomem *base;
@@ -454,6 +456,7 @@ struct etmv4_drvdata {
struct etmv4_config config;
struct etmv4_save_state *save_state;
bool state_needs_restore;
+ bool skip_power_up;
};
/* Address comparator access types */
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related
* [PATCHv3 2/2] dt-bindings: arm: coresight: Add support to skip trace unit power up
From: Sai Prakash Ranjan @ 2020-05-15 16:22 UTC (permalink / raw)
To: Mathieu Poirier, Suzuki K Poulose, Mike Leach, devicetree,
Rob Herring
Cc: Stephen Boyd, Leo Yan, linux-arm-kernel, linux-kernel,
linux-arm-msm, Tingwei Zhang, coresight, Sai Prakash Ranjan
In-Reply-To: <cover.1589558615.git.saiprakash.ranjan@codeaurora.org>
From: Tingwei Zhang <tingwei@codeaurora.org>
Add "qcom,skip-power-up" property to identify systems which can
skip powering up of trace unit since they share the same power
domain as their CPU core. This is required to identify such
systems with hardware errata which stops the CPU watchdog counter
when the power up bit is set (TRCPDCR.PU).
Signed-off-by: Tingwei Zhang <tingwei@codeaurora.org>
Co-developed-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Signed-off-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
---
Documentation/devicetree/bindings/arm/coresight.txt | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt
index 846f6daae71b..e4b2eda0b53b 100644
--- a/Documentation/devicetree/bindings/arm/coresight.txt
+++ b/Documentation/devicetree/bindings/arm/coresight.txt
@@ -108,6 +108,13 @@ its hardware characteristcs.
* arm,cp14: must be present if the system accesses ETM/PTM management
registers via co-processor 14.
+ * qcom,skip-power-up: boolean. Indicates that an implementation can
+ skip powering up the trace unit. TRCPDCR.PU does not have to be set
+ on Qualcomm Technologies Inc. systems since ETMs are in the same power
+ domain as their CPU cores. This property is required to identify such
+ systems with hardware errata where the CPU watchdog counter is stopped
+ when TRCPDCR.PU is set.
+
* Optional property for TMC:
* arm,buffer-size: size of contiguous buffer space for TMC ETR
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related
* Re: [Freedreno] [PATCH] drm/msm/dpu: ensure device suspend happens during PM sleep
From: Doug Anderson @ 2020-05-15 16:37 UTC (permalink / raw)
To: Kalyan Thota, Sean Paul
Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
mkrishn, linux-arm-msm, travitej, LKML, dri-devel, Rob Clark,
nganji, Kristian H. Kristensen, freedreno, Jeykumar Sankaran
In-Reply-To: <32c01e9a5277bdbdbab868eb71688184@codeaurora.org>
Hi,
On Fri, May 15, 2020 at 5:06 AM <kalyan_t@codeaurora.org> wrote:
>
> On 2020-05-14 21:47, Doug Anderson wrote:
> > Hi,
> >
> > On Fri, May 1, 2020 at 6:31 AM Kalyan Thota <kalyan_t@codeaurora.org>
> > wrote:
> >>
> >> "The PM core always increments the runtime usage counter
> >> before calling the ->suspend() callback and decrements it
> >> after calling the ->resume() callback"
> >>
> >> DPU and DSI are managed as runtime devices. When
> >> suspend is triggered, PM core adds a refcount on all the
> >> devices and calls device suspend, since usage count is
> >> already incremented, runtime suspend was not getting called
> >> and it kept the clocks on which resulted in target not
> >> entering into XO shutdown.
> >>
> >> Add changes to force suspend on runtime devices during pm sleep.
> >>
> >> Changes in v1:
> >> - Remove unnecessary checks in the function
> >> _dpu_kms_disable_dpu (Rob Clark).
> >>
> >> Changes in v2:
> >> - Avoid using suspend_late to reset the usagecount
> >> as suspend_late might not be called during suspend
> >> call failures (Doug).
> >>
> >> Changes in v3:
> >> - Use force suspend instead of managing device usage_count
> >> via runtime put and get API's to trigger callbacks (Doug).
> >>
> >> Changes in v4:
> >> - Check the return values of pm_runtime_force_suspend and
> >> pm_runtime_force_resume API's and pass appropriately (Doug).
> >>
> >> Changes in v5:
> >
> > Can you please put the version number properly in your subject? It's
> > really hard to tell one version of your patch from another.
> >
> >
> >> - With v4 patch, test cycle has uncovered issues in device resume.
> >>
> >> On bubs: cmd tx failures were seen as SW is sending panel off
> >> commands when the dsi resources are turned off.
> >>
> >> Upon suspend, DRM driver will issue a NULL composition to the
> >> dpu, followed by turning off all the HW blocks.
> >>
> >> v5 changes will serialize the NULL commit and resource unwinding
> >> by handling them under PM prepare and PM complete phases there by
> >> ensuring that clks are on when panel off commands are being
> >> processed.
> >
> > I'm still most definitely not an expert in how all the DRM pieces all
> > hook up together, but the solution you have in this patch seems wrong
> > to me. As far as I can tell the "prepare" state isn't supposed to be
> > actually doing the suspend work and here that's exactly what you're
> > doing. I think you should find a different solution to ensure
> > ordering is correct.
> >
> > -Doug
> >
>
> Hi,
Quite honestly I'm probably not the right person to be reviewing this
code. I mostly just noticed one of your early patches and it looked
strange to me. Hopefully someone with actual experience in how all
the DRM components work together can actually review and see if this
makes sense. Maybe Sean would know better?
That being said, let me at least look at what you're saying...
> Prepare and Complete are callbacks defined as part of Sleep and Resume
> sequence
>
> Entering PM SUSPEND the phases are : prepare --> suspend -->
> suspend_late --> suspend_noirq.
> While leaving PM SUSPEND the phases are: resume_noirq --> resume_early
> --> resume --> complete.
Sure, it's part of the sequence. It's also documented in pm.h as:
* The principal role of this callback is to prevent new children of
* the device from being registered after it has returned (the driver's
* subsystem and generally the rest of the kernel is supposed to prevent
* new calls to the probe method from being made too once @prepare() has
* succeeded).
It does not feel like that matches your usage of this call.
> The reason to push drm suspend handling to PM prepare phase is that
> parent here will trigger a modeset to turn off the timing and
> subsequently the panel.
> the child devices should not turn of their clocks before parent unwinds
> the composition. Hence they are serialized as per the sequence mentioned
> above.
So the general model in Linux is that children suspend before their
parents, right? So you're saying that, in this case, the parent needs
to act on the child before the child suspends. Is that correct?
Rather than hijacking the prepare/complete, I'd be at least slightly
inclined to move the other driver to turn off its clocks in
suspend_late and to turn them back on in resume_early? That seems to
be what was done in "analogix_dp-rockchip.c" to solve a similar
problem.
> A similar approach is taken by other driver that use drm framework. In
> this driver, the device registers for prepare and complete callbacks to
> handle drm_suspend and drm_resume.
> https://gitlab.freedesktop.org/drm/msm/-/blob/msm-next/drivers/gpu/drm/exynos/exynos_drm_drv.c#L163
OK, if there is another driver in DRM then I guess I won't object too
strongly. Note that when searching for other drivers I noticed this
bit in todo.rst:
* Most drivers (except i915 and nouveau) that use
* drm_atomic_helper_suspend/resume() can probably be converted to use
* drm_mode_config_helper_suspend/resume(). Also there's still open-coded version
* of the atomic suspend/resume code in older atomic modeset drivers.
Does anything get fixed if you do that? It seems like it'd cleanup
your code a bit so maybe worth doing anyway...
---
I guess the last question I'd want resolved is why you have this asymmetry:
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, msm_pm_resume)
Why couldn't you use pm_runtime_force_resume()?
-Doug
^ permalink raw reply
* Re: [PATCH v2 03/19] spi: dw: Clear DMAC register when done or stopped
From: Mark Brown @ 2020-05-15 16:42 UTC (permalink / raw)
To: Serge Semin
Cc: Serge Semin, Georgy Vlasov, Ramil Zaripov, Alexey Malahov,
Thomas Bogendoerfer, Paul Burton, Ralf Baechle, Arnd Bergmann,
Allison Randal, Andy Shevchenko, Gareth Williams, Rob Herring,
linux-mips, devicetree, Thomas Gleixner, Wan Ahmad Zainie,
Jarkko Nikula, linux-spi, linux-kernel
In-Reply-To: <20200515104758.6934-4-Sergey.Semin@baikalelectronics.ru>
[-- Attachment #1: Type: text/plain, Size: 623 bytes --]
On Fri, May 15, 2020 at 01:47:42PM +0300, Serge Semin wrote:
> If DMAC register is left uncleared any further DMAless transfers
> may cause the DMAC hardware handshaking interface getting activated.
This and patch 4 look good as is but they don't apply against for-5.7
due to context changes in -next, unfortunately everyone seems to have
decided that now is the time to start working on this driver which makes
combinations of new work and fixes awkward. I'm going to apply these
for 5.8 but it'd be good if you could send versions based on for-5.7 as
well so I can apply there - I can sort out the conflicts with 5.8.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [RFC] dt-bindings: mailbox: add doorbell support to ARM MHU
From: Jassi Brar @ 2020-05-15 16:46 UTC (permalink / raw)
To: Viresh Kumar
Cc: Arnd Bergmann, Rob Herring, Frank Rowand, Bjorn Andersson,
Vincent Guittot, linux-arm-kernel, Sudeep Holla, Devicetree List,
Linux Kernel Mailing List
In-Reply-To: <0a50f0cf5593baeb628dc8606c523665e5e2ae6c.1589519600.git.viresh.kumar@linaro.org>
On Fri, May 15, 2020 at 12:17 AM Viresh Kumar <viresh.kumar@linaro.org> wrote:
>
> - The hardware gives us the capability to write the register in
> parallel, i.e. we can write 0x800 and 0x400 together without any
> software locks, and so these 32 bits should be considered as separate
> channel even if only one interrupt is issued by the hardware finally.
> This shouldn't be called as virtualization of the channels, as the
> hardware supports this (as clearly mentioned in the TRM) and it takes
> care of handling the signal properly.
>
I'll leave this one open to bikeshed arguments.
> - With serialization, if we use only one channel as today at every
> priority, if there are 5 requests to send signal to the receiver and
> the dvfs request is the last one in queue (which may be called from
> scheduler's hot path with fast switching), it unnecessarily needs to
> wait for the first four transfers to finish due to the software
> locking imposed by the mailbox framework. This adds additional delay,
> maybe of few ms only, which isn't required by the hardware but just by
> the software and few ms can be important in scheduler's hotpath.
>
As I asked you yesterday over the call, it may help if you could share
some numbers to back up the doomsday scenario.
I don't believe mailbox will be a bottleneck, unless you send commands
in a while(1) ... but even then you have to compare against the
virtual-channel implementation. (Not to forget one usually doesn't
need/want the dvfs, power, clock, hotplug all happening at the _same_
time)
Please note, SCMI... lets not pretend it is not about making scmi work
with mhu :) ... itself uses shared-memory transfers and
wait_for_completion_timeout in scmi_do_xfer(). If some platform
_really-really_ faced speed bottlenecks, it would come to want to
exchange 32-bit encoded command/response over the mhu register,
asynchronously and totally bypassing shmem... which is possible only
now.
> - With the current approach it isn't possible to assign different bits
> (or doorbell numbers) to clients from DT and the only way of doing
> that without adding new bindings is by extending #mbox-cells to accept
> a value of 2 as done in this patch.
>
I am afraid you are confused. You can use bit/doorbell-6 by passing
0x40 to mhu as the data to send.
Cheers!
^ permalink raw reply
* Re: [PATCH v2 12/19] spi: dw: Fix Rx-only DMA transfers
From: Mark Brown @ 2020-05-15 16:55 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Serge Semin, Serge Semin, Georgy Vlasov, Ramil Zaripov,
Alexey Malahov, Thomas Bogendoerfer, Paul Burton, Ralf Baechle,
Arnd Bergmann, Allison Randal, Gareth Williams, Rob Herring,
linux-mips, devicetree, Wan Ahmad Zainie, Clement Leger,
Charles Keepax, wuxu.wu, Phil Edworthy, Thomas Gleixner,
linux-spi, linux-kernel
In-Reply-To: <20200515144050.GI1634618@smile.fi.intel.com>
[-- Attachment #1: Type: text/plain, Size: 1101 bytes --]
On Fri, May 15, 2020 at 05:40:50PM +0300, Andy Shevchenko wrote:
> On Fri, May 15, 2020 at 01:47:51PM +0300, Serge Semin wrote:
> > Tx-only DMA transfers are working perfectly fine since in this case
> > the code just ignores the Rx FIFO overflow interrupts. But it turns
> > out the SPI Rx-only transfers are broken since nothing pushing any
> > data to the shift registers, so the Rx FIFO is left empty and the
> > SPI core subsystems just returns a timeout error. Since DW DMAC
> > driver doesn't support something like cyclic write operations of
> > a single byte to a device register, the only way to support the
> > Rx-only SPI transfers is to fake it by using a dummy Tx-buffer.
> > This is what we intend to fix in this commit by setting the
> > SPI_CONTROLLER_MUST_TX flag for DMA-capable platform.
> I'm fine with this if Mark considers this right thing to do.
> So, conditionally
> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Yes, this is good - it's quite a common issue that controllers have and
the main reason the flag exists is to provide a standard fix for it.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH 1/4] dt-bindings: i2c: Document I2C controller binding for MT6797 SoC
From: Wolfram Sang @ 2020-05-15 16:56 UTC (permalink / raw)
To: Matthias Brugger
Cc: Rob Herring, Manivannan Sadhasivam, robh+dt, devicetree,
linux-arm-kernel, linux-mediatek, linux-kernel, adamboardman
In-Reply-To: <aa9ea456-dbee-229c-aea0-4860c6eb7adf@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 811 bytes --]
On Fri, May 15, 2020 at 04:48:28PM +0200, Matthias Brugger wrote:
> Hi Wolfram,
>
> On 26/02/2020 23:23, Rob Herring wrote:
> > On Sat, 22 Feb 2020 21:54:41 +0530, Manivannan Sadhasivam wrote:
> >> I2C controller driver for MT6577 SoC is reused for MT6797 SoC. Hence,
> >> document that in DT binding.
> >>
> >> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> >> ---
> >> Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt | 1 +
> >> 1 file changed, 1 insertion(+)
> >>
> >
> > Acked-by: Rob Herring <robh@kernel.org>
> >
>
> Do you want to take this thorough your tree or are you OK if I take it thorough
> mine?
The I2C list is neither in the CC field, nor is the patch in patchwork.
I suggest you take it.
Acked-by: Wolfram Sang <wsa@kernel.org>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH v3 7/7] clocksource: mips-gic-timer: Set limitations on clocksource/sched-clocks usage
From: Daniel Lezcano @ 2020-05-15 17:10 UTC (permalink / raw)
To: Serge Semin
Cc: Thomas Bogendoerfer, Thomas Gleixner, Serge Semin, Alexey Malahov,
Paul Burton, Ralf Baechle, Alessandro Zummo, Alexandre Belloni,
Arnd Bergmann, Rob Herring, linux-mips, linux-rtc, devicetree,
Vincenzo Frascino, linux-kernel
In-Reply-To: <20200506214107.25956-8-Sergey.Semin@baikalelectronics.ru>
On Thu, May 07, 2020 at 12:41:07AM +0300, Serge Semin wrote:
> Currently neither clocksource nor scheduler clock kernel framework
> support the clocks with variable frequency. Needless to say how many
> problems may cause the sudden base clocks frequency change. In a
> simplest case the system time will either slow down or speed up.
> Since on CM2.5 and earlier MIPS GIC timer is synchronously clocked
> with CPU we must set some limitations on using it for these frameworks
> if CPU frequency may change. First of all it's not safe to have the
> MIPS GIC used for scheduler timings. So we shouldn't proceed with
> the clocks registration in the sched-subsystem. Secondly we must
> significantly decrease the MIPS GIC clocksource rating. This will let
> the system to use it only as a last resort.
>
> Note CM3.x-based systems may also experience the problems with MIPS GIC
> if the CPU-frequency change is activated for the whole CPU cluster
> instead of using the individual CPC core clocks divider.
May be there is no alternative but the code looks a bit hacksih. Isn't possible
to do something with the sched_mark_unstable?
Or just not use the timer at all ?
^ permalink raw reply
* Re: [PATCH 04/17] dt-bindings: mmc: renesas,sdhi: Document r8a7742 support
From: Wolfram Sang @ 2020-05-15 17:17 UTC (permalink / raw)
To: Lad Prabhakar
Cc: Geert Uytterhoeven, Jens Axboe, Rob Herring, Ulf Hansson,
Sergei Shtylyov, David S. Miller, Wim Van Sebroeck, Guenter Roeck,
linux-ide, devicetree, linux-kernel, linux-i2c, linux-mmc, netdev,
linux-renesas-soc, linux-watchdog, Prabhakar
In-Reply-To: <1589555337-5498-5-git-send-email-prabhakar.mahadev-lad.rj@bp.renesas.com>
[-- Attachment #1: Type: text/plain, Size: 397 bytes --]
On Fri, May 15, 2020 at 04:08:44PM +0100, Lad Prabhakar wrote:
> Document SDHI controller for RZ/G1H (R8A7742) SoC, which is compatible
> with R-Car Gen2 SoC family.
>
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
> Reviewed-by: Marian-Cristian Rotariu <marian-cristian.rotariu.rb@bp.renesas.com>
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH 03/17] ARM: dts: r8a7742: Add I2C and IIC support
From: Wolfram Sang @ 2020-05-15 17:10 UTC (permalink / raw)
To: Lad Prabhakar
Cc: Geert Uytterhoeven, Jens Axboe, Rob Herring, Ulf Hansson,
Sergei Shtylyov, David S. Miller, Wim Van Sebroeck, Guenter Roeck,
linux-ide, devicetree, linux-kernel, linux-i2c, linux-mmc, netdev,
linux-renesas-soc, linux-watchdog, Prabhakar
In-Reply-To: <1589555337-5498-4-git-send-email-prabhakar.mahadev-lad.rj@bp.renesas.com>
[-- Attachment #1: Type: text/plain, Size: 680 bytes --]
On Fri, May 15, 2020 at 04:08:43PM +0100, Lad Prabhakar wrote:
> Add the I2C[0-3] and IIC[0-3] devices nodes to the R8A7742 device tree.
>
> Automatic transmission for PMIC control is not available on IIC3 hence
> compatible string "renesas,rcar-gen2-iic" and "renesas,rmobile-iic" is
> not added to iic3 node.
Makes sense.
However, both versions (with and without automatic transmission) are
described with the same "renesas,iic-r8a7742" compatible. Is it possible
to detect the reduced variant at runtime somehow?
My concern is that the peculiarity of this SoC might be forgotten if we
describe it like this and ever add "automatic transmissions" somewhen.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH 05/17] mmc: renesas_sdhi_sys_dmac: Add support for r8a7742 SoC
From: Wolfram Sang @ 2020-05-15 17:17 UTC (permalink / raw)
To: Lad Prabhakar
Cc: Geert Uytterhoeven, Jens Axboe, Rob Herring, Ulf Hansson,
Sergei Shtylyov, David S. Miller, Wim Van Sebroeck, Guenter Roeck,
linux-ide, devicetree, linux-kernel, linux-i2c, linux-mmc, netdev,
linux-renesas-soc, linux-watchdog, Prabhakar
In-Reply-To: <1589555337-5498-6-git-send-email-prabhakar.mahadev-lad.rj@bp.renesas.com>
[-- Attachment #1: Type: text/plain, Size: 1475 bytes --]
On Fri, May 15, 2020 at 04:08:45PM +0100, Lad Prabhakar wrote:
> Add support for r8a7742 SoC. Renesas RZ/G1H (R8A7742) SDHI is identical to
> the R-Car Gen2 family.
>
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
> Reviewed-by: Marian-Cristian Rotariu <marian-cristian.rotariu.rb@bp.renesas.com>
I think we can skip this because of the generic fallback? The other
entries come from a time when we had a different policy IIRC.
> ---
> drivers/mmc/host/renesas_sdhi_sys_dmac.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/mmc/host/renesas_sdhi_sys_dmac.c b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
> index 13ff023..dbfcbc2 100644
> --- a/drivers/mmc/host/renesas_sdhi_sys_dmac.c
> +++ b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
> @@ -75,6 +75,7 @@ static const struct of_device_id renesas_sdhi_sys_dmac_of_match[] = {
> { .compatible = "renesas,sdhi-r7s72100", .data = &of_rz_compatible, },
> { .compatible = "renesas,sdhi-r8a7778", .data = &of_rcar_gen1_compatible, },
> { .compatible = "renesas,sdhi-r8a7779", .data = &of_rcar_gen1_compatible, },
> + { .compatible = "renesas,sdhi-r8a7742", .data = &of_rcar_gen2_compatible, },
> { .compatible = "renesas,sdhi-r8a7743", .data = &of_rcar_gen2_compatible, },
> { .compatible = "renesas,sdhi-r8a7745", .data = &of_rcar_gen2_compatible, },
> { .compatible = "renesas,sdhi-r8a7790", .data = &of_rcar_gen2_compatible, },
> --
> 2.7.4
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH 01/17] dt-bindings: i2c: renesas,i2c: Document r8a7742 support
From: Wolfram Sang @ 2020-05-15 17:12 UTC (permalink / raw)
To: Lad Prabhakar
Cc: Geert Uytterhoeven, Jens Axboe, Rob Herring, Ulf Hansson,
Sergei Shtylyov, David S. Miller, Wim Van Sebroeck, Guenter Roeck,
linux-ide, devicetree, linux-kernel, linux-i2c, linux-mmc, netdev,
linux-renesas-soc, linux-watchdog, Prabhakar
In-Reply-To: <1589555337-5498-2-git-send-email-prabhakar.mahadev-lad.rj@bp.renesas.com>
[-- Attachment #1: Type: text/plain, Size: 514 bytes --]
On Fri, May 15, 2020 at 04:08:41PM +0100, Lad Prabhakar wrote:
> Document i2c controller for RZ/G1H (R8A7742) SoC, which is compatible
> with R-Car Gen2 SoC family.
>
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
> Reviewed-by: Marian-Cristian Rotariu <marian-cristian.rotariu.rb@bp.renesas.com>
Dunno if patches need to be this fine-grained (e.g. group all simple additions
like this in one patch) but still:
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH 02/17] dt-bindings: i2c: renesas,iic: Document r8a7742 support
From: Wolfram Sang @ 2020-05-15 17:14 UTC (permalink / raw)
To: Lad Prabhakar
Cc: Geert Uytterhoeven, Jens Axboe, Rob Herring, Ulf Hansson,
Sergei Shtylyov, David S. Miller, Wim Van Sebroeck, Guenter Roeck,
linux-ide, devicetree, linux-kernel, linux-i2c, linux-mmc, netdev,
linux-renesas-soc, linux-watchdog, Prabhakar
In-Reply-To: <1589555337-5498-3-git-send-email-prabhakar.mahadev-lad.rj@bp.renesas.com>
[-- Attachment #1: Type: text/plain, Size: 396 bytes --]
On Fri, May 15, 2020 at 04:08:42PM +0100, Lad Prabhakar wrote:
> Document IIC controller for RZ/G1H (R8A7742) SoC, which is compatible
> with R-Car Gen2 SoC family.
>
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
> Reviewed-by: Marian-Cristian Rotariu <marian-cristian.rotariu.rb@bp.renesas.com>
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH v2 03/19] spi: dw: Clear DMAC register when done or stopped
From: Serge Semin @ 2020-05-15 17:21 UTC (permalink / raw)
To: Mark Brown
Cc: Serge Semin, Georgy Vlasov, Ramil Zaripov, Alexey Malahov,
Thomas Bogendoerfer, Paul Burton, Ralf Baechle, Arnd Bergmann,
Allison Randal, Andy Shevchenko, Gareth Williams, Rob Herring,
linux-mips, devicetree, Thomas Gleixner, Wan Ahmad Zainie,
Jarkko Nikula, linux-spi, linux-kernel
In-Reply-To: <20200515164203.GJ5066@sirena.org.uk>
On Fri, May 15, 2020 at 05:42:03PM +0100, Mark Brown wrote:
> On Fri, May 15, 2020 at 01:47:42PM +0300, Serge Semin wrote:
> > If DMAC register is left uncleared any further DMAless transfers
> > may cause the DMAC hardware handshaking interface getting activated.
>
> This and patch 4 look good as is but they don't apply against for-5.7
> due to context changes in -next, unfortunately everyone seems to have
> decided that now is the time to start working on this driver which makes
> combinations of new work and fixes awkward. I'm going to apply these
> for 5.8 but it'd be good if you could send versions based on for-5.7 as
> well so I can apply there - I can sort out the conflicts with 5.8.
>
Thanks. I'll send these two patches:
spi: dw: Clear DMAC register when done or stopped
spi: dw: Fix native CS being unset
rebased on top of the for-5.7.
-Sergey
^ permalink raw reply
* [PATCH 1/2] dt-bindings: power: Add BQ27561 compatible
From: Dan Murphy @ 2020-05-15 17:44 UTC (permalink / raw)
To: sre, afd, pali; +Cc: linux-pm, robh, linux-kernel, devicetree, Dan Murphy
Add the Texas Instruments bq27561 battery monitor to the bq27xxx
binding.
Signed-off-by: Dan Murphy <dmurphy@ti.com>
---
This patch has a dependency on the yaml conversion - https://lore.kernel.org/patchwork/patch/1240876/
Documentation/devicetree/bindings/power/supply/bq27xxx.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/power/supply/bq27xxx.yaml b/Documentation/devicetree/bindings/power/supply/bq27xxx.yaml
index 03d1020a2e47..51cb1f685dcf 100644
--- a/Documentation/devicetree/bindings/power/supply/bq27xxx.yaml
+++ b/Documentation/devicetree/bindings/power/supply/bq27xxx.yaml
@@ -49,6 +49,7 @@ properties:
- ti,bq27426
- ti,bq27441
- ti,bq27621
+ - ti,bq27561
reg:
maxItems: 1
--
2.26.2
^ permalink raw reply related
* [PATCH 2/2] power: supply: bq27xxx_battery: Add the BQ27561 Battery monitor
From: Dan Murphy @ 2020-05-15 17:44 UTC (permalink / raw)
To: sre, afd, pali; +Cc: linux-pm, robh, linux-kernel, devicetree, Dan Murphy
In-Reply-To: <20200515174454.21866-1-dmurphy@ti.com>
Add the Texas Instruments BQ27561 battery monitor. The register address
map is laid out the same as compared to other devices within the file.
The battery status register has differing bits to determine if the
battery is full, discharging or dead.
Signed-off-by: Dan Murphy <dmurphy@ti.com>
---
drivers/power/supply/bq27xxx_battery.c | 68 +++++++++++++++++++++-
drivers/power/supply/bq27xxx_battery_i2c.c | 2 +
include/linux/power/bq27xxx_battery.h | 1 +
3 files changed, 70 insertions(+), 1 deletion(-)
diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
index 942c92127b6d..466bbc549799 100644
--- a/drivers/power/supply/bq27xxx_battery.c
+++ b/drivers/power/supply/bq27xxx_battery.c
@@ -43,6 +43,7 @@
* http://www.ti.com/product/bq27411-g1
* http://www.ti.com/product/bq27441-g1
* http://www.ti.com/product/bq27621-g1
+ * https://www.ti.com/lit/gpn/bq27z561
*/
#include <linux/device.h>
@@ -79,6 +80,11 @@
#define BQ27000_FLAG_FC BIT(5)
#define BQ27000_FLAG_CHGS BIT(7) /* Charge state flag */
+/* BQ27561 has different layout for Flags register */
+#define BQ27561_FLAG_FDC BIT(4) /* Battery fully discharged */
+#define BQ27561_FLAG_FC BIT(5) /* Battery fully charged */
+#define BQ27561_FLAG_DIS_CH BIT(6) /* Battery is discharging */
+
/* control register params */
#define BQ27XXX_SEALED 0x20
#define BQ27XXX_SET_CFGUPDATE 0x13
@@ -431,12 +437,32 @@ static u8
[BQ27XXX_REG_DCAP] = 0x3c,
[BQ27XXX_REG_AP] = 0x18,
BQ27XXX_DM_REG_ROWS,
- };
+ },
#define bq27411_regs bq27421_regs
#define bq27425_regs bq27421_regs
#define bq27426_regs bq27421_regs
#define bq27441_regs bq27421_regs
#define bq27621_regs bq27421_regs
+ bq27561_regs[BQ27XXX_REG_MAX] = {
+ [BQ27XXX_REG_CTRL] = 0x00,
+ [BQ27XXX_REG_TEMP] = 0x06,
+ [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
+ [BQ27XXX_REG_VOLT] = 0x08,
+ [BQ27XXX_REG_AI] = 0x14,
+ [BQ27XXX_REG_FLAGS] = 0x0a,
+ [BQ27XXX_REG_TTE] = 0x16,
+ [BQ27XXX_REG_TTF] = 0x18,
+ [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,
+ [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
+ [BQ27XXX_REG_NAC] = INVALID_REG_ADDR,
+ [BQ27XXX_REG_FCC] = 0x12,
+ [BQ27XXX_REG_CYCT] = 0x2a,
+ [BQ27XXX_REG_AE] = 0x22,
+ [BQ27XXX_REG_SOC] = 0x2c,
+ [BQ27XXX_REG_DCAP] = 0x3c,
+ [BQ27XXX_REG_AP] = 0x22,
+ BQ27XXX_DM_REG_ROWS,
+ };
static enum power_supply_property bq27000_props[] = {
POWER_SUPPLY_PROP_STATUS,
@@ -672,6 +698,25 @@ static enum power_supply_property bq27421_props[] = {
#define bq27441_props bq27421_props
#define bq27621_props bq27421_props
+static enum power_supply_property bq27561_props[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_CAPACITY_LEVEL,
+ POWER_SUPPLY_PROP_TEMP,
+ POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
+ POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
+ POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_CHARGE_FULL,
+ POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+ POWER_SUPPLY_PROP_CYCLE_COUNT,
+ POWER_SUPPLY_PROP_POWER_AVG,
+ POWER_SUPPLY_PROP_HEALTH,
+ POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
struct bq27xxx_dm_reg {
u8 subclass_id;
u8 offset;
@@ -767,11 +812,14 @@ static struct bq27xxx_dm_reg bq27621_dm_regs[] = {
#define bq27621_dm_regs 0
#endif
+#define bq27561_dm_regs 0
+
#define BQ27XXX_O_ZERO 0x00000001
#define BQ27XXX_O_OTDC 0x00000002 /* has OTC/OTD overtemperature flags */
#define BQ27XXX_O_UTOT 0x00000004 /* has OT overtemperature flag */
#define BQ27XXX_O_CFGUP 0x00000008
#define BQ27XXX_O_RAM 0x00000010
+#define BQ27561_O_BITS 0x00000020
#define BQ27XXX_DATA(ref, key, opt) { \
.opts = (opt), \
@@ -816,6 +864,7 @@ static struct {
[BQ27426] = BQ27XXX_DATA(bq27426, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM),
[BQ27441] = BQ27XXX_DATA(bq27441, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM),
[BQ27621] = BQ27XXX_DATA(bq27621, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM),
+ [BQ27561] = BQ27XXX_DATA(bq27561, 0 , BQ27561_O_BITS),
};
static DEFINE_MUTEX(bq27xxx_list_lock);
@@ -1551,6 +1600,8 @@ static bool bq27xxx_battery_dead(struct bq27xxx_device_info *di, u16 flags)
{
if (di->opts & BQ27XXX_O_ZERO)
return flags & (BQ27000_FLAG_EDV1 | BQ27000_FLAG_EDVF);
+ else if (di->opts & BQ27561_O_BITS)
+ return flags & BQ27561_FLAG_FDC;
else
return flags & (BQ27XXX_FLAG_SOC1 | BQ27XXX_FLAG_SOCF);
}
@@ -1595,6 +1646,7 @@ void bq27xxx_battery_update(struct bq27xxx_device_info *di)
cache.time_to_empty_avg = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP);
if (di->regs[BQ27XXX_REG_TTF] != INVALID_REG_ADDR)
cache.time_to_full = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF);
+
cache.charge_full = bq27xxx_battery_read_fcc(di);
cache.capacity = bq27xxx_battery_read_soc(di);
if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
@@ -1682,6 +1734,13 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
status = POWER_SUPPLY_STATUS_NOT_CHARGING;
else
status = POWER_SUPPLY_STATUS_DISCHARGING;
+ } else if (di->opts & BQ27561_O_BITS) {
+ if (di->cache.flags & BQ27561_FLAG_FC)
+ status = POWER_SUPPLY_STATUS_FULL;
+ else if (di->cache.flags & BQ27561_FLAG_DIS_CH)
+ status = POWER_SUPPLY_STATUS_DISCHARGING;
+ else
+ status = POWER_SUPPLY_STATUS_CHARGING;
} else {
if (di->cache.flags & BQ27XXX_FLAG_FC)
status = POWER_SUPPLY_STATUS_FULL;
@@ -1710,6 +1769,13 @@ static int bq27xxx_battery_capacity_level(struct bq27xxx_device_info *di,
level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
else
level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
+ } else if (di->opts & BQ27561_O_BITS) {
+ if (di->cache.flags & BQ27561_FLAG_FC)
+ level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
+ else if (di->cache.flags & BQ27561_FLAG_DIS_CH)
+ level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
+ else
+ level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
} else {
if (di->cache.flags & BQ27XXX_FLAG_FC)
level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
diff --git a/drivers/power/supply/bq27xxx_battery_i2c.c b/drivers/power/supply/bq27xxx_battery_i2c.c
index 2677c38a8a42..d0d55e0959d5 100644
--- a/drivers/power/supply/bq27xxx_battery_i2c.c
+++ b/drivers/power/supply/bq27xxx_battery_i2c.c
@@ -253,6 +253,7 @@ static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
{ "bq27426", BQ27426 },
{ "bq27441", BQ27441 },
{ "bq27621", BQ27621 },
+ { "bq27561", BQ27561 },
{},
};
MODULE_DEVICE_TABLE(i2c, bq27xxx_i2c_id_table);
@@ -286,6 +287,7 @@ static const struct of_device_id bq27xxx_battery_i2c_of_match_table[] = {
{ .compatible = "ti,bq27426" },
{ .compatible = "ti,bq27441" },
{ .compatible = "ti,bq27621" },
+ { .compatible = "ti,bq27561" },
{},
};
MODULE_DEVICE_TABLE(of, bq27xxx_battery_i2c_of_match_table);
diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
index 507c5e214c42..4a319950ea22 100644
--- a/include/linux/power/bq27xxx_battery.h
+++ b/include/linux/power/bq27xxx_battery.h
@@ -30,6 +30,7 @@ enum bq27xxx_chip {
BQ27426,
BQ27441,
BQ27621,
+ BQ27561,
};
struct bq27xxx_device_info;
--
2.26.2
^ permalink raw reply related
* [PATCH v11 0/3] Add support for the Gateworks System Controller
From: Tim Harvey @ 2020-05-15 17:57 UTC (permalink / raw)
To: Lee Jones, Jean Delvare, Guenter Roeck, linux-hwmon, Rob Herring,
Frank Rowand, devicetree, linux-kernel, Robert Jones
Cc: Tim Harvey
This series adds support for the Gateworks System Controller used on Gateworks
Laguna, Ventana, and Newport product families.
The GSC is an MSP430 I2C slave controller whose firmware embeds the following
features:
- I/O expander (16 GPIO's emulating a PCA955x)
- EEPROM (enumating AT24)
- RTC (enumating DS1672)
- HWMON
- 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
v11:
- mfd: fix compile error
v10:
- mfd: fix typo and gramatical errors in Kconfig and comment block
- mfd: drop unused i2c device-id table
- mfd: added Lee's ack in s-o-b
v9:
- rebase against 5.7-rc2
- dt-binding: remove allOf: see https://lkml.org/lkml/2020/4/15/1930
- dt-binding: encorporate Lee's review comments for item descriptions
- dt-binding: added Reviewed-by: Rob Herring <robh@kernel.org>
- mfd: cleanup gsc_powerdown() by using BIT(), put_unaligned_le32(), and
avoid unnecessary assignments
- mfd: rename GSC_CTRL_1 SLEEP related defines to simplify
- mfd: add better description and sub-module info to driver description
- mfd: whitespace changes per review
- mfd: remove unused irq_data pointer in ddata
- mfd: remove unnecesary i2c_set_clientdata
- mfd: use devm_i2c_new_dummy_device to avoid need of free's
- mfd: change regsiter definitions to enum
- mfd: export gsc_{read,write} instead of sharing them via ddata
- hwmon: use exported gsc_{read,write}
- hwmon: added Reviewed-by: Guenter Roeck <linux@roeck-us.net>
v8:
- mfd: whitespace fixes
- mfd: describe sub-devices in Kconfig
- mfd: add error print for invalid command
- mfd: update copyright
- mfd: use devm_of_platform_populate
- mfd: use probe_new
- mfd: move hwmon's regmap init to hwmon
- hwmon: move hwmon's regmap init to hwmon
- dt-bindings: add register to fan-controller node name
v7:
- dt-bindings: change divider from mili-ohms to ohms
- dt-bindings: add constraints for voltage divider and offset
- dt-bindings: remove unnecessary ref for offset
- dt-bindings: renamed fan to fan-controller and changed base prop to reg
- mfd: remove irq from private data struct
- hwmon: fix whitespace in Kconfig
- hwmon: remove unnecessary device pointer in private data
- hwmon: change divider from mili-ohms to ohms
- hwmon: move fan base property to reg
v6:
- hwmon: fix size of info field
- hwmon: improve pwm output control documentation
- hwmon: include unit suffix in divider and offset
- hwmon: change subnode name to gsc-adc
- hwmon: change to fan subnode
- hwmon: fix voltage offset
- dt-bindings: fix commit message typo
- dt-bindings: drop invalid description from #interrupt-cells property
- dt-bindings: fix adc pattern property
- dt-bindings: add unit suffix
- dt-bindings: replace hwmon/adc with adc/channel
- dt-bindings: changed adc type to gw,mode
- dt-bindings: add unit suffix and drop ref for voltage-divider
- dt-bindings: add unit suffix for voltage-offset
- dt-bindings: moved fan to its own subnode with base register
v5:
- fix checkpatch issues
- fix dt_binding_check issues
- address feedback from v4
v4:
- hwmon: move to using pwm<n>_auto_point<m>_{pwm,temp} for FAN PWM
- hwmon: remove unncessary resolution/scaling properties for ADCs
- bindings: update to yaml Documentation
- removed watchdog driver
v3:
- removed unnecessary input driver
- added wdt driver
- bindings: encorporated feedback from mailng list
- hwmon:
- encoroprated feedback from mailng list
- added support for raw ADC voltage input used in newer GSC firmware
v2:
- change license comment block style
- remove COMPILE_TEST
- fixed whitespace issues
- replaced a printk with dev_err
- remove DEBUG
- simplify regmap_bulk_read err check
- remove break after returns in switch statement
- fix fan setpoint buffer address
- remove unnecessary parens
- consistently use struct device *dev pointer
- add validation for hwmon child node props
- move parsing of of to own function
- use strlcpy to ensure null termination
- fix static array sizes and removed unnecessary initializers
- dynamically allocate channels
- fix fan input label
- support platform data
Tim Harvey (3):
dt-bindings: mfd: Add Gateworks System Controller bindings
mfd: add Gateworks System Controller core driver
hwmon: add Gateworks System Controller support
.../devicetree/bindings/mfd/gateworks-gsc.yaml | 196 +++++++++++
Documentation/hwmon/gsc-hwmon.rst | 53 +++
Documentation/hwmon/index.rst | 1 +
MAINTAINERS | 11 +
drivers/hwmon/Kconfig | 9 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/gsc-hwmon.c | 390 +++++++++++++++++++++
drivers/mfd/Kconfig | 15 +
drivers/mfd/Makefile | 1 +
drivers/mfd/gateworks-gsc.c | 277 +++++++++++++++
include/linux/mfd/gsc.h | 76 ++++
include/linux/platform_data/gsc_hwmon.h | 44 +++
12 files changed, 1074 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml
create mode 100644 Documentation/hwmon/gsc-hwmon.rst
create mode 100644 drivers/hwmon/gsc-hwmon.c
create mode 100644 drivers/mfd/gateworks-gsc.c
create mode 100644 include/linux/mfd/gsc.h
create mode 100644 include/linux/platform_data/gsc_hwmon.h
--
2.7.4
^ permalink raw reply
* [PATCH v11 1/3] dt-bindings: mfd: Add Gateworks System Controller bindings
From: Tim Harvey @ 2020-05-15 17:57 UTC (permalink / raw)
To: Lee Jones, Jean Delvare, Guenter Roeck, linux-hwmon, Rob Herring,
Frank Rowand, devicetree, linux-kernel, Robert Jones
Cc: Tim Harvey
In-Reply-To: <1589565428-28886-1-git-send-email-tharvey@gateworks.com>
This patch adds documentation of device-tree bindings for the
Gateworks System Controller (GSC).
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
v11:
- no change
v10:
- no change
v9:
- added Reviewed-by: Rob Herring <robh@kernel.org>
- remove allOf: see https://lkml.org/lkml/2020/4/15/1930
- encorporate Lee's review comments for item descriptions
v8:
- add register to fan-controller node name
v7:
- change divider from mili-ohms to ohms
- add constraints for voltage divider and offset
- remove unnecessary ref for offset
- renamed fan to fan-controller and changed base prop to reg
v6:
- fix typo
- drop invalid description from #interrupt-cells property
- fix adc pattern property
- add unit suffix
- replace hwmon/adc with adc/channel
- changed adc type to mode and enum int
- add unit suffix and drop ref for voltage-divider
- moved fan to its own subnode with base register
v5:
- resolve dt_binding_check issues
v4:
- move to using pwm<n>_auto_point<m>_{pwm,temp} for FAN PWM
- remove unncessary resolution/scaling properties for ADCs
- update to yaml
- remove watchdog
v3:
- replaced _ with -
- remove input bindings
- added full description of hwmon
- fix unit address of hwmon child nodes
---
.../devicetree/bindings/mfd/gateworks-gsc.yaml | 196 +++++++++++++++++++++
1 file changed, 196 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml
diff --git a/Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml b/Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml
new file mode 100644
index 00000000..487a844
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml
@@ -0,0 +1,196 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/gateworks-gsc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Gateworks System Controller
+
+description: |
+ The Gateworks System Controller (GSC) is a device present across various
+ Gateworks product families that provides a set of system related features
+ such as the following (refer to the board hardware user manuals to see what
+ features are present)
+ - Watchdog Timer
+ - GPIO
+ - Pushbutton controller
+ - Hardware monitor with ADC's for temperature and voltage rails and
+ fan controller
+
+maintainers:
+ - Tim Harvey <tharvey@gateworks.com>
+ - Robert Jones <rjones@gateworks.com>
+
+properties:
+ $nodename:
+ pattern: "gsc@[0-9a-f]{1,2}"
+ compatible:
+ const: gw,gsc
+
+ reg:
+ description: I2C device address
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ interrupt-controller: true
+
+ "#interrupt-cells":
+ const: 1
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 0
+
+ adc:
+ type: object
+ description: Optional hardware monitoring module
+
+ properties:
+ compatible:
+ const: gw,gsc-adc
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 0
+
+ patternProperties:
+ "^channel@[0-9]+$":
+ type: object
+ description: |
+ Properties for a single ADC which can report cooked values
+ (i.e. temperature sensor based on thermister), raw values
+ (i.e. voltage rail with a pre-scaling resistor divider).
+
+ properties:
+ reg:
+ description: Register of the ADC
+ maxItems: 1
+
+ label:
+ description: Name of the ADC input
+
+ gw,mode:
+ description: |
+ conversion mode:
+ 0 - temperature, in C*10
+ 1 - pre-scaled voltage value
+ 2 - scaled voltage based on an optional resistor divider
+ and optional offset
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1, 2]
+
+ gw,voltage-divider-ohms:
+ description: Values of resistors for divider on raw ADC input
+ maxItems: 2
+ items:
+ minimum: 1000
+ maximum: 1000000
+
+ gw,voltage-offset-microvolt:
+ description: |
+ A positive voltage offset to apply to a raw ADC
+ (i.e. to compensate for a diode drop).
+ minimum: 0
+ maximum: 1000000
+
+ required:
+ - gw,mode
+ - reg
+ - label
+
+ required:
+ - compatible
+ - "#address-cells"
+ - "#size-cells"
+
+patternProperties:
+ "^fan-controller@[0-9a-f]+$":
+ type: object
+ description: Optional fan controller
+
+ properties:
+ compatible:
+ const: gw,gsc-fan
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 0
+
+ reg:
+ description: The fan controller base address
+ maxItems: 1
+
+ required:
+ - compatible
+ - reg
+ - "#address-cells"
+ - "#size-cells"
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - interrupt-controller
+ - "#interrupt-cells"
+ - "#address-cells"
+ - "#size-cells"
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gsc@20 {
+ compatible = "gw,gsc";
+ reg = <0x20>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <4 GPIO_ACTIVE_LOW>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ adc {
+ compatible = "gw,gsc-adc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ channel@0 { /* A0: Board Temperature */
+ reg = <0x00>;
+ label = "temp";
+ gw,mode = <0>;
+ };
+
+ channel@2 { /* A1: Input Voltage (raw ADC) */
+ reg = <0x02>;
+ label = "vdd_vin";
+ gw,mode = <1>;
+ gw,voltage-divider-ohms = <22100 1000>;
+ gw,voltage-offset-microvolt = <800000>;
+ };
+
+ channel@b { /* A2: Battery voltage */
+ reg = <0x0b>;
+ label = "vdd_bat";
+ gw,mode = <1>;
+ };
+ };
+
+ fan-controller@2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "gw,gsc-fan";
+ reg = <0x2c>;
+ };
+ };
+ };
--
2.7.4
^ permalink raw reply related
* [PATCH 3/3] hwmon: add Gateworks System Controller support
From: Tim Harvey @ 2020-05-15 17:57 UTC (permalink / raw)
To: Lee Jones, Jean Delvare, Guenter Roeck, linux-hwmon, Rob Herring,
Frank Rowand, devicetree, linux-kernel, Robert Jones
Cc: Tim Harvey
In-Reply-To: <1589565428-28886-1-git-send-email-tharvey@gateworks.com>
The Gateworks System Controller has a hwmon sub-component that exposes
up to 16 ADC's, some of which are temperature sensors, others which are
voltage inputs. The ADC configuration (register mapping and name) is
configured via device-tree and varies board to board.
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
---
v11:
- no change
v10:
- no change
v9:
- use exported gsc_{read,write}
- added Reviewed-by: Guenter Roeck <linux@roeck-us.net>
v8:
- move regmap init to hwmon
v7:
- fix whitespace in Kconfig
- remove unnecessary device pointer in private data
- change divider from mili-ohms to ohms
- move fan base property to reg
v6:
- fix size of info field
- improve pwm output control documentation
- include unit suffix in divider and offset
- change subnode name to gsc-adc
- change to fan subnode
- fix voltage offset
v5:
- fix various checkpatch issues
- correct gsc-hwmon.rst in MAINTAINERS
- encorporate Gunter's feedback:
- switch to SENSOR_DEVICE_ATTR_{RW,RO}
- use tmp value to avoid excessive pointer deference
- simplify shift operation
- scale voffset once
- simplify is_visible function
- remove empty line at end of file
v4:
- adjust for uV offset from device-tree
- remove unnecessary optional write function
- remove register range check
- change dev_err prints to use gsc dev
- hard-code resolution/scaling for raw adcs
- describe units of ADC resolution
- move to using pwm<n>_auto_point<m>_{pwm,temp} for FAN PWM
- ensure space before/after operators
- remove unnecessary parens
- remove more debugging
- add default case and comment for type_voltage
- remove unnecessary index bounds checks for channel
- remove unnecessary clearing of struct fields
- added Documentation/hwmon/gsc-hwmon.rst
v3:
- add voltage_raw input type and supporting fields
- add channel validation to is_visible function
- remove unnecessary channel validation from read/write functions
v2:
- change license comment style
- remove DEBUG
- simplify regmap_bulk_read err check
- remove break after returns in switch statement
- fix fan setpoint buffer address
- remove unnecessary parens
- consistently use struct device *dev pointer
- change license/comment block
- add validation for hwmon child node props
- move parsing of of to own function
- use strlcpy to ensure null termination
- fix static array sizes and removed unnecessary initializers
- dynamically allocate channels
- fix fan input label
- support platform data
- fixed whitespace issues
---
Documentation/hwmon/gsc-hwmon.rst | 53 +++++
Documentation/hwmon/index.rst | 1 +
MAINTAINERS | 3 +
drivers/hwmon/Kconfig | 9 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/gsc-hwmon.c | 390 ++++++++++++++++++++++++++++++++
include/linux/platform_data/gsc_hwmon.h | 44 ++++
7 files changed, 501 insertions(+)
create mode 100644 Documentation/hwmon/gsc-hwmon.rst
create mode 100644 drivers/hwmon/gsc-hwmon.c
create mode 100644 include/linux/platform_data/gsc_hwmon.h
diff --git a/Documentation/hwmon/gsc-hwmon.rst b/Documentation/hwmon/gsc-hwmon.rst
new file mode 100644
index 00000000..ffac392
--- /dev/null
+++ b/Documentation/hwmon/gsc-hwmon.rst
@@ -0,0 +1,53 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Kernel driver gsc-hwmon
+=======================
+
+Supported chips: Gateworks GSC
+Datasheet: http://trac.gateworks.com/wiki/gsc
+Author: Tim Harvey <tharvey@gateworks.com>
+
+Description:
+------------
+
+This driver supports hardware monitoring for the temperature sensor,
+various ADC's connected to the GSC, and optional FAN controller available
+on some boards.
+
+
+Voltage Monitoring
+------------------
+
+The voltage inputs are scaled either internally or by the driver depending
+on the GSC version and firmware. The values returned by the driver do not need
+further scaling. The voltage input labels provide the voltage rail name:
+
+inX_input Measured voltage (mV).
+inX_label Name of voltage rail.
+
+
+Temperature Monitoring
+----------------------
+
+Temperatures are measured with 12-bit or 10-bit resolution and are scaled
+either internally or by the driver depending on the GSC version and firmware.
+The values returned by the driver reflect millidegree Celcius:
+
+tempX_input Measured temperature.
+tempX_label Name of temperature input.
+
+
+PWM Output Control
+------------------
+
+The GSC features 1 PWM output that operates in automatic mode where the
+PWM value will be scalled depending on 6 temperature boundaries.
+The tempeature boundaries are read-write and in millidegree Celcius and the
+read-only PWM values range from 0 (off) to 255 (full speed).
+Fan speed will be set to minimum (off) when the temperature sensor reads
+less than pwm1_auto_point1_temp and maximum when the temperature sensor
+equals or exceeds pwm1_auto_point6_temp.
+
+pwm1_auto_point[1-6]_pwm PWM value.
+pwm1_auto_point[1-6]_temp Temperature boundary.
+
diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index 8ef62fd..1c02aa6 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -60,6 +60,7 @@ Hardware Monitoring Kernel Drivers
ftsteutates
g760a
g762
+ gsc-hwmon
gl518sm
hih6130
ibmaem
diff --git a/MAINTAINERS b/MAINTAINERS
index c78a014..7f8ece8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7035,6 +7035,9 @@ S: Maintained
F: Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml
F: drivers/mfd/gateworks-gsc.c
F: include/linux/mfd/gsc.h
+F: Documentation/hwmon/gsc-hwmon.rst
+F: drivers/hwmon/gsc-hwmon.c
+F: include/linux/platform_data/gsc_hwmon.h
GASKET DRIVER FRAMEWORK
M: Rob Springer <rspringer@google.com>
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 4c62f90..5549906 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -523,6 +523,15 @@ config SENSORS_F75375S
This driver can also be built as a module. If so, the module
will be called f75375s.
+config SENSORS_GSC
+ tristate "Gateworks System Controller ADC"
+ depends on MFD_GATEWORKS_GSC
+ help
+ Support for the Gateworks System Controller A/D converters.
+
+ To compile this driver as a module, choose M here:
+ the module will be called gsc-hwmon.
+
config SENSORS_MC13783_ADC
tristate "Freescale MC13783/MC13892 ADC"
depends on MFD_MC13XXX
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index b0b9c8e..a6564d0 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -74,6 +74,7 @@ obj-$(CONFIG_SENSORS_G760A) += g760a.o
obj-$(CONFIG_SENSORS_G762) += g762.o
obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o
obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o
+obj-$(CONFIG_SENSORS_GSC) += gsc-hwmon.o
obj-$(CONFIG_SENSORS_GPIO_FAN) += gpio-fan.o
obj-$(CONFIG_SENSORS_HIH6130) += hih6130.o
obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o
diff --git a/drivers/hwmon/gsc-hwmon.c b/drivers/hwmon/gsc-hwmon.c
new file mode 100644
index 00000000..2137bc6
--- /dev/null
+++ b/drivers/hwmon/gsc-hwmon.c
@@ -0,0 +1,390 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for Gateworks System Controller Hardware Monitor module
+ *
+ * Copyright (C) 2020 Gateworks Corporation
+ */
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/mfd/gsc.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#include <linux/platform_data/gsc_hwmon.h>
+
+#define GSC_HWMON_MAX_TEMP_CH 16
+#define GSC_HWMON_MAX_IN_CH 16
+
+#define GSC_HWMON_RESOLUTION 12
+#define GSC_HWMON_VREF 2500
+
+struct gsc_hwmon_data {
+ struct gsc_dev *gsc;
+ struct gsc_hwmon_platform_data *pdata;
+ struct regmap *regmap;
+ const struct gsc_hwmon_channel *temp_ch[GSC_HWMON_MAX_TEMP_CH];
+ const struct gsc_hwmon_channel *in_ch[GSC_HWMON_MAX_IN_CH];
+ u32 temp_config[GSC_HWMON_MAX_TEMP_CH + 1];
+ u32 in_config[GSC_HWMON_MAX_IN_CH + 1];
+ struct hwmon_channel_info temp_info;
+ struct hwmon_channel_info in_info;
+ const struct hwmon_channel_info *info[3];
+ struct hwmon_chip_info chip;
+};
+
+static struct regmap_bus gsc_hwmon_regmap_bus = {
+ .reg_read = gsc_read,
+ .reg_write = gsc_write,
+};
+
+static const struct regmap_config gsc_hwmon_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .cache_type = REGCACHE_NONE,
+};
+
+static ssize_t pwm_auto_point_temp_show(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct gsc_hwmon_data *hwmon = dev_get_drvdata(dev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ u8 reg = hwmon->pdata->fan_base + (2 * attr->index);
+ u8 regs[2];
+ int ret;
+
+ ret = regmap_bulk_read(hwmon->regmap, reg, regs, 2);
+ if (ret)
+ return ret;
+
+ ret = regs[0] | regs[1] << 8;
+ return sprintf(buf, "%d\n", ret * 10);
+}
+
+static ssize_t pwm_auto_point_temp_store(struct device *dev,
+ struct device_attribute *devattr,
+ const char *buf, size_t count)
+{
+ struct gsc_hwmon_data *hwmon = dev_get_drvdata(dev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ u8 reg = hwmon->pdata->fan_base + (2 * attr->index);
+ u8 regs[2];
+ long temp;
+ int err;
+
+ if (kstrtol(buf, 10, &temp))
+ return -EINVAL;
+
+ temp = clamp_val(temp, 0, 10000);
+ temp = DIV_ROUND_CLOSEST(temp, 10);
+
+ regs[0] = temp & 0xff;
+ regs[1] = (temp >> 8) & 0xff;
+ err = regmap_bulk_write(hwmon->regmap, reg, regs, 2);
+ if (err)
+ return err;
+
+ return count;
+}
+
+static ssize_t pwm_auto_point_pwm_show(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+
+ return sprintf(buf, "%d\n", 255 * (50 + (attr->index * 10)) / 100);
+}
+
+static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point1_pwm, pwm_auto_point_pwm, 0);
+static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point1_temp, pwm_auto_point_temp, 0);
+
+static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point2_pwm, pwm_auto_point_pwm, 1);
+static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point2_temp, pwm_auto_point_temp, 1);
+
+static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point3_pwm, pwm_auto_point_pwm, 2);
+static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point3_temp, pwm_auto_point_temp, 2);
+
+static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point4_pwm, pwm_auto_point_pwm, 3);
+static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point4_temp, pwm_auto_point_temp, 3);
+
+static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point5_pwm, pwm_auto_point_pwm, 4);
+static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point5_temp, pwm_auto_point_temp, 4);
+
+static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point6_pwm, pwm_auto_point_pwm, 5);
+static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point6_temp, pwm_auto_point_temp, 5);
+
+static struct attribute *gsc_hwmon_attributes[] = {
+ &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_point4_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_point4_temp.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_point5_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_point5_temp.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_point6_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_point6_temp.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group gsc_hwmon_group = {
+ .attrs = gsc_hwmon_attributes,
+};
+__ATTRIBUTE_GROUPS(gsc_hwmon);
+
+static int
+gsc_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
+ int channel, long *val)
+{
+ struct gsc_hwmon_data *hwmon = dev_get_drvdata(dev);
+ const struct gsc_hwmon_channel *ch;
+ int sz, ret;
+ long tmp;
+ u8 buf[3];
+
+ switch (type) {
+ case hwmon_in:
+ ch = hwmon->in_ch[channel];
+ break;
+ case hwmon_temp:
+ ch = hwmon->temp_ch[channel];
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ sz = (ch->mode == mode_voltage) ? 3 : 2;
+ ret = regmap_bulk_read(hwmon->regmap, ch->reg, buf, sz);
+ if (ret)
+ return ret;
+
+ tmp = 0;
+ while (sz-- > 0)
+ tmp |= (buf[sz] << (8 * sz));
+
+ switch (ch->mode) {
+ case mode_temperature:
+ if (tmp > 0x8000)
+ tmp -= 0xffff;
+ break;
+ case mode_voltage_raw:
+ tmp = clamp_val(tmp, 0, BIT(GSC_HWMON_RESOLUTION));
+ /* scale based on ref voltage and ADC resolution */
+ tmp *= GSC_HWMON_VREF;
+ tmp >>= GSC_HWMON_RESOLUTION;
+ /* scale based on optional voltage divider */
+ if (ch->vdiv[0] && ch->vdiv[1]) {
+ tmp *= (ch->vdiv[0] + ch->vdiv[1]);
+ tmp /= ch->vdiv[1];
+ }
+ /* adjust by uV offset */
+ tmp += ch->mvoffset;
+ break;
+ case mode_voltage:
+ /* no adjustment needed */
+ break;
+ }
+
+ *val = tmp;
+
+ return 0;
+}
+
+static int
+gsc_hwmon_read_string(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, const char **buf)
+{
+ struct gsc_hwmon_data *hwmon = dev_get_drvdata(dev);
+
+ switch (type) {
+ case hwmon_in:
+ *buf = hwmon->in_ch[channel]->name;
+ break;
+ case hwmon_temp:
+ *buf = hwmon->temp_ch[channel]->name;
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+
+ return 0;
+}
+
+static umode_t
+gsc_hwmon_is_visible(const void *_data, enum hwmon_sensor_types type, u32 attr,
+ int ch)
+{
+ return 0444;
+}
+
+static const struct hwmon_ops gsc_hwmon_ops = {
+ .is_visible = gsc_hwmon_is_visible,
+ .read = gsc_hwmon_read,
+ .read_string = gsc_hwmon_read_string,
+};
+
+static struct gsc_hwmon_platform_data *
+gsc_hwmon_get_devtree_pdata(struct device *dev)
+{
+ struct gsc_hwmon_platform_data *pdata;
+ struct gsc_hwmon_channel *ch;
+ struct fwnode_handle *child;
+ struct device_node *fan;
+ int nchannels;
+
+ nchannels = device_get_child_node_count(dev);
+ if (nchannels == 0)
+ return ERR_PTR(-ENODEV);
+
+ pdata = devm_kzalloc(dev,
+ sizeof(*pdata) + nchannels * sizeof(*ch),
+ GFP_KERNEL);
+ if (!pdata)
+ return ERR_PTR(-ENOMEM);
+ ch = (struct gsc_hwmon_channel *)(pdata + 1);
+ pdata->channels = ch;
+ pdata->nchannels = nchannels;
+
+ /* fan controller base address */
+ fan = of_find_compatible_node(dev->parent->of_node, NULL, "gw,gsc-fan");
+ if (fan && of_property_read_u32(fan, "reg", &pdata->fan_base)) {
+ dev_err(dev, "fan node without base\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ /* allocate structures for channels and count instances of each type */
+ device_for_each_child_node(dev, child) {
+ if (fwnode_property_read_string(child, "label", &ch->name)) {
+ dev_err(dev, "channel without label\n");
+ fwnode_handle_put(child);
+ return ERR_PTR(-EINVAL);
+ }
+ if (fwnode_property_read_u32(child, "reg", &ch->reg)) {
+ dev_err(dev, "channel without reg\n");
+ fwnode_handle_put(child);
+ return ERR_PTR(-EINVAL);
+ }
+ if (fwnode_property_read_u32(child, "gw,mode", &ch->mode)) {
+ dev_err(dev, "channel without mode\n");
+ fwnode_handle_put(child);
+ return ERR_PTR(-EINVAL);
+ }
+ if (ch->mode > mode_max) {
+ dev_err(dev, "invalid channel mode\n");
+ fwnode_handle_put(child);
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (!fwnode_property_read_u32(child,
+ "gw,voltage-offset-microvolt",
+ &ch->mvoffset))
+ ch->mvoffset /= 1000;
+ fwnode_property_read_u32_array(child,
+ "gw,voltage-divider-ohms",
+ ch->vdiv, ARRAY_SIZE(ch->vdiv));
+ ch++;
+ }
+
+ return pdata;
+}
+
+static int gsc_hwmon_probe(struct platform_device *pdev)
+{
+ struct gsc_dev *gsc = dev_get_drvdata(pdev->dev.parent);
+ struct device *dev = &pdev->dev;
+ struct device *hwmon_dev;
+ struct gsc_hwmon_platform_data *pdata = dev_get_platdata(dev);
+ struct gsc_hwmon_data *hwmon;
+ const struct attribute_group **groups;
+ int i, i_in, i_temp;
+
+ if (!pdata) {
+ pdata = gsc_hwmon_get_devtree_pdata(dev);
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
+ }
+
+ hwmon = devm_kzalloc(dev, sizeof(*hwmon), GFP_KERNEL);
+ if (!hwmon)
+ return -ENOMEM;
+ hwmon->gsc = gsc;
+ hwmon->pdata = pdata;
+
+ hwmon->regmap = devm_regmap_init(dev, &gsc_hwmon_regmap_bus,
+ gsc->i2c_hwmon,
+ &gsc_hwmon_regmap_config);
+ if (IS_ERR(hwmon->regmap))
+ return PTR_ERR(hwmon->regmap);
+
+ for (i = 0, i_in = 0, i_temp = 0; i < hwmon->pdata->nchannels; i++) {
+ const struct gsc_hwmon_channel *ch = &pdata->channels[i];
+
+ switch (ch->mode) {
+ case mode_temperature:
+ if (i_temp == GSC_HWMON_MAX_TEMP_CH) {
+ dev_err(gsc->dev, "too many temp channels\n");
+ return -EINVAL;
+ }
+ hwmon->temp_ch[i_temp] = ch;
+ hwmon->temp_config[i_temp] = HWMON_T_INPUT |
+ HWMON_T_LABEL;
+ i_temp++;
+ break;
+ case mode_voltage:
+ case mode_voltage_raw:
+ if (i_in == GSC_HWMON_MAX_IN_CH) {
+ dev_err(gsc->dev, "too many input channels\n");
+ return -EINVAL;
+ }
+ hwmon->in_ch[i_in] = ch;
+ hwmon->in_config[i_in] =
+ HWMON_I_INPUT | HWMON_I_LABEL;
+ i_in++;
+ break;
+ default:
+ dev_err(gsc->dev, "invalid mode: %d\n", ch->mode);
+ return -EINVAL;
+ }
+ }
+
+ /* setup config structures */
+ hwmon->chip.ops = &gsc_hwmon_ops;
+ hwmon->chip.info = hwmon->info;
+ hwmon->info[0] = &hwmon->temp_info;
+ hwmon->info[1] = &hwmon->in_info;
+ hwmon->temp_info.type = hwmon_temp;
+ hwmon->temp_info.config = hwmon->temp_config;
+ hwmon->in_info.type = hwmon_in;
+ hwmon->in_info.config = hwmon->in_config;
+
+ groups = pdata->fan_base ? gsc_hwmon_groups : NULL;
+ hwmon_dev = devm_hwmon_device_register_with_info(dev,
+ KBUILD_MODNAME, hwmon,
+ &hwmon->chip, groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+static const struct of_device_id gsc_hwmon_of_match[] = {
+ { .compatible = "gw,gsc-adc", },
+ {}
+};
+
+static struct platform_driver gsc_hwmon_driver = {
+ .driver = {
+ .name = "gsc-hwmon",
+ .of_match_table = gsc_hwmon_of_match,
+ },
+ .probe = gsc_hwmon_probe,
+};
+
+module_platform_driver(gsc_hwmon_driver);
+
+MODULE_AUTHOR("Tim Harvey <tharvey@gateworks.com>");
+MODULE_DESCRIPTION("GSC hardware monitor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/platform_data/gsc_hwmon.h b/include/linux/platform_data/gsc_hwmon.h
new file mode 100644
index 00000000..ec1611a
--- /dev/null
+++ b/include/linux/platform_data/gsc_hwmon.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _GSC_HWMON_H
+#define _GSC_HWMON_H
+
+enum gsc_hwmon_mode {
+ mode_temperature,
+ mode_voltage,
+ mode_voltage_raw,
+ mode_max,
+};
+
+/**
+ * struct gsc_hwmon_channel - configuration parameters
+ * @reg: I2C register offset
+ * @mode: channel mode
+ * @name: channel name
+ * @mvoffset: voltage offset
+ * @vdiv: voltage divider array (2 resistor values in milli-ohms)
+ */
+struct gsc_hwmon_channel {
+ unsigned int reg;
+ unsigned int mode;
+ const char *name;
+ unsigned int mvoffset;
+ unsigned int vdiv[2];
+};
+
+/**
+ * struct gsc_hwmon_platform_data - platform data for gsc_hwmon driver
+ * @channels: pointer to array of gsc_hwmon_channel structures
+ * describing channels
+ * @nchannels: number of elements in @channels array
+ * @vreference: voltage reference (mV)
+ * @resolution: ADC bit resolution
+ * @fan_base: register base for FAN controller
+ */
+struct gsc_hwmon_platform_data {
+ const struct gsc_hwmon_channel *channels;
+ int nchannels;
+ unsigned int resolution;
+ unsigned int vreference;
+ unsigned int fan_base;
+};
+#endif
--
2.7.4
^ permalink raw reply related
* [PATCH v11 2/3] mfd: add Gateworks System Controller core driver
From: Tim Harvey @ 2020-05-15 17:57 UTC (permalink / raw)
To: Lee Jones, Jean Delvare, Guenter Roeck, linux-hwmon, Rob Herring,
Frank Rowand, devicetree, linux-kernel, Robert Jones
Cc: Tim Harvey
In-Reply-To: <1589565428-28886-1-git-send-email-tharvey@gateworks.com>
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
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>
---
v11:
- fix compile error
v10:
- fix typo and gramatical errors in Kconfig and comment block
- drop unused i2c device-id table
- added Lee's ack in s-o-b
v9:
- rebase against 5.7-rc2
- cleanup gsc_powerdown() by using BIT(), put_unaligned_le32(), and avoid
unnecessary assignments
- rename GSC_CTRL_1 SLEEP related defines to simplify
- add better description and sub-module info to driver description
- whitespace changes per review
- remove unused irq_data pointer in ddata
- remove unnecesary i2c_set_clientdata
- use devm_i2c_new_dummy_device to avoid need of free's
- change regsiter definitions to enum
- export gsc_{read,write} instead of sharing them via ddata
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 | 15 +++
drivers/mfd/Makefile | 1 +
drivers/mfd/gateworks-gsc.c | 277 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/mfd/gsc.h | 76 ++++++++++++
5 files changed, 377 insertions(+)
create mode 100644 drivers/mfd/gateworks-gsc.c
create mode 100644 include/linux/mfd/gsc.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 091ec22..c78a014 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7028,6 +7028,14 @@ F: kernel/futex.c
F: tools/perf/bench/futex*
F: tools/testing/selftests/futex/
+GATEWORKS SYSTEM CONTROLLER (GSC) DRIVER
+M: Tim Harvey <tharvey@gateworks.com>
+M: Robert Jones <rjones@gateworks.com>
+S: Maintained
+F: Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml
+F: drivers/mfd/gateworks-gsc.c
+F: include/linux/mfd/gsc.h
+
GASKET DRIVER FRAMEWORK
M: Rob Springer <rspringer@google.com>
M: Todd Poynor <toddpoynor@google.com>
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 0a59249..05448e7 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -407,6 +407,21 @@ 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 (GSC) found
+ on Gateworks Single Board Computers supporting system functions
+ such as push-button monitor, multiple ADC's for voltage and
+ temperature monitoring, fan controller and watchdog monitor.
+ This driver provides common support for accessing the device.
+ Additional drivers must be enabled in order to use the
+ functionality of the device.
+
config MFD_MC13XXX
tristate
depends on (SPI_MASTER || I2C)
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index f935d10..ed433ae 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 00000000..576da62
--- /dev/null
+++ b/drivers/mfd/gateworks-gsc.c
@@ -0,0 +1,277 @@
+// 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 push-button monitoring, multiple ADC's for
+ * voltage and temperature monitoring, fan controller and watchdog monitor.
+ *
+ * Copyright (C) 2020 Gateworks Corporation
+ */
+
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/gsc.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <asm/unaligned.h>
+
+/*
+ * 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
+
+int gsc_write(void *context, unsigned int reg, unsigned int val)
+{
+ struct i2c_client *client = context;
+ int retry, ret;
+
+ for (retry = 0; retry < I2C_RETRIES; retry++) {
+ ret = i2c_smbus_write_byte_data(client, reg, val);
+ /*
+ * -EAGAIN returned when the i2c host controller is busy
+ * -EIO returned when i2c device is busy
+ */
+ if (ret != -EAGAIN && ret != -EIO)
+ break;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(gsc_write);
+
+int gsc_read(void *context, unsigned int reg, unsigned int *val)
+{
+ struct i2c_client *client = context;
+ int retry, ret;
+
+ for (retry = 0; retry < I2C_RETRIES; retry++) {
+ ret = i2c_smbus_read_byte_data(client, reg);
+ /*
+ * -EAGAIN returned when the i2c host controller is busy
+ * -EIO returned when i2c device is busy
+ */
+ if (ret != -EAGAIN && ret != -EIO)
+ break;
+ }
+ *val = ret & 0xff;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(gsc_read);
+
+/*
+ * gsc_powerdown - API to use GSC to power down board for a specific time
+ *
+ * secs - number of seconds to remain powered off
+ */
+static int gsc_powerdown(struct gsc_dev *gsc, unsigned long secs)
+{
+ int ret;
+ unsigned char regs[4];
+
+ dev_info(&gsc->i2c->dev, "GSC powerdown for %ld seconds\n",
+ secs);
+
+ put_unaligned_le32(secs, regs);
+ ret = regmap_bulk_write(gsc->regmap, GSC_TIME_ADD, regs, 4);
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(gsc->regmap, GSC_CTRL_1,
+ BIT(GSC_CTRL_1_SLEEP_ADD),
+ BIT(GSC_CTRL_1_SLEEP_ADD));
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(gsc->regmap, GSC_CTRL_1,
+ BIT(GSC_CTRL_1_SLEEP_ACTIVATE) |
+ BIT(GSC_CTRL_1_SLEEP_ENABLE),
+ BIT(GSC_CTRL_1_SLEEP_ACTIVATE) |
+ BIT(GSC_CTRL_1_SLEEP_ENABLE));
+
+
+ return ret;
+}
+
+static ssize_t gsc_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct gsc_dev *gsc = dev_get_drvdata(dev);
+ const char *name = attr->attr.name;
+ int rz = 0;
+
+ if (strcasecmp(name, "fw_version") == 0)
+ rz = sprintf(buf, "%d\n", gsc->fwver);
+ else if (strcasecmp(name, "fw_crc") == 0)
+ rz = sprintf(buf, "0x%04x\n", gsc->fwcrc);
+ else
+ dev_err(dev, "invalid command: '%s'\n", name);
+
+ return rz;
+}
+
+static ssize_t gsc_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct gsc_dev *gsc = dev_get_drvdata(dev);
+ const char *name = attr->attr.name;
+ long value;
+
+ if (strcasecmp(name, "powerdown") == 0) {
+ if (kstrtol(buf, 0, &value) == 0)
+ gsc_powerdown(gsc, value);
+ } else {
+ dev_err(dev, "invalid command: '%s\n", name);
+ }
+
+ return count;
+}
+
+static struct device_attribute attr_fwver =
+ __ATTR(fw_version, 0440, gsc_show, NULL);
+static struct device_attribute attr_fwcrc =
+ __ATTR(fw_crc, 0440, gsc_show, NULL);
+static struct device_attribute attr_pwrdown =
+ __ATTR(powerdown, 0220, NULL, gsc_store);
+
+static struct attribute *gsc_attrs[] = {
+ &attr_fwver.attr,
+ &attr_fwcrc.attr,
+ &attr_pwrdown.attr,
+ NULL,
+};
+
+static struct attribute_group attr_group = {
+ .attrs = gsc_attrs,
+};
+
+static const struct of_device_id gsc_of_match[] = {
+ { .compatible = "gw,gsc", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, gsc_of_match);
+
+static struct regmap_bus gsc_regmap_bus = {
+ .reg_read = gsc_read,
+ .reg_write = gsc_write,
+};
+
+static const struct regmap_config gsc_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .cache_type = REGCACHE_NONE,
+ .max_register = GSC_WP,
+};
+
+static const struct regmap_irq gsc_irqs[] = {
+ REGMAP_IRQ_REG(GSC_IRQ_PB, 0, BIT(GSC_IRQ_PB)),
+ REGMAP_IRQ_REG(GSC_IRQ_KEY_ERASED, 0, BIT(GSC_IRQ_KEY_ERASED)),
+ REGMAP_IRQ_REG(GSC_IRQ_EEPROM_WP, 0, BIT(GSC_IRQ_EEPROM_WP)),
+ REGMAP_IRQ_REG(GSC_IRQ_RESV, 0, BIT(GSC_IRQ_RESV)),
+ REGMAP_IRQ_REG(GSC_IRQ_GPIO, 0, BIT(GSC_IRQ_GPIO)),
+ REGMAP_IRQ_REG(GSC_IRQ_TAMPER, 0, BIT(GSC_IRQ_TAMPER)),
+ REGMAP_IRQ_REG(GSC_IRQ_WDT_TIMEOUT, 0, BIT(GSC_IRQ_WDT_TIMEOUT)),
+ REGMAP_IRQ_REG(GSC_IRQ_SWITCH_HOLD, 0, BIT(GSC_IRQ_SWITCH_HOLD)),
+};
+
+static const struct regmap_irq_chip gsc_irq_chip = {
+ .name = "gateworks-gsc",
+ .irqs = gsc_irqs,
+ .num_irqs = ARRAY_SIZE(gsc_irqs),
+ .num_regs = 1,
+ .status_base = GSC_IRQ_STATUS,
+ .mask_base = GSC_IRQ_ENABLE,
+ .mask_invert = true,
+ .ack_base = GSC_IRQ_STATUS,
+ .ack_invert = true,
+};
+
+static int gsc_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct gsc_dev *gsc;
+ struct regmap_irq_chip_data *irq_data;
+ int ret;
+ unsigned int reg;
+
+ gsc = devm_kzalloc(dev, sizeof(*gsc), GFP_KERNEL);
+ if (!gsc)
+ return -ENOMEM;
+
+ gsc->dev = &client->dev;
+ gsc->i2c = client;
+ i2c_set_clientdata(client, gsc);
+
+ gsc->regmap = devm_regmap_init(dev, &gsc_regmap_bus, client,
+ &gsc_regmap_config);
+ if (IS_ERR(gsc->regmap))
+ return PTR_ERR(gsc->regmap);
+
+ if (regmap_read(gsc->regmap, GSC_FW_VER, ®))
+ return -EIO;
+ gsc->fwver = reg;
+
+ regmap_read(gsc->regmap, GSC_FW_CRC, ®);
+ gsc->fwcrc = reg;
+ regmap_read(gsc->regmap, GSC_FW_CRC + 1, ®);
+ gsc->fwcrc |= reg << 8;
+
+ gsc->i2c_hwmon = devm_i2c_new_dummy_device(dev, client->adapter,
+ GSC_HWMON);
+ if (IS_ERR(gsc->i2c_hwmon)) {
+ dev_err(dev, "Failed to allocate I2C device for HWMON\n");
+ return PTR_ERR(gsc->i2c_hwmon);
+ }
+
+ ret = devm_regmap_add_irq_chip(dev, gsc->regmap, client->irq,
+ IRQF_ONESHOT | IRQF_SHARED |
+ IRQF_TRIGGER_FALLING, 0,
+ &gsc_irq_chip, &irq_data);
+ if (ret)
+ return ret;
+
+ dev_info(dev, "Gateworks System Controller v%d: fw 0x%04x\n",
+ gsc->fwver, gsc->fwcrc);
+
+ ret = sysfs_create_group(&dev->kobj, &attr_group);
+ if (ret)
+ dev_err(dev, "failed to create sysfs attrs\n");
+
+ ret = devm_of_platform_populate(dev);
+ if (ret) {
+ sysfs_remove_group(&dev->kobj, &attr_group);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int gsc_remove(struct i2c_client *client)
+{
+ sysfs_remove_group(&client->dev.kobj, &attr_group);
+
+ return 0;
+}
+
+static struct i2c_driver gsc_driver = {
+ .driver = {
+ .name = "gateworks-gsc",
+ .of_match_table = gsc_of_match,
+ },
+ .probe_new = gsc_probe,
+ .remove = gsc_remove,
+};
+module_i2c_driver(gsc_driver);
+
+MODULE_AUTHOR("Tim Harvey <tharvey@gateworks.com>");
+MODULE_DESCRIPTION("I2C Core interface for GSC");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/gsc.h b/include/linux/mfd/gsc.h
new file mode 100644
index 00000000..6bd639c
--- /dev/null
+++ b/include/linux/mfd/gsc.h
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2020 Gateworks Corporation
+ */
+#ifndef __LINUX_MFD_GSC_H_
+#define __LINUX_MFD_GSC_H_
+
+#include <linux/regmap.h>
+
+/* Device Addresses */
+#define GSC_MISC 0x20
+#define GSC_UPDATE 0x21
+#define GSC_GPIO 0x23
+#define GSC_HWMON 0x29
+#define GSC_EEPROM0 0x50
+#define GSC_EEPROM1 0x51
+#define GSC_EEPROM2 0x52
+#define GSC_EEPROM3 0x53
+#define GSC_RTC 0x68
+
+/* Register offsets */
+enum {
+ GSC_CTRL_0 = 0x00,
+ GSC_CTRL_1 = 0x01,
+ GSC_TIME = 0x02,
+ GSC_TIME_ADD = 0x06,
+ GSC_IRQ_STATUS = 0x0A,
+ GSC_IRQ_ENABLE = 0x0B,
+ GSC_FW_CRC = 0x0C,
+ GSC_FW_VER = 0x0E,
+ GSC_WP = 0x0F,
+};
+
+/* Bit definitions */
+#define GSC_CTRL_0_PB_HARD_RESET 0
+#define GSC_CTRL_0_PB_CLEAR_SECURE_KEY 1
+#define GSC_CTRL_0_PB_SOFT_POWER_DOWN 2
+#define GSC_CTRL_0_PB_BOOT_ALTERNATE 3
+#define GSC_CTRL_0_PERFORM_CRC 4
+#define GSC_CTRL_0_TAMPER_DETECT 5
+#define GSC_CTRL_0_SWITCH_HOLD 6
+
+#define GSC_CTRL_1_SLEEP_ENABLE 0
+#define GSC_CTRL_1_SLEEP_ACTIVATE 1
+#define GSC_CTRL_1_SLEEP_ADD 2
+#define GSC_CTRL_1_SLEEP_NOWAKEPB 3
+#define GSC_CTRL_1_WDT_TIME 4
+#define GSC_CTRL_1_WDT_ENABLE 5
+#define GSC_CTRL_1_SWITCH_BOOT_ENABLE 6
+#define GSC_CTRL_1_SWITCH_BOOT_CLEAR 7
+
+#define GSC_IRQ_PB 0
+#define GSC_IRQ_KEY_ERASED 1
+#define GSC_IRQ_EEPROM_WP 2
+#define GSC_IRQ_RESV 3
+#define GSC_IRQ_GPIO 4
+#define GSC_IRQ_TAMPER 5
+#define GSC_IRQ_WDT_TIMEOUT 6
+#define GSC_IRQ_SWITCH_HOLD 7
+
+int gsc_read(void *context, unsigned int reg, unsigned int *val);
+int gsc_write(void *context, unsigned int reg, unsigned int val);
+
+struct gsc_dev {
+ struct device *dev;
+
+ struct i2c_client *i2c; /* 0x20: interrupt controller, WDT */
+ struct i2c_client *i2c_hwmon; /* 0x29: hwmon, fan controller */
+
+ struct regmap *regmap;
+
+ unsigned int fwver;
+ unsigned short fwcrc;
+};
+
+#endif /* __LINUX_MFD_GSC_H_ */
--
2.7.4
^ permalink raw reply related
* Re: [PATCH v7 1/4] dt-bindings: phy: qcom,qmp: Convert QMP PHY bindings to yaml
From: Matthias Kaehlcke @ 2020-05-15 18:18 UTC (permalink / raw)
To: Sandeep Maheswaram
Cc: Andy Gross, Bjorn Andersson, Kishon Vijay Abraham I, Rob Herring,
Mark Rutland, Stephen Boyd, Doug Anderson, linux-arm-msm,
linux-kernel, devicetree, Manu Gautam
In-Reply-To: <1589510358-3865-2-git-send-email-sanm@codeaurora.org>
On Fri, May 15, 2020 at 08:09:15AM +0530, Sandeep Maheswaram wrote:
> Convert QMP PHY bindings to DT schema format using json-schema.
>
> Signed-off-by: Sandeep Maheswaram <sanm@codeaurora.org>
This is essentially the same as v5, for which got a 'Reviewed-by' tag
from Rob:
diff --git a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
index 18a8985e54d5..dcdb014d6d4d 100644
--- a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
@@ -30,6 +30,7 @@ properties:
- qcom,sdm845-qmp-usb3-phy
- qcom,sdm845-qmp-usb3-uni-phy
- qcom,sm8150-qmp-ufs-phy
+ - qcom,sm8250-qmp-ufs-phy
reg:
minItems: 1
@@ -217,6 +218,7 @@ allOf:
- qcom,msm8998-qmp-ufs-phy
- qcom,sdm845-qmp-ufs-phy
- qcom,sm8150-qmp-ufs-phy
+ - qcom,sm8250-qmp-ufs-phy
then:
properties:
clocks:
I think it would have been ok to add Rob's 'Reviewed-by' tag and save
him the time to look at this again.
^ permalink raw reply related
* Re: [PATCH v8 2/6] ARM: tegra: Add device-tree for ASUS Google Nexus 7
From: Michał Mirosław @ 2020-05-15 18:18 UTC (permalink / raw)
To: Dmitry Osipenko
Cc: Rob Herring, Thierry Reding, Jonathan Hunter, David Heidelberg,
Peter Geis, Stephen Warren, Nicolas Chauvet, Pedro Ângelo,
Matt Merhar, Zack Pearsall, linux-tegra, devicetree, linux-kernel
In-Reply-To: <20200514213654.12834-3-digetx@gmail.com>
On Fri, May 15, 2020 at 12:36:50AM +0300, Dmitry Osipenko wrote:
> There are few hardware variants of NVIDIA Tegra30-based Nexus 7 device:
>
> 1. WiFi-only (named Grouper)
> 2. GSM (named Tilapia)
> 3. Using Maxim PMIC (E1565 board ID)
> 4. Using Ti PMIC (PM269 board ID)
Hi,
I've briefly looked at the PM269 devicetree (PMIC part) and it looks very
similar, if not the same, to what I deduced from the TF300T kernel.
Those devices don't look to differ much from original Cardhu tablet
devkit, so maybe the trees can base off of that?
I would also guess that because of this 'ram-code', memory timings would
be duplicated between devices. I can see small differences between
ram-code=1 timings of Grouper and TF300T, though they look like arbiter
tuning differences. I'll have to test if my TF300T works with Grouper's
settings. In case they work, could you split the memory timings to another
dtsi file?
BTW, shouldn't EMC timing set match MC? I see more frequencies listed in
MC than EMC nodes.
Best Regards,
Michał Mirosław
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox