* Re: [PATCH 1/2] doc: Add bindings document for Xilinx LogiCore PR Decoupler
From: Moritz Fischer @ 2017-04-04 23:36 UTC (permalink / raw)
To: Rob Herring
Cc: Alan Tull, Greg Kroah-Hartman, Linux Kernel Mailing List,
linux-fpga-u79uwXL29TY76Z2rM5mHXA, Moritz Fischer, Michal Simek,
Sören Brinkmann, Devicetree List
In-Reply-To: <20170330224429.yo42hgnr7nhm2ljv@rob-hp-laptop>
On Thu, Mar 30, 2017 at 05:44:29PM -0500, Rob Herring wrote:
> On Fri, Mar 24, 2017 at 10:33:20AM -0500, Alan Tull wrote:
> > From: Moritz Fischer <mdf-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>
> Please use "dt-bindings: fpga: ..." for the subject.
>
>
> >
> > This adds the binding documentation for the Xilinx LogiCORE PR
> > Decoupler soft core.
> >
> > Signed-off-by: Moritz Fischer <mdf-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> > Signed-off-by: Michal Simek <michal.simek-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
> > Acked-by: Alan Tull <atull-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>
> I'm confused why you are sending these instead of Moritz? If it goes
> through you, then it should have your S-o-B too.
Do you want me to resend this Alan (with Rob's suggestions)?
>
> > Cc: Sören Brinkmann <soren.brinkmann-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
> > Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > ---
> > .../bindings/fpga/xilinx-pr-decoupler.txt | 35 ++++++++++++++++++++++
> > 1 file changed, 35 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt
> >
> > diff --git a/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt b/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt
> > new file mode 100644
> > index 000000000000..2c527ac30398
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt
> > @@ -0,0 +1,35 @@
> > +Xilinx LogiCORE Partial Reconfig Decoupler Softcore
> > +
> > +The Xilinx LogiCORE Partial Reconfig Decoupler manages one or more
> > +decouplers / fpga bridges.
> > +The controller can decouple/disable the bridges which prevents signal
> > +changes from passing through the bridge. The controller can also
> > +couple / enable the bridges which allows traffic to pass through the
> > +bridge normally.
> > +
> > +The Driver supports only MMIO handling. A PR region can have multiple
> > +PR Decouplers which can be handled independently or chained via decouple/
> > +decouple_status signals.
> > +
> > +Required properties:
> > +- compatible : Should contain "xlnx,pr-decoupler-1.00" or "xlnx,pr-decoupler"
>
> I'd drop xlnx,pr-decoupler, but in any case, it should not be OR rather
> "followed by". Plus the example has both.
Michal wanted to have both, so I put both. Personally I don't care. I
think they have some downstream stuff that relied on it.
>
> > +- regs : base address and size for decoupler module
> > +- clocks : input clock to IP
> > +- clock-names : should contain "aclk"
> > +
> > +Optional properties:
> > +- bridge-enable : 0 if driver should disable bridge at startup
> > + 1 if driver should enable bridge at startup
> > + Default is to leave bridge in current state.
> > +
> > +See Documentation/devicetree/bindings/fpga/fpga-region.txt for generic bindings.
> > +
> > +Example:
> > + fpga-bridge@100000450 {
> > + compatible = "xlnx,pr-decoupler-1.00",
> > + "xlnx-pr-decoupler";
> > + regs = <0x10000045 0x10>;
> > + clocks = <&clkc 15>;
> > + clock-names = "aclk";
> > + bridge-enable = <0>;
> > + };
> > --
> > 2.11.0
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe devicetree" in
> > the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
Thanks,
Moritz
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [RFC] [media] imx: assume MEDIA_ENT_F_ATV_DECODER entities output video on pad 1
From: Russell King - ARM Linux @ 2017-04-04 23:10 UTC (permalink / raw)
To: Philipp Zabel
Cc: Steve Longerbeam, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, shawnguo-DgEjT+Ai2ygdnm+yROfE0A,
kernel-bIcnvbaLZ9MEGnE8C9+IrQ, fabio.estevam-3arQi8VN3Tc,
mchehab-DgEjT+Ai2ygdnm+yROfE0A, hverkuil-qWit8jRvyhVmR6Xm/wNWPw,
nick-gcszYUEDH4VrovVCs/uTlw, markus.heiser-O6JHGLzbNUwb1SvskN2V4Q,
laurent.pinchart+renesas-ryLnwIuWjnjg/C1BVhZhaw,
bparrot-l0cyMroinI0, geert-Td1EMuHUCqxL1ZNQvxDV9g,
arnd-r2nGTMty4D4, sudipm.mukherjee-Re5JQEeQqe8AvxtiuMwx3w,
minghsiu.tsai-NuS5LvNUpcJWk0Htik3J/w,
tiffany.lin-NuS5LvNUpcJWk0Htik3J/w,
jean-christophe.trotin-qxv4g6HH51o,
horms+renesas-/R6kz+dDXgpPR4JQBCEnsQ,
niklas.soderlund+renesas-1zkq55x86MTxsAP9Fp7wbw,
robert.jarzmik-GANU6spQydw, songjun.wu-UWL1GkI3JZL3oGB3hsPCZA,
andrew-ct.chen-NuS5LvNUpcJWk0Htik3J/w,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
shuah-DgEjT+Ai2ygdnm+yROfE0A, sakari.ailus-VuQAYsv1563Yd54FQh9/CA,
pavel-+ZI9xUNit7I, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, linux-media
In-Reply-To: <1490894749.2404.33.camel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
On Thu, Mar 30, 2017 at 07:25:49PM +0200, Philipp Zabel wrote:
> The TVP5150 DT bindings specify a single output port (port 0) that
> corresponds to the video output pad (pad 1, DEMOD_PAD_VID_OUT).
>
> Signed-off-by: Philipp Zabel <p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
> ---
> I'm trying to get this to work with a TVP5150 analog TV decoder, and the
> first problem is that this device doesn't have pad 0 as its single
> output pad. Instead, as a MEDIA_ENT_F_ATV_DECODER entity, it has for
> pads (input, video out, vbi out, audio out), and video out is pad 1,
> whereas the device tree only defines a single port (0).
Looking at the patch, it's highlighted another review point with
Steve's driver.
> diff --git a/drivers/staging/media/imx/imx-media-dev.c b/drivers/staging/media/imx/imx-media-dev.c
> index 17e2386a3ca3a..c52d6ca797965 100644
> --- a/drivers/staging/media/imx/imx-media-dev.c
> +++ b/drivers/staging/media/imx/imx-media-dev.c
> @@ -267,6 +267,15 @@ static int imx_media_create_link(struct imx_media_dev *imxmd,
> source_pad = link->local_pad;
> sink_pad = link->remote_pad;
>
> + /*
> + * If the source subdev is an analog video decoder with a single source
> + * port, assume that this port 0 corresponds to the DEMOD_PAD_VID_OUT
> + * entity pad.
> + */
> + if (source->entity.function == MEDIA_ENT_F_ATV_DECODER &&
> + local_sd->num_sink_pads == 0 && local_sd->num_src_pads == 1)
> + source_pad = DEMOD_PAD_VID_OUT;
> +
> v4l2_info(&imxmd->v4l2_dev, "%s: %s:%d -> %s:%d\n", __func__,
> source->name, source_pad, sink->name, sink_pad);
What is "local" and what is "remote" here? It seems that, in the case of
a link being created with the sensor(etc), it's all back to front.
Eg, I see locally:
imx-media: imx_media_create_link: imx219 0-0010:0 -> imx6-mipi-csi2:0
So here, "source" is the imx219 (the sensor), and sink is "imx6-mipi-csi2"
(part of the iMX6 capture.) However, this makes "local_sd" the subdev of
the sensor, and "remote_sd" the subdev of the CSI2 interface - which is
totally back to front - this code is part of the iMX6 capture system,
so "local" implies that it should be part of that, and the "remote" thing
would be the sensor.
Hence, this seems completely confused. I'd suggest that:
(a) the "pad->pad.flags & MEDIA_PAD_FL_SINK" test in imx_media_create_link()
is moved into imx_media_create_links(), and placed here instead:
for (j = 0; j < num_pads; j++) {
pad = &local_sd->pad[j];
if (pad->pad.flags & MEDIA_PAD_FL_SINK)
continue;
...
}
as the pad isn't going to spontaneously change this flag while we
consider each individual link. However, maybe the test should be:
if (!(pad->pad.flags & MEDIA_PAD_FL_SOURCE))
?
(b) the terms "local" and "remote" in imx_media_create_link() are
replaced with "source" and "sink" respectively, since this will
now be called with a guaranteed source pad.
As for Philipp's solution, I'm not sure what the correct solution for
something like this is. It depends how you view "hardware interface"
as defined by video-interfaces.txt, and whether the pads on the TVP5150
represent the hardware interfaces. If we take the view that the pads
do represent hardware interfaces, then using the reg= property on the
port node will solve this problem.
If not, it would mean that we would have to have the iMX capture code
scan the pads on the source device, looking for outputs - but that
runs into a problem - if the source device has multiple outputs, does
the reg= property specify the output pad index or the pad number, and
what if one binding for a device specifies it one way and another
device's binding specifies it a different way.
There's lots of scope for making things really painful here, and
ending up with needing sensor-specific code in capture drivers to
work around different decisions on this.
I think someone needs to nail this down, if it's not already too late.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v4 19/23] drivers/fsi: Add GPIO based FSI master
From: Benjamin Herrenschmidt @ 2017-04-04 22:19 UTC (permalink / raw)
To: Christopher Bostic, Joel Stanley
Cc: Mark Rutland, devicetree, Andrew Jeffery, Greg KH, Russell King,
rostedt, Linux Kernel Mailing List, Rob Herring, Jeremy Kerr,
Edward A . James, Alistair Popple, mingo, linux-arm-kernel
In-Reply-To: <93b21624-11fc-b71b-aa78-6cb4371c87ae@linux.vnet.ibm.com>
On Tue, 2017-04-04 at 12:32 -0500, Christopher Bostic wrote:
> Agreed that there is room for improvement. I intend to look further
> into your suggestions from here and our private conversation on the
> matter and make changes as appropriate. I have an open issue to track
> this. As it exists in this patch reads/writes from master to slave
> fundamentally work.
My understanding is they "seem to work if you get lucky with the timing
and fall apart under load". Or did I hear wrong ?
> Given the pervasiveness and time to fully evaluate
> and test any protocol updates I intend address this in the near future
> with a separate follow on patch.
Please try the simple change I proposed in my email. It's a 4 or 5
lines change max to your clock_toggle function and how it's called in
send and receive. It should be trivial to check if things still "seem
to work" to begin with.
Do you have some kind of test mechanism that hammers the FSI
continuously ? Such as doing a series of putmemproc/getmemproc &
checking the values ?
Then you can run that while hammering the LPC bus and generally putting
the BMC under load and you'll quickly see if it's reliable or not.
Cheers,
Ben.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFC] [media] imx: assume MEDIA_ENT_F_ATV_DECODER entities output video on pad 1
From: Steve Longerbeam @ 2017-04-04 22:11 UTC (permalink / raw)
To: Philipp Zabel
Cc: robh+dt, mark.rutland, shawnguo, kernel, fabio.estevam, linux,
mchehab, hverkuil, nick, markus.heiser, laurent.pinchart+renesas,
bparrot, geert, arnd, sudipm.mukherjee, minghsiu.tsai,
tiffany.lin, jean-christophe.trotin, horms+renesas,
niklas.soderlund+renesas, robert.jarzmik, songjun.wu,
andrew-ct.chen, gregkh, shuah, sakari.ailus, pavel, devicetree,
linux-kernel, linux-arm-kernel, linux-media
In-Reply-To: <1490894749.2404.33.camel@pengutronix.de>
On 03/30/2017 10:25 AM, Philipp Zabel wrote:
> The TVP5150 DT bindings specify a single output port (port 0) that
> corresponds to the video output pad (pad 1, DEMOD_PAD_VID_OUT).
>
> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
> ---
> I'm trying to get this to work with a TVP5150 analog TV decoder, and the
> first problem is that this device doesn't have pad 0 as its single
> output pad. Instead, as a MEDIA_ENT_F_ATV_DECODER entity, it has for
> pads (input, video out, vbi out, audio out), and video out is pad 1,
> whereas the device tree only defines a single port (0).
Shouldn't the DT bindings define ports for these other pads?
I haven't seen this documented anywhere, but shouldn't there
be a 1:1 correspondence between DT ports and media pads?
Steve
> ---
>
> drivers/staging/media/imx/imx-media-dev.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/drivers/staging/media/imx/imx-media-dev.c b/drivers/staging/media/imx/imx-media-dev.c
> index 17e2386a3ca3a..c52d6ca797965 100644
> --- a/drivers/staging/media/imx/imx-media-dev.c
> +++ b/drivers/staging/media/imx/imx-media-dev.c
> @@ -267,6 +267,15 @@ static int imx_media_create_link(struct imx_media_dev *imxmd,
> source_pad = link->local_pad;
> sink_pad = link->remote_pad;
>
> + /*
> + * If the source subdev is an analog video decoder with a single source
> + * port, assume that this port 0 corresponds to the DEMOD_PAD_VID_OUT
> + * entity pad.
> + */
> + if (source->entity.function == MEDIA_ENT_F_ATV_DECODER &&
> + local_sd->num_sink_pads == 0 && local_sd->num_src_pads == 1)
> + source_pad = DEMOD_PAD_VID_OUT;
> +
> v4l2_info(&imxmd->v4l2_dev, "%s: %s:%d -> %s:%d\n", __func__,
> source->name, source_pad, sink->name, sink_pad);
>
>
^ permalink raw reply
* Re: [PATCH v5 7/9] clk: hi6220: add debug APB clock
From: Stephen Boyd @ 2017-04-04 21:51 UTC (permalink / raw)
To: Leo Yan
Cc: Jonathan Corbet, Rob Herring, Mark Rutland, Wei Xu,
Catalin Marinas, Will Deacon, Andy Gross, David Brown,
Michael Turquette, Mathieu Poirier, Guodong Xu, John Stultz,
linux-doc, linux-kernel, devicetree, linux-arm-kernel,
linux-arm-msm, linux-soc, linux-clk, mike.leach, Suzuki.Poulose,
sudeep.holla
In-Reply-To: <1490466197-29163-8-git-send-email-leo.yan@linaro.org>
On 03/26, Leo Yan wrote:
> The debug APB clock is absent in hi6220 driver, so this patch is to add
> support for it.
>
> Signed-off-by: Leo Yan <leo.yan@linaro.org>
> ---
Applied to clk-next. I suspect we don't need a topic branch for
the DT header because arm-soc won't be taking the dts side of the
changes?
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* Re: [PATCH v5 5/9] coresight: use const for device_node structures
From: Stephen Boyd @ 2017-04-04 21:48 UTC (permalink / raw)
To: Leo Yan
Cc: Jonathan Corbet, Rob Herring, Mark Rutland, Wei Xu,
Catalin Marinas, Will Deacon, Andy Gross, David Brown,
Michael Turquette, Mathieu Poirier, Guodong Xu, John Stultz,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
linux-soc-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA,
mike.leach-QSEj5FYQhm4dnm+yROfE0A, Suzuki.Poulose-5wv7dgnIgG8,
sudeep.holla-5wv7dgnIgG8
In-Reply-To: <1490466197-29163-6-git-send-email-leo.yan-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
On 03/26, Leo Yan wrote:
> Almost low level functions from open firmware have used const to
> qualify device_node structures, so add const for device_node
> parameters in of_coresight related functions.
>
> Signed-off-by: Leo Yan <leo.yan-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
Reviewed-by: Stephen Boyd <sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [GIT PULL] PCI: Support for configurable PCI endpoint
From: Bjorn Helgaas @ 2017-04-04 20:36 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: Bjorn Helgaas, Joao Pinto, linux-pci, linux-doc, linux-kernel,
devicetree, linux-omap, linux-arm-kernel, hch, nsekhar
In-Reply-To: <20170327094520.3129-1-kishon@ti.com>
On Mon, Mar 27, 2017 at 03:14:56PM +0530, Kishon Vijay Abraham I wrote:
> Hi Bjorn,
>
> Please find the pull request for PCI endpoint support below. I've
> also included all the history here.
I tentatively applied this to pci/host-designware with the mostly trival
textual changes below. If you post the series again, please include them.
I saw some acks to prior revisions, but few of them were included in this
series. Can you collect them up? If there are no other substantial
changes, I can insert them into my branch manually.
Bjorn
diff --git a/Documentation/PCI/00-INDEX b/Documentation/PCI/00-INDEX
index fd533c79fa19..00c9a90b6f38 100644
--- a/Documentation/PCI/00-INDEX
+++ b/Documentation/PCI/00-INDEX
@@ -15,10 +15,10 @@ pcieaer-howto.txt
endpoint/pci-endpoint.txt
- guide to add endpoint controller driver and endpoint function driver.
endpoint/pci-endpoint-cfs.txt
- - guide to use configfs to configure the pci endpoint function.
+ - guide to use configfs to configure the PCI endpoint function.
endpoint/pci-test-function.txt
- - specification of *pci test* function device.
+ - specification of *PCI test* function device.
endpoint/pci-test-howto.txt
- userguide for PCI endpoint test function.
endpoint/function/binding/
- - binding documentation for pci endpoint function
+ - binding documentation for PCI endpoint function
diff --git a/Documentation/PCI/endpoint/function/binding/pci-test.txt b/Documentation/PCI/endpoint/function/binding/pci-test.txt
index c44fc18d78cc..3b68b955fb50 100644
--- a/Documentation/PCI/endpoint/function/binding/pci-test.txt
+++ b/Documentation/PCI/endpoint/function/binding/pci-test.txt
@@ -13,5 +13,5 @@ cache_line_size : don't care
subsys_vendor_id : don't care
subsys_id : don't care
interrupt_pin : Should be 1 - INTA, 2 - INTB, 3 - INTC, 4 -INTD
-msi_interrupts : Should be 1 to 32 depending on the number of msi interrupts
+msi_interrupts : Should be 1 to 32 depending on the number of MSI interrupts
to test
diff --git a/Documentation/PCI/endpoint/pci-endpoint-cfs.txt b/Documentation/PCI/endpoint/pci-endpoint-cfs.txt
index 8b2a8280b131..d740f29960a4 100644
--- a/Documentation/PCI/endpoint/pci-endpoint-cfs.txt
+++ b/Documentation/PCI/endpoint/pci-endpoint-cfs.txt
@@ -1,10 +1,10 @@
CONFIGURING PCI ENDPOINT USING CONFIGFS
Kishon Vijay Abraham I <kishon@ti.com>
-The PCI Endpoint Core exposes configfs entry (pci_ep) in order to configure the
-PCI endpoint function and in order to bind the endpoint function
+The PCI Endpoint Core exposes configfs entry (pci_ep) to configure the
+PCI endpoint function and to bind the endpoint function
with the endpoint controller. (For introducing other mechanisms to
-configure the PCI Endpoint Function refer [1]).
+configure the PCI Endpoint Function refer to [1]).
*) Mounting configfs
diff --git a/Documentation/PCI/endpoint/pci-endpoint.txt b/Documentation/PCI/endpoint/pci-endpoint.txt
index 4a3e4388b37b..9b1d66829290 100644
--- a/Documentation/PCI/endpoint/pci-endpoint.txt
+++ b/Documentation/PCI/endpoint/pci-endpoint.txt
@@ -2,27 +2,27 @@
Kishon Vijay Abraham I <kishon@ti.com>
This document is a guide to use the PCI Endpoint Framework in order to create
-endpoint controller driver, endpoint function driver and using configfs
+endpoint controller driver, endpoint function driver, and using configfs
interface to bind the function driver to the controller driver.
1. Introduction
-*Linux* has a comprehensive PCI subsystem to support PCI controllers that
+Linux has a comprehensive PCI subsystem to support PCI controllers that
operates in Root Complex mode. The subsystem has capability to scan PCI bus,
-assign memory resources and irq resources, load PCI driver (based on
-vendorid, deviceid), support other services like hot-plug, power management,
+assign memory resources and IRQ resources, load PCI driver (based on
+vendor ID, device ID), support other services like hot-plug, power management,
advanced error reporting and virtual channels.
-However PCI controller IPs integrated in certain SoC is capable of operating
+However the PCI controller IP integrated in some SoCs is capable of operating
either in Root Complex mode or Endpoint mode. PCI Endpoint Framework will
-add endpoint mode support in *Linux*. This will help to run Linux in an
+add endpoint mode support in Linux. This will help to run Linux in an
EP system which can have a wide variety of use cases from testing or
-validation, co-processor accelerator etc..
+validation, co-processor accelerator, etc.
2. PCI Endpoint Core
-The PCI Endpoint Core layer comprises of 3 components: the Endpoint Controller
-library, the Endpoint Function library and the configfs layer to bind the
+The PCI Endpoint Core layer comprises 3 components: the Endpoint Controller
+library, the Endpoint Function library, and the configfs layer to bind the
endpoint function with the endpoint controller.
2.1 PCI Endpoint Controller(EPC) Library
@@ -42,20 +42,20 @@ by the PCI controller driver.
* write_header: ops to populate configuration space header
* set_bar: ops to configure the BAR
* clear_bar: ops to reset the BAR
- * alloc_addr_space: ops to allocate *in* PCI controller address space
+ * alloc_addr_space: ops to allocate in PCI controller address space
* free_addr_space: ops to free the allocated address space
* raise_irq: ops to raise a legacy or MSI interrupt
* start: ops to start the PCI link
* stop: ops to stop the PCI link
The PCI controller driver can then create a new EPC device by invoking
- devm_pci_epc_create/pci_epc_create.
+ devm_pci_epc_create()/pci_epc_create().
*) devm_pci_epc_destroy()/pci_epc_destroy()
The PCI controller driver can destroy the EPC device created by either
- devm_pci_epc_create or pci_epc_create using devm_pci_epc_destroy() or
- /pci_epc_destroy()
+ devm_pci_epc_create() or pci_epc_create() using devm_pci_epc_destroy() or
+ pci_epc_destroy().
*) pci_epc_linkup()
@@ -112,27 +112,27 @@ by the PCI endpoint function driver.
2.1.3 Other APIs
There are other APIs provided by the EPC library. These are used for binding
-the epf device with epc device. pci-ep-cfs.c can be used as reference for
+the EPF device with EPC device. pci-ep-cfs.c can be used as reference for
using these APIs.
*) pci_epc_get()
- Get a reference to the pci endpoint controller based on the device name of
+ Get a reference to the PCI endpoint controller based on the device name of
the controller.
*) pci_epc_put()
- Release the reference to the pci endpoint controller obtained using
+ Release the reference to the PCI endpoint controller obtained using
pci_epc_get()
*) pci_epc_add_epf()
- Add a pci endpoint function to a pci endpoint controller. A pcie device
- can have upto 8 functions according to the specification.
+ Add a PCI endpoint function to a PCI endpoint controller. A PCIe device
+ can have up to 8 functions according to the specification.
*) pci_epc_remove_epf()
- Remove the pci endpoint function from pci endpoint controller.
+ Remove the PCI endpoint function from PCI endpoint controller.
*) pci_epc_start()
@@ -147,7 +147,7 @@ using these APIs.
2.2 PCI Endpoint Function(EPF) Library
The EPF library provides APIs to be used by the function driver and the EPC
-library in order to provide endpoint mode functionality.
+library to provide endpoint mode functionality.
2.2.1 APIs for the PCI Endpoint Function Driver
diff --git a/Documentation/PCI/endpoint/pci-test-function.txt b/Documentation/PCI/endpoint/pci-test-function.txt
index 1324376ec6a3..0c519c9bf94a 100644
--- a/Documentation/PCI/endpoint/pci-test-function.txt
+++ b/Documentation/PCI/endpoint/pci-test-function.txt
@@ -32,8 +32,8 @@ This register will be used by the host driver to indicate the function
that the endpoint device must perform.
Bitfield Description:
- Bit 0 : raise legacy irq
- Bit 1 : raise MSI irq
+ Bit 0 : raise legacy IRQ
+ Bit 1 : raise MSI IRQ
Bit 2 - 7 : MSI interrupt number
Bit 8 : read command (read data from RC buffer)
Bit 9 : write command (write data to RC buffer)
@@ -51,7 +51,7 @@ Bitfield Description:
Bit 3 : write fail
Bit 4 : copy success
Bit 5 : copy fail
- Bit 6 : irq raised
+ Bit 6 : IRQ raised
Bit 7 : source address is invalid
Bit 8 : destination address is invalid
diff --git a/Documentation/PCI/endpoint/pci-test-howto.txt b/Documentation/PCI/endpoint/pci-test-howto.txt
index 730b70c73055..75f48c3bb191 100644
--- a/Documentation/PCI/endpoint/pci-test-howto.txt
+++ b/Documentation/PCI/endpoint/pci-test-howto.txt
@@ -49,7 +49,7 @@ configurable fields.
cache_line_size msi_interrupts subclass_code vendorid
deviceid progif_code subsys_id
-The pci endpoint function driver populates these entries with default values
+The PCI endpoint function driver populates these entries with default values
when the device is bound to the driver. The pci-epf-test driver populates
vendorid with 0xffff and interrupt_pin with 0x0001
diff --git a/Documentation/devicetree/bindings/pci/ti-pci.txt b/Documentation/devicetree/bindings/pci/ti-pci.txt
index b69dd7dbd29e..6a07c96227e0 100644
--- a/Documentation/devicetree/bindings/pci/ti-pci.txt
+++ b/Documentation/devicetree/bindings/pci/ti-pci.txt
@@ -14,7 +14,7 @@ HOST MODE
=========
- reg : Two register ranges as listed in the reg-names property
- reg-names : The first entry must be "ti-conf" for the TI specific registers
- The second entry must be "rc-dbics" for the designware pcie
+ The second entry must be "rc-dbics" for the DesignWare PCIe
registers
The third entry must be "config" for the PCIe configuration space
- interrupts : Two interrupt entries must be specified. The first one is for
@@ -39,7 +39,7 @@ DEVICE MODE
- interrupts : one interrupt entries must be specified for main interrupt.
- num-ib-windows : number of inbound address translation windows
- num-ob-windows : number of outbound address translation windows
- - ti,syscon-unaligned-access: phandle to the syscon dt node. The 1st argument
+ - ti,syscon-unaligned-access: phandle to the syscon DT node. The 1st argument
should contain the register offset within syscon
and the 2nd argument should contain the bit field
for setting the bit to enable unaligned
@@ -48,10 +48,10 @@ DEVICE MODE
Optional Property:
- gpios : Should be added if a gpio line is required to drive PERST# line
-NOTE: Two dt nodes may be added for each PCI controller; one for host
+NOTE: Two DT nodes may be added for each PCI controller; one for host
mode and another for device mode. So in order for PCI to
-work in host mode, EP mode dt node should be disabled and in order to PCI to
-work in EP mode, host mode dt node should be disabled. And host mode and EP
+work in host mode, EP mode DT node should be disabled and in order to PCI to
+work in EP mode, host mode DT node should be disabled. Host mode and EP
mode are mutually exclusive.
Example:
diff --git a/Documentation/misc-devices/pci-endpoint-test.txt b/Documentation/misc-devices/pci-endpoint-test.txt
index 438571898d27..4ebc3594b32c 100644
--- a/Documentation/misc-devices/pci-endpoint-test.txt
+++ b/Documentation/misc-devices/pci-endpoint-test.txt
@@ -1,7 +1,7 @@
Driver for PCI Endpoint Test Function
This driver should be used as a host side driver if the root complex is
-connected to a configurable pci endpoint running *pci_epf_test* function
+connected to a configurable PCI endpoint running *pci_epf_test* function
driver configured according to [1].
The "pci_endpoint_test" driver can be used to perform the following tests.
@@ -20,10 +20,10 @@ should be used to perform the above tests.
ioctl
-----
- PCITEST_BAR: Tests the BAR. The number of the BAR that has to be tested
+ PCITEST_BAR: Tests the BAR. The number of the BAR to be tested
should be passed as argument.
PCITEST_LEGACY_IRQ: Tests legacy IRQ
- PCITEST_MSI: Tests message signalled interrupts. The MSI number that has
+ PCITEST_MSI: Tests message signalled interrupts. The MSI number
to be tested should be passed as argument.
PCITEST_WRITE: Perform write tests. The size of the buffer should be passed
as argument.
diff --git a/MAINTAINERS b/MAINTAINERS
index 3c1b947811e2..15ed84389092 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9581,7 +9581,7 @@ F: include/linux/pci*
F: arch/x86/pci/
F: arch/x86/kernel/quirks.c
-PCI EP SUBSYSTEM
+PCI ENDPOINT SUBSYSTEM
M: Kishon Vijay Abraham I <kishon@ti.com>
L: linux-pci@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kishon/pci-endpoint.git
diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index 5f4f8f8ff1c2..09c10f426b64 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -424,7 +424,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
err = devm_request_irq(dev, pdev->irq, pci_endpoint_test_irqhandler,
IRQF_SHARED, DRV_MODULE_NAME, test);
if (err) {
- dev_err(dev, "failed to request irq\n");
+ dev_err(dev, "failed to request IRQ %d\n", pdev->irq);
goto err_disable_msi;
}
@@ -433,8 +433,8 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
pci_endpoint_test_irqhandler,
IRQF_SHARED, DRV_MODULE_NAME, test);
if (err)
- dev_err(dev, "failed to request irq for MSI %d\n",
- i + 1);
+ dev_err(dev, "failed to request IRQ %d for MSI %d\n",
+ pdev->irq + i, i + 1);
}
for (bar = BAR_0; bar <= BAR_5; bar++) {
diff --git a/drivers/pci/dwc/Kconfig b/drivers/pci/dwc/Kconfig
index 345ad67dca3c..b7e15526d676 100644
--- a/drivers/pci/dwc/Kconfig
+++ b/drivers/pci/dwc/Kconfig
@@ -21,8 +21,8 @@ config PCI_DRA7XX
help
Enables support for the PCIe controller in the DRA7xx SoC. There
are two instances of PCIe controller in DRA7xx. This controller can
- work either as EP or RC. In order to enable host specific features
- PCI_DRA7XX_HOST must be selected and in order to enable device
+ work either as EP or RC. In order to enable host-specific features
+ PCI_DRA7XX_HOST must be selected and in order to enable device-
specific features PCI_DRA7XX_EP must be selected. This uses
the Designware core.
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index 29cbe9a73b30..9ae9e59b2a74 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -43,7 +43,7 @@ static int devm_pci_epc_match(struct device *dev, void *res, void *match_data)
}
/**
- * pci_epc_put() - release the pci endpoint controller
+ * pci_epc_put() - release the PCI endpoint controller
* @epc: epc returned by pci_epc_get()
*
* release the refcount the caller obtained by invoking pci_epc_get()
@@ -59,7 +59,7 @@ void pci_epc_put(struct pci_epc *epc)
EXPORT_SYMBOL_GPL(pci_epc_put);
/**
- * pci_epc_get() - get the pci endpoint controller
+ * pci_epc_get() - get the PCI endpoint controller
* @epc_name: device name of the endpoint controller
*
* Invoke to get struct pci_epc * corresponding to the device name of the
@@ -225,11 +225,11 @@ int pci_epc_set_msi(struct pci_epc *epc, u8 interrupts)
EXPORT_SYMBOL_GPL(pci_epc_set_msi);
/**
- * pci_epc_unmap_addr() - unmap cpu address from pci address
+ * pci_epc_unmap_addr() - unmap CPU address from PCI address
* @epc: the EPC device on which address is allocated
* @phys_addr: physical address of the local system
*
- * Invoke to unmap the cpu address from pci address.
+ * Invoke to unmap the CPU address from PCI address.
*/
void pci_epc_unmap_addr(struct pci_epc *epc, phys_addr_t phys_addr)
{
@@ -248,13 +248,13 @@ void pci_epc_unmap_addr(struct pci_epc *epc, phys_addr_t phys_addr)
EXPORT_SYMBOL_GPL(pci_epc_unmap_addr);
/**
- * pci_epc_map_addr() - map cpu address to pci address
+ * pci_epc_map_addr() - map CPU address to PCI address
* @epc: the EPC device on which address is allocated
* @phys_addr: physical address of the local system
- * @pci_addr: pci address to which the physical address should be mapped
+ * @pci_addr: PCI address to which the physical address should be mapped
* @size: the size of the allocation
*
- * Invoke to map cpu address with pci address.
+ * Invoke to map CPU address with PCI address.
*/
int pci_epc_map_addr(struct pci_epc *epc, phys_addr_t phys_addr,
u64 pci_addr, size_t size)
@@ -279,7 +279,7 @@ EXPORT_SYMBOL_GPL(pci_epc_map_addr);
/**
* pci_epc_clear_bar() - reset the BAR
* @epc: the EPC device for which the BAR has to be cleared
- * @bar: the bar number that has to be reset
+ * @bar: the BAR number that has to be reset
*
* Invoke to reset the BAR of the endpoint device.
*/
@@ -302,7 +302,7 @@ EXPORT_SYMBOL_GPL(pci_epc_clear_bar);
/**
* pci_epc_set_bar() - configure BAR in order for host to assign PCI addr space
* @epc: the EPC device on which BAR has to be configured
- * @bar: the bar number that has to be configured
+ * @bar: the BAR number that has to be configured
* @size: the size of the addr space
* @flags: specify memory allocation/io allocation/32bit address/64 bit address
*
@@ -358,13 +358,13 @@ int pci_epc_write_header(struct pci_epc *epc, struct pci_epf_header *header)
EXPORT_SYMBOL_GPL(pci_epc_write_header);
/**
- * pci_epc_add_epf() - bind pci endpoint function to an endpoint controller
+ * pci_epc_add_epf() - bind PCI endpoint function to an endpoint controller
* @epc: the EPC device to which the endpoint function should be added
* @epf: the endpoint function to be added
*
* A PCI endpoint device can have one or more functions. In the case of PCIe,
- * the specification allows upto 8 PCIe endpoint functions. Invoke
- * pci_epc_add_epf() to add a pci endpoint function to an endpoint controller.
+ * the specification allows up to 8 PCIe endpoint functions. Invoke
+ * pci_epc_add_epf() to add a PCI endpoint function to an endpoint controller.
*/
int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf)
{
@@ -392,11 +392,11 @@ int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf)
EXPORT_SYMBOL_GPL(pci_epc_add_epf);
/**
- * pci_epc_remove_epf() - remove pci endpoint function from endpoint controller
+ * pci_epc_remove_epf() - remove PCI endpoint function from endpoint controller
* @epc: the EPC device from which the endpoint function should be removed
* @epf: the endpoint function to be removed
*
- * Invoke to remove pci endpoint function from the endpoint controller.
+ * Invoke to remove PCI endpoint function from the endpoint controller.
*/
void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf)
{
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index 9ec1639ef749..92db7dcd911c 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -87,7 +87,7 @@ EXPORT_SYMBOL_GPL(pci_epf_bind);
/**
* pci_epf_free_space() - free the allocated PCI EPF register space
* @addr: the virtual address of the PCI EPF register space
- * @bar: the bar number corresponding to the register space
+ * @bar: the BAR number corresponding to the register space
*
* Invoke to free the allocated PCI EPF register space.
*/
@@ -109,7 +109,7 @@ EXPORT_SYMBOL_GPL(pci_epf_free_space);
/**
* pci_epf_alloc_space() - allocate memory for the PCI EPF register space
* @size: the size of the memory that has to be allocated
- * @bar: the bar number corresponding to the allocated register space
+ * @bar: the BAR number corresponding to the allocated register space
*
* Invoke to allocate memory for the PCI EPF register space.
*/
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index d6eb32291462..af5edbf3eea3 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -27,8 +27,8 @@ enum pci_epc_irq_type {
* @write_header: ops to populate configuration space header
* @set_bar: ops to configure the BAR
* @clear_bar: ops to reset the BAR
- * @map_addr: ops to map cpu address to pci address
- * @unmap_addr: ops to unmap cpu address and pci address
+ * @map_addr: ops to map CPU address to PCI address
+ * @unmap_addr: ops to unmap CPU address and PCI address
* @set_msi: ops to set the requested number of MSI interrupts in the MSI
* capability register
* @get_msi: ops to get the number of MSI interrupts allocated by the RC from
@@ -58,9 +58,9 @@ struct pci_epc_ops {
/**
* struct pci_epc_mem - address space of the endpoint controller
- * @phys_base: physical base address of the pci address space
- * @size: the size of the pci address space
- * @bitmap: bitmap to manage the pci address space
+ * @phys_base: physical base address of the PCI address space
+ * @size: the size of the PCI address space
+ * @bitmap: bitmap to manage the PCI address space
* @pages: number of bits representing the address region
*/
struct pci_epc_mem {
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
index 5ff2c5a592c3..0d529cb90143 100644
--- a/include/linux/pci-epf.h
+++ b/include/linux/pci-epf.h
@@ -38,7 +38,7 @@ enum pci_barno {
* struct pci_epf_header - represents standard configuration header
* @vendorid: identifies device manufacturer
* @deviceid: identifies a particular device
- * @revid: specifies a device specific revision identifier
+ * @revid: specifies a device-specific revision identifier
* @progif_code: identifies a specific register-level programming interface
* @subclass_code: identifies more specifically the function of the device
* @baseclass_code: broadly classifies the type of function the device performs
@@ -115,11 +115,11 @@ struct pci_epf_bar {
* @name: the name of the PCI EPF device
* @header: represents standard configuration header
* @bar: represents the BAR of EPF device
- * @msi_interrupts: number of msi interrupts required by this function
+ * @msi_interrupts: number of MSI interrupts required by this function
* @func_no: unique function number within this endpoint device
* @epc: the EPC device to which this EPF device is bound
* @driver: the EPF driver to which this EPF device is bound
- * @list: to add pci_epf as a list of pci endpoint functions to pci_epc
+ * @list: to add pci_epf as a list of PCI endpoint functions to pci_epc
*/
struct pci_epf {
struct device dev;
diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c
index 39b5b0ba569e..ad54a58d7dda 100644
--- a/tools/pci/pcitest.c
+++ b/tools/pci/pcitest.c
@@ -170,7 +170,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"usage: %s [options]\n"
"Options:\n"
- "\t-D <dev> pci endpoint test device {default: /dev/pci-endpoint-test.0}\n"
+ "\t-D <dev> PCI endpoint test device {default: /dev/pci-endpoint-test.0}\n"
"\t-b <bar num> BAR test (bar number between 0..5)\n"
"\t-m <msi num> MSI test (msi number between 1..32)\n"
"\t-r Read buffer test\n"
--- cl.orig 2017-04-04 15:26:34.555152663 -0500
+++ cl.new 2017-04-04 15:26:47.575278312 -0500
@@ -1,67 +1,67 @@
-commit 485847badf93
+commit 2f81b96ef43e
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:15:20 2017 +0530
ARM: DRA7: clockdomain: Change the CLKTRCTRL of CM_PCIE_CLKSTCTRL to SW_WKUP
- The PCIe programming sequence in TRM suggests CLKSTCTRL of PCIe should
- be set to SW_WKUP. There are no issues when CLKSTCTRL is set to HW_AUTO
- in RC mode. However in EP mode, the host system is not able to access the
+ The PCIe programming sequence in TRM suggests CLKSTCTRL of PCIe should be
+ set to SW_WKUP. There are no issues when CLKSTCTRL is set to HW_AUTO in RC
+ mode. However in EP mode, the host system is not able to access the
MEMSPACE and setting the CLKSTCTRL to SW_WKUP fixes it.
Acked-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-commit ea4a8033fd42
+commit 4d53ed89fe50
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:15:19 2017 +0530
- MAINTAINERS: add PCI EP maintainer
+ MAINTAINERS: Add PCI Endpoint maintainer
- Add maintainer for the newly introduced PCI EP framework.
+ Add maintainer for the newly introduced PCI Endpoint framework.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-commit 9c3eb6b9db09
+commit a11812c0dacc
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:15:18 2017 +0530
Documentation: PCI: Add userguide for PCI endpoint test function
- Add documentation to help users use pci-epf-test function driver
- and pci_endpoint_test host driver for testing PCI.
+ Add documentation to help users use pci-epf-test function driver and
+ pci_endpoint_test host driver for testing PCI.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-commit ce58c0dca0fc
+commit c7ce6959f0a5
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:15:17 2017 +0530
tools: PCI: Add sample test script to invoke pcitest
- Add a simple test script that invokes the pcitest userspace tool
- to perform all the PCI endpoint tests (BAR tests, interrupt tests,
- read tests, write tests and copy tests).
+ Add a simple test script that invokes the pcitest userspace tool to perform
+ all the PCI endpoint tests (BAR tests, interrupt tests, read tests, write
+ tests and copy tests).
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-commit fdc27ef5bde2
+commit f9ee26a038d8
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:15:16 2017 +0530
tools: PCI: Add a userspace tool to test PCI endpoint
- Add a userspace tool to invoke the ioctls exposed by the
- PCI endpoint test driver to perform various PCI tests.
+ Add a userspace tool to invoke the ioctls exposed by the PCI endpoint test
+ driver to perform various PCI tests.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-commit d323b479a02e
+commit fea31fd3cf56
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:15:15 2017 +0530
@@ -72,21 +72,21 @@
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-commit d26ec30392dd
+commit bedcd782937f
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:15:14 2017 +0530
- misc: Add host side pci driver for pci test function device
+ misc: Add host side PCI driver for PCI test function device
- Add PCI endpoint test driver that can verify base address
- register, legacy interrupt/MSI interrupt and read/write/copy
- buffers between host and device. The corresponding pci-epf-test
- function driver should be used on the EP side.
+ Add PCI endpoint test driver that can verify base address register, legacy
+ interrupt/MSI interrupt and read/write/copy buffers between host and
+ device. The corresponding pci-epf-test function driver should be used on
+ the EP side.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-commit 5b43200ddaa7
+commit 8066f3c52feb
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:15:13 2017 +0530
@@ -98,115 +98,115 @@
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-commit a5090d8e9668
+commit 25eef24289ee
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:15:12 2017 +0530
- dt-bindings: PCI: dra7xx: Add dt bindings to enable unaligned access
+ dt-bindings: PCI: dra7xx: Add DT bindings to enable unaligned access
- Update device tree binding documentation of TI's dra7xx PCI
- controller to include property for enabling unaligned mem access.
+ Update device tree binding documentation of TI's dra7xx PCI controller to
+ include property for enabling unaligned mem access.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-commit 3f080640d53f
+commit ebe506162817
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:15:11 2017 +0530
PCI: dwc: dra7xx: Workaround for errata id i870
- According to errata i870, access to the PCIe slave port
- that are not 32-bit aligned will result in incorrect mapping
- to TLP Address and Byte enable fields.
+ According to errata i870, access to the PCIe slave port that are not 32-bit
+ aligned will result in incorrect mapping to TLP Address and Byte enable
+ fields.
Accessing non 32-bit aligned data causes incorrect data in the target
- buffer if memcpy is used. Implement the workaround for this
- errata here.
+ buffer if memcpy is used. Implement the workaround for this errata here.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-commit 24365ea32418
+commit 9ff4601c7765
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:15:10 2017 +0530
dt-bindings: mfd: syscon: Add documentation for #syscon-cells property
- Add documentation for the optional #syscon-cells property to determine
- the number of cells that should be given in the phandle while
- referencing the syscon-node.
+ Add documentation for the optional #syscon-cells property to determine the
+ number of cells that should be given in the phandle while referencing the
+ syscon-node.
Suggested-by: Rob Herring <robh@kernel.org>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-commit 27cb5fde6551
+commit 1329cf15fe87
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:15:09 2017 +0530
- dt-bindings: PCI: dra7xx: Add dt bindings for pci dra7xx EP mode
+ dt-bindings: PCI: dra7xx: Add DT bindings for PCI dra7xx EP mode
- Add device tree binding documentation for pci dra7xx EP mode.
+ Add device tree binding documentation for PCI dra7xx EP mode.
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-commit e8be32886fd1
+commit 6259ce5e8f4a
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:15:08 2017 +0530
PCI: dwc: dra7xx: Add EP mode support
- The PCIe controller integrated in dra7xx SoCs is capable of operating
- in endpoint mode. Add endpoint mode support to dra7xx driver.
+ The PCIe controller integrated in dra7xx SoCs is capable of operating in
+ endpoint mode. Add endpoint mode support to dra7xx driver.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-commit 3138c72f71f2
+commit 9567c35d6566
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:15:07 2017 +0530
- PCI: dwc: dra7xx: Facilitate wrapper and msi interrupts to be enabled independently
+ PCI: dwc: dra7xx: Facilitate wrapper and MSI interrupts to be enabled independently
- No functional change. Split dra7xx_pcie_enable_interrupts into
- dra7xx_pcie_enable_wrapper_interrupts and dra7xx_pcie_enable_msi_interrupts
- so that wrapper interrupts and msi interrupts can be enabled independently.
- This is in preparation for adding EP mode support to dra7xx driver since
- EP mode doesn't have to enable msi_interrupts.
+ No functional change. Split dra7xx_pcie_enable_interrupts() into
+ dra7xx_pcie_enable_wrapper_interrupts() and
+ dra7xx_pcie_enable_msi_interrupts() so that wrapper interrupts and MSI
+ interrupts can be enabled independently. This is in preparation for adding
+ EP mode support to dra7xx driver since EP mode doesn't have to enable
+ msi_interrupts.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-commit 8ba73ff9284c
+commit c10abab4c7ca
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:15:06 2017 +0530
- dt-bindings: PCI: Add dt bindings for pci designware EP mode
+ dt-bindings: PCI: Add DT bindings for PCI designware EP mode
- Add device tree binding documentation for pci designware EP mode.
+ Add device tree binding documentation for PCI designware EP mode.
- Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+ Acked-by: Rob Herring <robh@kernel.org>
-commit b6251498f9bc
+commit 98d63c77d6a0
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:15:05 2017 +0530
PCI: dwc: designware: Add EP mode support
- Add endpoint mode support to designware driver. This uses the
- EP Core layer introduced recently to add endpoint mode support.
- *Any* function driver can now use this designware device
- in order to achieve the EP functionality.
+ Add endpoint mode support to designware driver. This uses the EP Core layer
+ introduced recently to add endpoint mode support. *Any* function driver
+ can now use this designware device in order to achieve the EP
+ functionality.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-commit 86d768a59594
+commit 36ecd387d736
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:15:04 2017 +0530
@@ -218,71 +218,70 @@
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-commit 41c1e46c71b9
+commit b8116f7d8cec
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:15:03 2017 +0530
PCI: endpoint: functions: Add an EP function to test PCI
- Adds a new endpoint function driver (to program the virtual
- test device) making use of the EP-core library.
+ Adds a new endpoint function driver (to program the virtual test device)
+ making use of the EP-core library.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-commit 05e78b3dee04
+commit 1a5946105d8d
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:15:02 2017 +0530
- Documentation: PCI: Add specification for the *pci test* function device
+ Documentation: PCI: Add specification for the *PCI test* function device
- Add specification for the *pci test* virtual function device. The endpoint
- function driver and the host pci driver should be created based on this
+ Add specification for the *PCI test* virtual function device. The endpoint
+ function driver and the host PCI driver should be created based on this
specification.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-commit 5904951f2a07
+commit f24b3959ecbc
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:15:01 2017 +0530
PCI: endpoint: Create configfs entry for EPC device and EPF driver
- Invoke API's provided by pci-ep-cfs to create configfs entry for
- every EPC device and EPF driver to help users in creating EPF device
- and binding the EPF device to the EPC device.
+ Invoke APIs provided by pci-ep-cfs to create configfs entry for every EPC
+ device and EPF driver to help users in creating EPF device and binding the
+ EPF device to the EPC device.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-commit c782a62981cd
+commit afbfe69d612b
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:15:00 2017 +0530
- Documentation: PCI: Guide to use pci endpoint configfs
+ Documentation: PCI: Guide to use PCI endpoint configfs
- Add Documentation to help users use pci endpoint to configure
- pci endpoint function and to bind the endpoint function
- with endpoint controller.
+ Add Documentation to help users use PCI endpoint to configure PCI endpoint
+ function and to bind the endpoint function with endpoint controller.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-commit 9b703e4292d1
+commit 7049ceb16f8d
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:14:59 2017 +0530
PCI: endpoint: Introduce configfs entry for configuring EP functions
Introduce a new configfs entry to configure the EP function (like
- configuring the standard configuration header entries) and to
- bind the EP function with EP controller.
+ configuring the standard configuration header entries) and to bind the EP
+ function with EP controller.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-commit d03d46a9d9fc
+commit e025fb44364f
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:14:58 2017 +0530
@@ -294,18 +293,17 @@
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-commit ff50e9e4a512
+commit 79e4effb2a36
Author: Kishon Vijay Abraham I <kishon@ti.com>
Date: Mon Mar 27 15:14:57 2017 +0530
PCI: endpoint: Add EP core layer to enable EP controller and EP functions
- Introduce a new EP core layer in order to support endpoint functions
- in linux kernel. This comprises of EPC library
- (Endpoint Controller Library) and EPF library (Endpoint
- Function Library). EPC library implements functions that is specific
- to an endpoint controller and EPF library implements functions
- that is specific to an endpoint function.
+ Introduce a new EP core layer in order to support endpoint functions in
+ linux kernel. This comprises the EPC library (Endpoint Controller Library)
+ and EPF library (Endpoint Function Library). EPC library implements
+ functions specific to an endpoint controller and EPF library implements
+ functions specific to an endpoint function.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
^ permalink raw reply related
* Re: Re: [PATCH v2 1/6] clk: sunxi-ng: Add sun4i/sun7i CCU driver
From: Priit Laes @ 2017-04-04 20:09 UTC (permalink / raw)
To: Maxime Ripard
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng, Russell King,
Chen-Yu Tsai, Mark Rutland, Rob Herring, Stephen Boyd,
Michael Turquette, Philipp Zabel
In-Reply-To: <20170327075438.cw3d6s7zyeemenwr@lukather>
On Mon, Mar 27, 2017 at 09:54:38AM +0200, Maxime Ripard wrote:
> Hi,
>
> Thanks a lot for working on this.
>
> On Sun, Mar 26, 2017 at 08:20:16PM +0300, Priit Laes wrote:
> > Introduce a clock controller driver for sun4i A10 and sun7i A20
> > series SoCs.
> >
> > Signed-off-by: Priit Laes <plaes-q/aMd4JkU83YtjvyW6yDsg@public.gmane.org>
> > ---
> > drivers/clk/sunxi-ng/Kconfig | 13 +-
> > drivers/clk/sunxi-ng/Makefile | 1 +-
> > drivers/clk/sunxi-ng/ccu-sunxi-a10-a20.c | 1532 ++++++++++++++++++-
> > drivers/clk/sunxi-ng/ccu-sunxi-a10-a20.h | 59 +-
> > include/dt-bindings/clock/sunxi-a10-a20-ccu.h | 208 ++-
> > include/dt-bindings/reset/sunxi-a10-a20-ccu.h | 66 +-
>
> I'm not too fond of those sunxi-<all the SoCs supported>. We're not
> doing that for any other driver, I don't really know why this has
> became a trend lately.
>
> You can call them ccu-sun4i-a10.h, and it will work just fine.
OK, will do!
>
> > +/* Not documented on A10 */
> > +static SUNXI_CCU_GATE(pll_periph_sata_clk, "pll-periph-sata", "pll-periph",
> > + 0x028, BIT(14), 0);
>
> The rate doesn't come from pll-periph directly, does it?
So it uses hosc (24MHz parent clock) instead of pll-periph?
>
> > +#define SUN4I_AHB_REG 0x054
> > +static struct ccu_mux cpu_clk = {
> > + .mux = {
> > + .shift = 16,
> > + .width = 2,
> > + .fixed_predivs = cpu_predivs,
> > + .n_predivs = ARRAY_SIZE(cpu_predivs),
> > + },
> > + .common = {
> > + .reg = 0x054,
>
> Why did you define this one, even though you don't seem to be using it
> anywhere?
Leftover from when I also included A10 support.
>
> > +static const char *const ahb_parents[] = { "axi", "pll-periph",
> > + "pll-periph-2x" };
> > +static const struct ccu_mux_fixed_prediv ahb_predivs[] = {
> > + { .index = 2, .div = 2, },
> > +};
>
> This seems to be only true for the A20, and not the A10.
>
> Are you sure here? The pll-periph-2x seem to be only used in the MBUS
> clock in our current code.
Nope...
>
> And then, using pll-periph-2x, and then dividing it by 2 just gives us
> pll-periph, which is also our previous parent :)
...will investigate.
>
> > +/* Undocumented on A10 */
> > +static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0",
> > + 0x088, 8, 3, 0);
> > +/* Undocumented on A10 */
> > +static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0",
> > + 0x088, 20, 3, 0);
>
> The A10 doesn't have them.
Are you sure? Although, they weren't listed in datasheet, they are defined
in the sun4i-a10.dtsi:
mmc0_clk: clk@01c20088 {
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c20088 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "mmc0",
"mmc0_output",
"mmc0_sample";
};
> > +/* TODO: Check whether A10 actually supports osc32k as 4th parent? */
> > +static const char *const ir_parents_sun4i[] = { "hosc", "pll-periph",
> > + "pll-ddr-other" };
>
> What does the BSP say about this?
sun7i datasheet mentions osc32k, but BSP code for sun4i, sun5i and sun7i
is identical and supports only 3 first parents without osc32k.
> > +/* Undocumented on A10 */
> > +static SUNXI_CCU_MUX_WITH_GATE(spdif_clk, "spdif", audio_parents,
> > + 0x0c0, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
>
> This doesn't seem to exist at all on the A10
Wasn't listed in datasheet, but it's in BSP and also in sun4i-a10.dtsi:
spdif_clk: clk@01c200c0 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod1-clk";
reg = <0x01c200c0 0x4>;
clocks = <&pll2 SUN4I_A10_PLL2_8X>,
<&pll2 SUN4I_A10_PLL2_4X>,
<&pll2 SUN4I_A10_PLL2_2X>,
<&pll2 SUN4I_A10_PLL2_1X>;
clock-output-names = "spdif";
};
>
> > +/*
> > + * TODO: SATA clock also supports external clock as parent via BIT(24)
> > + * The external clock is probably an optional crystal or oscillator
> > + * that can be connected to the SATA-CLKM / SATA-CLKP pins.
> > + */
> > +static SUNXI_CCU_GATE(sata_clk, "sata", "pll-periph-sata",
> > + 0x0c8, BIT(31), 0);
>
> The rate won't be good here either. This is supposed to be 100MHz.
Hmm.. I tested SATA with Cubietruck. Or what do you mean?
> > +static const char *const csi_isp_parents[] = { "pll-video0", "pll-ve",
> > + "pll-ddr-other", "pll-sata" };
> > +
> > +static SUNXI_CCU_M_WITH_MUX_GATE(csi_isp_clk, "csi-isp",
> > + csi_isp_parents,
> > + 0x120, 0, 4, 24, 2, BIT(31), 0);
>
> We've been calling it sclk in the other SoC iirc. Any particular
> reason to call it differently?
It's called ISP in BSP and A10 manual.
In A20 it's indeed Special Clock Register (SCLK).
> > +static const char *const out_parents[] = { "hosc", "osc32k", "hosc" };
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(out_a_clk, "out-a", out_parents,
> > + 0x1f0, 8, 5, 20, 2, 24, 2, BIT(31), 0);
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(out_b_clk, "out-b", out_parents,
> > + 0x1f4, 8, 5, 20, 2, 24, 2, BIT(31), 0);
>
> There's a fixed pre-divider on the first hosc of 750.
Nice catch.
So it should be something like this:
[snip]
static const char *const out_parents[] = { "osc24M", "osc32k", "osc24M" };
static const struct ccu_mux_fixed_prediv out_prediv = {
.index = 0, .div = 750
};
static struct ccu_mp out_a_clk = {
.enable = BIT(31),
.m = _SUNXI_CCU_DIV(8, 5),
.p = _SUNXI_CCU_DIV(20, 2),
.mux = {
.shift = 24,
.width = 2,
.fixed_predivs = &out_prediv,
.n_predivs = ARRAY_SIZE(out_prediv),
},
.common = {
.reg = 0x1f0,
.features = CCU_FEATURE_FIXED_PREDIV,
.hw.init = CLK_HW_INIT_PARENTS("out-a",
out_parents,
&ccu_mp_ops,
0),
},
};
[/snip]
> > +static void init_clocks(void __iomem *reg)
> > +{
> > + u32 val;
> > +
> > + /* Force the PLL-Audio-1x divider to 4 */
> > + val = readl(reg + SUN4I_PLL_AUDIO_REG);
> > + val &= ~GENMASK(19, 16);
> > + writel(val | (3 << 16), reg + SUN4I_PLL_AUDIO_REG);
> > +
> > + /* Use PLL6 as parent for AHB */
> > + val = readl(reg + SUN4I_AHB_REG);
> > + val &= ~GENMASK(7, 6);
> > + writel(val | (2 << 6), reg + SUN4I_AHB_REG);
>
> Keeping some kind of comment similar to what was in the DT would be
> great, otherwise we lose *why* we need to do so.
OK
> > +}
> > +
> > +static void __init sun4i_a10_ccu_setup(struct device_node *node)
> > +{
> > + void __iomem *reg;
> > +
> > + reg = of_io_request_and_map(node, 0, of_node_full_name(node));
> > + if (IS_ERR(reg)) {
> > + pr_err("%s: Could not map the clock registers\n",
> > + of_node_full_name(node));
> > + return;
> > + }
> > +
> > + init_clocks(reg);
> > +
> > + sunxi_ccu_probe(node, reg, &sun4i_a10_ccu_desc);
>
> Can't you move the request_and_map / probe in the common function?
Will do.
> > +#ifndef _DT_BINDINGS_CLK_SUNXI_A10_A20_H_
> > +#define _DT_BINDINGS_CLK_SUNXI_A10_A20_H_
> > +
> > +#define CLK_HOSC 1
> > +#define CLK_PLL_PERIPH_SATA 16
>
> That one looks suspicious. I don't see why we would need the PLL,
> while we have a perfectly functional SATA clock below. Have you tried
> gating the bit31 of the register 0xc8 to see if it has any impact?
Will try it...
> Thanks!
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com
>
> --
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
> For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply
* Re: [PATCH 2/2] ARM: dts: keystone: Add minimum support for K2G ICE evm
From: Franklin S Cooper Jr @ 2017-04-04 20:04 UTC (permalink / raw)
To: Rob Herring; +Cc: linux-arm-kernel, devicetree, linux, linux-kernel, ssantosh
In-Reply-To: <20170403162708.sf4ovwu3wm2tlyqh@rob-hp-laptop>
On 04/03/2017 11:27 AM, Rob Herring wrote:
> On Thu, Mar 30, 2017 at 10:29:07AM -0500, Franklin S Cooper Jr wrote:
>> Add barebones dts support for TI's K2G Industrial Communication Engine evm.
>> This dts allows the board to boot using a ram based filesystem.
>>
>> Signed-off-by: Franklin S Cooper Jr <fcooper@ti.com>
>> ---
>> arch/arm/boot/dts/Makefile | 3 ++-
>> arch/arm/boot/dts/keystone-k2g-ice.dts | 42 ++++++++++++++++++++++++++++++++++
>> 2 files changed, 44 insertions(+), 1 deletion(-)
>> create mode 100644 arch/arm/boot/dts/keystone-k2g-ice.dts
>>
>> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
>> index 0118084..01a98f1 100644
>> --- a/arch/arm/boot/dts/Makefile
>> +++ b/arch/arm/boot/dts/Makefile
>> @@ -193,7 +193,8 @@ dtb-$(CONFIG_ARCH_KEYSTONE) += \
>> keystone-k2hk-evm.dtb \
>> keystone-k2l-evm.dtb \
>> keystone-k2e-evm.dtb \
>> - keystone-k2g-evm.dtb
>> + keystone-k2g-evm.dtb \
>> + keystone-k2g-ice.dtb
>> dtb-$(CONFIG_MACH_KIRKWOOD) += \
>> kirkwood-b3.dtb \
>> kirkwood-blackarmor-nas220.dtb \
>> diff --git a/arch/arm/boot/dts/keystone-k2g-ice.dts b/arch/arm/boot/dts/keystone-k2g-ice.dts
>> new file mode 100644
>> index 0000000..9ab5f42
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/keystone-k2g-ice.dts
>> @@ -0,0 +1,42 @@
>> +/*
>> + * Device Tree Source for K2G Industrial Communication Engine EVM
>> + *
>> + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + *
>> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
>> + * kind, whether express or implied; without even the implied warranty
>> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + * GNU General Public License for more details.
>
> You can Use SPDX tags here.
>
>> + */
>> +/dts-v1/;
>> +
>> +#include "keystone-k2g.dtsi"
>> +
>> +/ {
>> + compatible = "ti,k2g-ice", "ti,k2g", "ti,keystone";
>> + model = "Texas Instruments K2G Industrial Communication EVM";
>> +
>> + memory {
>
> memory@800000000
Adding this causes the dtb compiler to issue the below warning:
Warning (reg_format): "reg" property in /memory has invalid length (8
bytes) (#address-cells == 2, #size-cells == 2)
I don't quite understand what causes this to be triggered only when the
unit address is included. I tried adding the unit address to the memory
node on other dts/dtsi files and compiled it and I get similar errors.
Looking at scripts/dtc/checks.c its a bit unclear how the value for
prop->val.len is set. But I'm curious if the check has issues with 64
bit addressing? Note it says the property's length is 8 bytes while the
entry length is 16 ((addr_cells + size_cells) * sizeof(cell_t))
>
> unless that gives you bootloader(s) problems.
>
>> + device_type = "memory";
>> + reg = <0x00000008 0x00000000 0x00000000 0x20000000>;
>> + };
>> +};
>> +
>> +&k2g_pinctrl {
>> + uart0_pins: pinmux_uart0_pins {
>> + pinctrl-single,pins = <
>> + K2G_CORE_IOPAD(0x11cc) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* uart0_rxd.uart0_rxd */
>> + K2G_CORE_IOPAD(0x11d0) (BUFFER_CLASS_B | PIN_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
>> + >;
>> + };
>> +};
>> +
>> +&uart0 {
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&uart0_pins>;
>> + status = "okay";
>> +};
>> --
>> 2.10.0
>>
^ permalink raw reply
* Re: [PATCH v3 04/11] drm/sun4i: abstract the layer type
From: Icenowy Zheng @ 2017-04-04 19:53 UTC (permalink / raw)
To: Sean Paul
Cc: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
linux-clk-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20170404192837.pvlhwyeut45vg2wg@art_vandelay>
在 2017年04月05日 03:28, Sean Paul 写道:
> On Thu, Mar 30, 2017 at 03:46:06AM +0800, Icenowy Zheng wrote:
>> As we are going to add support for the Allwinner DE2 Mixer in sun4i-drm
>> driver, we will finally have two types of layer.
>>
>> Abstract the layer type to void * and a ops struct, which contains the
>> only function used by crtc -- get the drm_plane struct of the layer.
>>
>> Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
>> ---
>> Refactored patch in v3.
>>
>> drivers/gpu/drm/sun4i/sun4i_crtc.c | 19 +++++++++++--------
>> drivers/gpu/drm/sun4i/sun4i_crtc.h | 3 ++-
>> drivers/gpu/drm/sun4i/sun4i_layer.c | 19 ++++++++++++++++++-
>> drivers/gpu/drm/sun4i/sun4i_layer.h | 2 +-
>> drivers/gpu/drm/sun4i/sunxi_layer.h | 17 +++++++++++++++++
>> 5 files changed, 49 insertions(+), 11 deletions(-)
>> create mode 100644 drivers/gpu/drm/sun4i/sunxi_layer.h
>>
>> diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c
>> index 3c876c3a356a..33854ee7f636 100644
>> --- a/drivers/gpu/drm/sun4i/sun4i_crtc.c
>> +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c
>> @@ -29,6 +29,7 @@
>> #include "sun4i_crtc.h"
>> #include "sun4i_drv.h"
>> #include "sun4i_layer.h"
>> +#include "sunxi_layer.h"
>> #include "sun4i_tcon.h"
>>
>> static void sun4i_crtc_atomic_begin(struct drm_crtc *crtc,
>> @@ -149,7 +150,7 @@ struct sun4i_crtc *sun4i_crtc_init(struct drm_device *drm,
>> scrtc->tcon = tcon;
>>
>> /* Create our layers */
>> - scrtc->layers = sun4i_layers_init(drm, scrtc->backend);
>> + scrtc->layers = (void **)sun4i_layers_init(drm, scrtc);
>> if (IS_ERR(scrtc->layers)) {
>> dev_err(drm->dev, "Couldn't create the planes\n");
>> return NULL;
>> @@ -157,14 +158,15 @@ struct sun4i_crtc *sun4i_crtc_init(struct drm_device *drm,
>>
>> /* find primary and cursor planes for drm_crtc_init_with_planes */
>> for (i = 0; scrtc->layers[i]; i++) {
>> - struct sun4i_layer *layer = scrtc->layers[i];
>> + void *layer = scrtc->layers[i];
>> + struct drm_plane *plane = scrtc->layer_ops->get_plane(layer);
>>
>> - switch (layer->plane.type) {
>> + switch (plane->type) {
>> case DRM_PLANE_TYPE_PRIMARY:
>> - primary = &layer->plane;
>> + primary = plane;
>> break;
>> case DRM_PLANE_TYPE_CURSOR:
>> - cursor = &layer->plane;
>> + cursor = plane;
>> break;
>> default:
>> break;
>> @@ -190,10 +192,11 @@ struct sun4i_crtc *sun4i_crtc_init(struct drm_device *drm,
>> /* Set possible_crtcs to this crtc for overlay planes */
>> for (i = 0; scrtc->layers[i]; i++) {
>> uint32_t possible_crtcs = BIT(drm_crtc_index(&scrtc->crtc));
>> - struct sun4i_layer *layer = scrtc->layers[i];
>> + void *layer = scrtc->layers[i];
>> + struct drm_plane *plane = scrtc->layer_ops->get_plane(layer);
>>
>> - if (layer->plane.type == DRM_PLANE_TYPE_OVERLAY)
>> - layer->plane.possible_crtcs = possible_crtcs;
>> + if (plane->type == DRM_PLANE_TYPE_OVERLAY)
>> + plane->possible_crtcs = possible_crtcs;
>> }
>>
>> return scrtc;
>> diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.h b/drivers/gpu/drm/sun4i/sun4i_crtc.h
>> index 230cb8f0d601..a4036ee44cf8 100644
>> --- a/drivers/gpu/drm/sun4i/sun4i_crtc.h
>> +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.h
>> @@ -19,7 +19,8 @@ struct sun4i_crtc {
>>
>> struct sun4i_backend *backend;
>> struct sun4i_tcon *tcon;
>> - struct sun4i_layer **layers;
>> + void **layers;
>> + const struct sunxi_layer_ops *layer_ops;
>
> I think you should probably take a different approach to abstract the layer
> type. How about creating
>
> struct sunxi_layer {
> struct drm_plane plane;
> }
>
> base and then subclassing that for sun4i and sun8i? By doing this you can avoid
> the nasty casting and you can also get rid of the get_plane() hook and
> layer_ops.
For the situation that using ** things are easily to get weird.
>
> Sean
>
>
>
>> };
>>
>> static inline struct sun4i_crtc *drm_crtc_to_sun4i_crtc(struct drm_crtc *crtc)
>> diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c
>> index f26bde5b9117..bc4a70d6968b 100644
>> --- a/drivers/gpu/drm/sun4i/sun4i_layer.c
>> +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
>> @@ -16,7 +16,9 @@
>> #include <drm/drmP.h>
>>
>> #include "sun4i_backend.h"
>> +#include "sun4i_crtc.h"
>> #include "sun4i_layer.h"
>> +#include "sunxi_layer.h"
>>
>> struct sun4i_plane_desc {
>> enum drm_plane_type type;
>> @@ -100,6 +102,17 @@ static const struct sun4i_plane_desc sun4i_backend_planes[] = {
>> },
>> };
>>
>> +static struct drm_plane *sun4i_layer_get_plane(void *layer)
>> +{
>> + struct sun4i_layer *sun4i_layer = layer;
>> +
>> + return &sun4i_layer->plane;
>> +}
>> +
>> +static const struct sunxi_layer_ops layer_ops = {
>> + .get_plane = sun4i_layer_get_plane,
>> +};
>> +
>> static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm,
>> struct sun4i_backend *backend,
>> const struct sun4i_plane_desc *plane)
>> @@ -129,9 +142,10 @@ static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm,
>> }
>>
>> struct sun4i_layer **sun4i_layers_init(struct drm_device *drm,
>> - struct sun4i_backend *backend)
>> + struct sun4i_crtc *crtc)
>> {
>> struct sun4i_layer **layers;
>> + struct sun4i_backend *backend = crtc->backend;
>> int i;
>>
>> layers = devm_kcalloc(drm->dev, ARRAY_SIZE(sun4i_backend_planes) + 1,
>> @@ -181,5 +195,8 @@ struct sun4i_layer **sun4i_layers_init(struct drm_device *drm,
>> layers[i] = layer;
>> };
>>
>> + /* Assign layer ops to the CRTC */
>> + crtc->layer_ops = &layer_ops;
>> +
>> return layers;
>> }
>> diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.h b/drivers/gpu/drm/sun4i/sun4i_layer.h
>> index 4be1f0919df2..425eea7b9e3b 100644
>> --- a/drivers/gpu/drm/sun4i/sun4i_layer.h
>> +++ b/drivers/gpu/drm/sun4i/sun4i_layer.h
>> @@ -27,6 +27,6 @@ plane_to_sun4i_layer(struct drm_plane *plane)
>> }
>>
>> struct sun4i_layer **sun4i_layers_init(struct drm_device *drm,
>> - struct sun4i_backend *backend);
>> + struct sun4i_crtc *crtc);
>>
>> #endif /* _SUN4I_LAYER_H_ */
>> diff --git a/drivers/gpu/drm/sun4i/sunxi_layer.h b/drivers/gpu/drm/sun4i/sunxi_layer.h
>> new file mode 100644
>> index 000000000000..d8838ec39299
>> --- /dev/null
>> +++ b/drivers/gpu/drm/sun4i/sunxi_layer.h
>> @@ -0,0 +1,17 @@
>> +/*
>> + * Copyright (C) 2017 Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License as
>> + * published by the Free Software Foundation; either version 2 of
>> + * the License, or (at your option) any later version.
>> + */
>> +
>> +#ifndef _SUNXI_LAYER_H_
>> +#define _SUNXI_LAYER_H_
>> +
>> +struct sunxi_layer_ops {
>> + struct drm_plane *(*get_plane)(void *layer);
>> +};
>> +
>> +#endif /* _SUNXI_LAYER_H_ */
>> --
>> 2.12.0
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply
* Re: [RESEND PATCH] ARM: dts: imx6q-utilite-pro: add hpd gpio
From: Christopher Spinrath @ 2017-04-04 19:42 UTC (permalink / raw)
To: shawnguo-DgEjT+Ai2ygdnm+yROfE0A, kernel-bIcnvbaLZ9MEGnE8C9+IrQ
Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
linux-I+IVW8TIWO2tmTQ+vhA3Yw,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
grinberg-UTxiZqZC01RS1MOuV/RT9w, fabio.estevam-3arQi8VN3Tc,
christopher.spinrath-vA1bhqPz9FBZXbeN9DUtxg
In-Reply-To: <68f4fe14a312455cbb4165d215277359-gtPewvpZjL8umhiu9RXYRl5UTUQ924AY@public.gmane.org>
On 04/04/2017 09:41 PM, christopher.spinrath-vA1bhqPz9FBZXbeN9DUtxg@public.gmane.org wrote:
> From: Christopher Spinrath <christopher.spinrath-vA1bhqPz9FBZXbeN9DUtxg@public.gmane.org>
>
> The hpd pin of the second hdmi connector of the Utilite Pro is wired
> up to a gpio pin of the SoC. Reflect this in the device tree.
>
> Signed-off-by: Christopher Spinrath <christopher.spinrath-vA1bhqPz9FBZXbeN9DUtxg@public.gmane.org>
> ---
>
> Hi Shawn,
>
> this was Patch 2/2 of a mini series [1] I sent four weeks ago. The
> drm part (Patch 1/2) has already been merged into drm-next.
>
> Any comments?
>
> Cheers,
> Christopher
Sorry, I forgot the link:
[1]
http://lists.infradead.org/pipermail/linux-arm-kernel/2017-March/491829.html
>
> arch/arm/boot/dts/imx6q-utilite-pro.dts | 10 +++++++++-
> 1 file changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/imx6q-utilite-pro.dts b/arch/arm/boot/dts/imx6q-utilite-pro.dts
> index 69bdd82..d900ad6 100644
> --- a/arch/arm/boot/dts/imx6q-utilite-pro.dts
> +++ b/arch/arm/boot/dts/imx6q-utilite-pro.dts
> @@ -101,9 +101,11 @@
>
> hdmi-connector {
> compatible = "hdmi-connector";
> -
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_hpd>;
> type = "a";
> ddc-i2c-bus = <&i2c_dvi_ddc>;
> + hpd-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
>
> port {
> hdmi_connector_in: endpoint {
> @@ -209,6 +211,12 @@
> >;
> };
>
> + pinctrl_hpd: hpdgrp {
> + fsl,pins = <
> + MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1b0b0
> + >;
> + };
> +
> pinctrl_i2c1: i2c1grp {
> fsl,pins = <
> MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [RESEND PATCH] ARM: dts: imx6q-utilite-pro: add hpd gpio
From: christopher.spinrath-vA1bhqPz9FBZXbeN9DUtxg @ 2017-04-04 19:41 UTC (permalink / raw)
To: shawnguo-DgEjT+Ai2ygdnm+yROfE0A, kernel-bIcnvbaLZ9MEGnE8C9+IrQ
Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
linux-I+IVW8TIWO2tmTQ+vhA3Yw,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
grinberg-UTxiZqZC01RS1MOuV/RT9w, fabio.estevam-3arQi8VN3Tc,
christopher.spinrath-vA1bhqPz9FBZXbeN9DUtxg
From: Christopher Spinrath <christopher.spinrath-vA1bhqPz9FBZXbeN9DUtxg@public.gmane.org>
The hpd pin of the second hdmi connector of the Utilite Pro is wired
up to a gpio pin of the SoC. Reflect this in the device tree.
Signed-off-by: Christopher Spinrath <christopher.spinrath-vA1bhqPz9FBZXbeN9DUtxg@public.gmane.org>
---
Hi Shawn,
this was Patch 2/2 of a mini series [1] I sent four weeks ago. The
drm part (Patch 1/2) has already been merged into drm-next.
Any comments?
Cheers,
Christopher
arch/arm/boot/dts/imx6q-utilite-pro.dts | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/imx6q-utilite-pro.dts b/arch/arm/boot/dts/imx6q-utilite-pro.dts
index 69bdd82..d900ad6 100644
--- a/arch/arm/boot/dts/imx6q-utilite-pro.dts
+++ b/arch/arm/boot/dts/imx6q-utilite-pro.dts
@@ -101,9 +101,11 @@
hdmi-connector {
compatible = "hdmi-connector";
-
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hpd>;
type = "a";
ddc-i2c-bus = <&i2c_dvi_ddc>;
+ hpd-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
port {
hdmi_connector_in: endpoint {
@@ -209,6 +211,12 @@
>;
};
+ pinctrl_hpd: hpdgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1b0b0
+ >;
+ };
+
pinctrl_i2c1: i2c1grp {
fsl,pins = <
MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
--
2.10.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH V3 0/5] iommu/arm-smmu: Add runtime pm/sleep support
From: Stephen Boyd @ 2017-04-04 19:39 UTC (permalink / raw)
To: Will Deacon
Cc: Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Mathieu Poirier, linux-arm-msm,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org,
Rob Herring, linux-clk-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
In-Reply-To: <20170403172307.GI5706-5wv7dgnIgG8@public.gmane.org>
On 04/03, Will Deacon wrote:
> On Fri, Mar 31, 2017 at 10:58:16PM -0400, Rob Clark wrote:
> > On Fri, Mar 31, 2017 at 1:54 PM, Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org> wrote:
> > > On Thu, Mar 09, 2017 at 09:05:43PM +0530, Sricharan R wrote:
> > >> This series provides the support for turning on the arm-smmu's
> > >> clocks/power domains using runtime pm. This is done using the
> > >> recently introduced device links patches, which lets the symmu's
> > >> runtime to follow the master's runtime pm, so the smmu remains
> > >> powered only when the masters use it.
> > >
> > > Do you have any numbers for the power savings you achieve with this?
> > > How often do we actually manage to stop the SMMU clocks on an SoC with
> > > a handful of masters?
> > >
> > > In other words, is this too coarse-grained to be useful, or is it common
> > > that all the devices upstream of the SMMU are suspended?
> >
> > well, if you think about a phone/tablet with a command mode panel,
> > pretty much all devices will be suspended most of the time ;-)
>
> Well, that's really what I was asking about. I assumed that periodic
> modem/radio transactions would keep the SMMU clocked, so would like to get a
> rough idea of the power savings achieved with this coarse-grained approach.
Sometimes we distribute SMMUs to each IP block in the system and
let each one of those live in their own clock + power domain. In
these cases, the SMMU can be powered down along with the only IP
block that uses it. Furthermore, sometimes we put the IP block
and the SMMU inside the same power domain to really tie the two
together, so we definitely have cases where all devices (device?)
upstream of the SMMU are suspended. And in the case of
multimedia, it could be very often that something like the camera
app isn't open and thus the SMMU dedicated for the camera can be
powered down.
Other times we have two SMMUs in the system where one is
dedicated to GPU and the other is "everything else". Even in
these cases, we can suspend the GPU one when the GPU is inactive
because it's the only consumer. The other SMMU might not be as
fine grained, but I think we still power it down quite often
because the consumers are mostly multimedia devices that aren't
active when the display is off.
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* Re: [PATCH v3 04/11] drm/sun4i: abstract the layer type
From: Sean Paul @ 2017-04-04 19:28 UTC (permalink / raw)
To: Icenowy Zheng
Cc: Rob Herring, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
devicetree, linux-kernel, dri-devel, linux-sunxi, linux-clk,
linux-arm-kernel
In-Reply-To: <20170329194613.55548-5-icenowy@aosc.io>
On Thu, Mar 30, 2017 at 03:46:06AM +0800, Icenowy Zheng wrote:
> As we are going to add support for the Allwinner DE2 Mixer in sun4i-drm
> driver, we will finally have two types of layer.
>
> Abstract the layer type to void * and a ops struct, which contains the
> only function used by crtc -- get the drm_plane struct of the layer.
>
> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> ---
> Refactored patch in v3.
>
> drivers/gpu/drm/sun4i/sun4i_crtc.c | 19 +++++++++++--------
> drivers/gpu/drm/sun4i/sun4i_crtc.h | 3 ++-
> drivers/gpu/drm/sun4i/sun4i_layer.c | 19 ++++++++++++++++++-
> drivers/gpu/drm/sun4i/sun4i_layer.h | 2 +-
> drivers/gpu/drm/sun4i/sunxi_layer.h | 17 +++++++++++++++++
> 5 files changed, 49 insertions(+), 11 deletions(-)
> create mode 100644 drivers/gpu/drm/sun4i/sunxi_layer.h
>
> diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c
> index 3c876c3a356a..33854ee7f636 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_crtc.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c
> @@ -29,6 +29,7 @@
> #include "sun4i_crtc.h"
> #include "sun4i_drv.h"
> #include "sun4i_layer.h"
> +#include "sunxi_layer.h"
> #include "sun4i_tcon.h"
>
> static void sun4i_crtc_atomic_begin(struct drm_crtc *crtc,
> @@ -149,7 +150,7 @@ struct sun4i_crtc *sun4i_crtc_init(struct drm_device *drm,
> scrtc->tcon = tcon;
>
> /* Create our layers */
> - scrtc->layers = sun4i_layers_init(drm, scrtc->backend);
> + scrtc->layers = (void **)sun4i_layers_init(drm, scrtc);
> if (IS_ERR(scrtc->layers)) {
> dev_err(drm->dev, "Couldn't create the planes\n");
> return NULL;
> @@ -157,14 +158,15 @@ struct sun4i_crtc *sun4i_crtc_init(struct drm_device *drm,
>
> /* find primary and cursor planes for drm_crtc_init_with_planes */
> for (i = 0; scrtc->layers[i]; i++) {
> - struct sun4i_layer *layer = scrtc->layers[i];
> + void *layer = scrtc->layers[i];
> + struct drm_plane *plane = scrtc->layer_ops->get_plane(layer);
>
> - switch (layer->plane.type) {
> + switch (plane->type) {
> case DRM_PLANE_TYPE_PRIMARY:
> - primary = &layer->plane;
> + primary = plane;
> break;
> case DRM_PLANE_TYPE_CURSOR:
> - cursor = &layer->plane;
> + cursor = plane;
> break;
> default:
> break;
> @@ -190,10 +192,11 @@ struct sun4i_crtc *sun4i_crtc_init(struct drm_device *drm,
> /* Set possible_crtcs to this crtc for overlay planes */
> for (i = 0; scrtc->layers[i]; i++) {
> uint32_t possible_crtcs = BIT(drm_crtc_index(&scrtc->crtc));
> - struct sun4i_layer *layer = scrtc->layers[i];
> + void *layer = scrtc->layers[i];
> + struct drm_plane *plane = scrtc->layer_ops->get_plane(layer);
>
> - if (layer->plane.type == DRM_PLANE_TYPE_OVERLAY)
> - layer->plane.possible_crtcs = possible_crtcs;
> + if (plane->type == DRM_PLANE_TYPE_OVERLAY)
> + plane->possible_crtcs = possible_crtcs;
> }
>
> return scrtc;
> diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.h b/drivers/gpu/drm/sun4i/sun4i_crtc.h
> index 230cb8f0d601..a4036ee44cf8 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_crtc.h
> +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.h
> @@ -19,7 +19,8 @@ struct sun4i_crtc {
>
> struct sun4i_backend *backend;
> struct sun4i_tcon *tcon;
> - struct sun4i_layer **layers;
> + void **layers;
> + const struct sunxi_layer_ops *layer_ops;
I think you should probably take a different approach to abstract the layer
type. How about creating
struct sunxi_layer {
struct drm_plane plane;
}
base and then subclassing that for sun4i and sun8i? By doing this you can avoid
the nasty casting and you can also get rid of the get_plane() hook and
layer_ops.
Sean
> };
>
> static inline struct sun4i_crtc *drm_crtc_to_sun4i_crtc(struct drm_crtc *crtc)
> diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c
> index f26bde5b9117..bc4a70d6968b 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_layer.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
> @@ -16,7 +16,9 @@
> #include <drm/drmP.h>
>
> #include "sun4i_backend.h"
> +#include "sun4i_crtc.h"
> #include "sun4i_layer.h"
> +#include "sunxi_layer.h"
>
> struct sun4i_plane_desc {
> enum drm_plane_type type;
> @@ -100,6 +102,17 @@ static const struct sun4i_plane_desc sun4i_backend_planes[] = {
> },
> };
>
> +static struct drm_plane *sun4i_layer_get_plane(void *layer)
> +{
> + struct sun4i_layer *sun4i_layer = layer;
> +
> + return &sun4i_layer->plane;
> +}
> +
> +static const struct sunxi_layer_ops layer_ops = {
> + .get_plane = sun4i_layer_get_plane,
> +};
> +
> static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm,
> struct sun4i_backend *backend,
> const struct sun4i_plane_desc *plane)
> @@ -129,9 +142,10 @@ static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm,
> }
>
> struct sun4i_layer **sun4i_layers_init(struct drm_device *drm,
> - struct sun4i_backend *backend)
> + struct sun4i_crtc *crtc)
> {
> struct sun4i_layer **layers;
> + struct sun4i_backend *backend = crtc->backend;
> int i;
>
> layers = devm_kcalloc(drm->dev, ARRAY_SIZE(sun4i_backend_planes) + 1,
> @@ -181,5 +195,8 @@ struct sun4i_layer **sun4i_layers_init(struct drm_device *drm,
> layers[i] = layer;
> };
>
> + /* Assign layer ops to the CRTC */
> + crtc->layer_ops = &layer_ops;
> +
> return layers;
> }
> diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.h b/drivers/gpu/drm/sun4i/sun4i_layer.h
> index 4be1f0919df2..425eea7b9e3b 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_layer.h
> +++ b/drivers/gpu/drm/sun4i/sun4i_layer.h
> @@ -27,6 +27,6 @@ plane_to_sun4i_layer(struct drm_plane *plane)
> }
>
> struct sun4i_layer **sun4i_layers_init(struct drm_device *drm,
> - struct sun4i_backend *backend);
> + struct sun4i_crtc *crtc);
>
> #endif /* _SUN4I_LAYER_H_ */
> diff --git a/drivers/gpu/drm/sun4i/sunxi_layer.h b/drivers/gpu/drm/sun4i/sunxi_layer.h
> new file mode 100644
> index 000000000000..d8838ec39299
> --- /dev/null
> +++ b/drivers/gpu/drm/sun4i/sunxi_layer.h
> @@ -0,0 +1,17 @@
> +/*
> + * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.xyz>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + */
> +
> +#ifndef _SUNXI_LAYER_H_
> +#define _SUNXI_LAYER_H_
> +
> +struct sunxi_layer_ops {
> + struct drm_plane *(*get_plane)(void *layer);
> +};
> +
> +#endif /* _SUNXI_LAYER_H_ */
> --
> 2.12.0
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
Sean Paul, Software Engineer, Google / Chromium OS
^ permalink raw reply
* [PATCH 2/2] devicetree: Document the max31760 device binding.
From: John Muir @ 2017-04-04 19:20 UTC (permalink / raw)
To: Jean Delvare, Guenter Roeck, Jonathan Corbet, Rob Herring,
Pawel Moll, Ian Campbell, Kumar Gala, devicetree, linux-hwmon,
linux-doc
Cc: John Muir, Anatol Pomazau, Mark Segal
In-Reply-To: <20170404192034.158901-1-john@jmuir.com>
Signed-off-by: John Muir <john@jmuir.com>
---
.../devicetree/bindings/hwmon/max31760.txt | 58 ++++++++++++++++++++++
1 file changed, 58 insertions(+)
create mode 100644 Documentation/devicetree/bindings/hwmon/max31760.txt
diff --git a/Documentation/devicetree/bindings/hwmon/max31760.txt b/Documentation/devicetree/bindings/hwmon/max31760.txt
new file mode 100644
index 000000000000..43787a77c322
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwmon/max31760.txt
@@ -0,0 +1,58 @@
+MAX31760 fan controller
+-----------------------
+
+This device supports I2C only. Many properties of this device are configurable
+thorugh the hwmon interface. See also Documentation/hwmon/max31760.
+
+Required node properties:
+- compatible : "maxim,max31760"
+- reg : The I2C address of the device. This is 0x50 - 0x57 depending on the
+ hardware configuration.
+
+Optional node properties:
+- maxim,fan1-enabled - 1 to enable, 0 to disable. Default: 1.
+- maxim,fan2-enabled - 1 to enable, 0 to disable. Default: 1.
+- maxim,fan1-label - String: Hwmon fan1_label.
+- maxim,fan2-label - String: Hwmon fan2_label.
+- maxim,fan-fail-full-only - Set to 1 to assert a fan failure only when the
+ PWM is at 100%. Default: 0.
+- maxim,fan-rd-signal - Set to 1 if fan(s) provide a rotation
+ detection (RD) signal, or 0 if the fan
+ generates square-wave pulses. Default: 0.
+- maxim,fan-rd-polarity - 0: RD is low when the fan is running.
+ 1: RD is high when the fan is running.
+ Only relevant when fan-rd-signal is 1.
+ Default: 0.
+- maxim,fan-signal-enabled - Set to 1 if externally driving FF/FS low
+ should force PWM output to 100%. Default: 0.
+- maxim,fan-spin-up-enabled - For fan startup: Set to 1 to set the PWM to
+ 100% until tach is detected or two seconds
+ have passed before reducing to the target
+ value. Default: 0.
+- maxim,pwm-polarity - 0: 100% PWM is when PWM is high.
+ 1: 100% PWM is when PWM is low.
+ Default: 0.
+- maxim,pwm-pulse-stretch-enabled
+ - 1 to enable PWM pulse stretching, 0 to
+ disable. Default: 0.
+- maxim,pwm-zero-fan-can-fail - 0: Fan failure detection disabled when PWM is
+ ramping to 0%.
+ 1: Fan failure detection enabled for all PWM
+ values.
+ Default: 0.
+- maxim,temp1-label - String: Hwmon temp1_label.
+- maxim,temp2-label - String: Hwmon temp2_label.
+- maxim,temp2-ideality - Set ideality factor for the remote temperature
+ sensor. Integer with range 0 to 63,
+ representing a multiplication factor of 0.9844
+ to 1.0489. Default: 24 (1.0080).
+
+Example:
+ max31760@50 {
+ compatible = "maxim,max31760";
+ reg = <0x50>;
+ maxim,fan1-label = "Left";
+ maxim,fan2-label = "Right";
+ maxim,fan-spin-up-enabled = <1>;
+ maxim,temp2-label = "CPU";
+ };
--
2.12.2.715.g7642488e1d-goog
^ permalink raw reply related
* [PATCH 1/2] hwmon: Add MAX31760 fan controller driver.
From: John Muir @ 2017-04-04 19:20 UTC (permalink / raw)
To: Jean Delvare, Guenter Roeck, Jonathan Corbet, Rob Herring,
Pawel Moll, Ian Campbell, Kumar Gala, devicetree, linux-hwmon,
linux-doc
Cc: John Muir, Anatol Pomazau, Mark Segal
In-Reply-To: <20170404192034.158901-1-john@jmuir.com>
Add a driver for the Maxim Integrated MAX31760 Precision Fan
Speed Controller.
Signed-off-by: John Muir <john@jmuir.com>
---
Documentation/hwmon/max31760 | 41 ++
drivers/hwmon/Kconfig | 10 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/max31760.c | 1430 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 1482 insertions(+)
create mode 100644 Documentation/hwmon/max31760
create mode 100644 drivers/hwmon/max31760.c
diff --git a/Documentation/hwmon/max31760 b/Documentation/hwmon/max31760
new file mode 100644
index 000000000000..95937844ed18
--- /dev/null
+++ b/Documentation/hwmon/max31760
@@ -0,0 +1,41 @@
+Kernel driver max31760
+======================
+
+Supported chips:
+ * Maxim Integrated MAX31760
+ Prefix: 'max31760'
+ Addresses scanned: none
+ Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX31760.pdf
+
+Author:
+ John Muir <john@jmuir.com>
+
+Description
+-----------
+
+The MAX31760 integrates temperature sensing along with precision PWM fan
+control. Please read the datasheet referenced above for a comprehensive
+description of this device.
+
+This device driver's hwmon integration provides the common sysfs interfaces to
+manage two fans and two temperature sensors, and pwm controls for the fan speed.
+A temperature to pwm lookup table is exposed via a series of 'auto_point'
+configuration files. See Documentation/hwmon/sysfs-interface for more
+information.
+
+The following custom controls are defined (in the custom sub-directory):
+
+control - Accepts control commands:
+ "reset" - Execute a soft reset of the device.
+ "clearff" - Clear the fan fault.
+
+eeprom_read - Read from the EEPROM into registers.
+eeprom_write - Write register contents to the EEPROM.
+ Write "0" to these to read or write the entire register
+ contents. Write a bit-field as per the data-sheet to write a
+ portion of the register contents.
+
+pwm1_fan_fault - PWM value in the range of 0 to 255 used when a fan is faulty.
+
+pwm1_ramp_rate - PWM increment per second when the PWM value is changed.
+ Accepted values are 8, 16, 32, or 255 (instantaneous).
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 2d5447bebab6..3aef5c07f1c3 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -849,6 +849,16 @@ config SENSORS_MAX6697
This driver can also be built as a module. If so, the module
will be called max6697.
+config SENSORS_MAX31760
+ tristate "Maxim MAX31760 fan controller"
+ depends on I2C
+ help
+ If you say yes here you get support for the Maxim Integrated
+ MAX31760 Precision Fan-Speed Controller.
+
+ This driver can also be built as a module. If so, the module
+ will be called max31760.
+
config SENSORS_MAX31790
tristate "Maxim MAX31790 sensor chip"
depends on I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 76e1456ddf2f..7b08f069d5a4 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -116,6 +116,7 @@ obj-$(CONFIG_SENSORS_MAX6639) += max6639.o
obj-$(CONFIG_SENSORS_MAX6642) += max6642.o
obj-$(CONFIG_SENSORS_MAX6650) += max6650.o
obj-$(CONFIG_SENSORS_MAX6697) += max6697.o
+obj-$(CONFIG_SENSORS_MAX31760) += max31760.o
obj-$(CONFIG_SENSORS_MAX31790) += max31790.o
obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o
obj-$(CONFIG_SENSORS_MCP3021) += mcp3021.o
diff --git a/drivers/hwmon/max31760.c b/drivers/hwmon/max31760.c
new file mode 100644
index 000000000000..735b4fe9a510
--- /dev/null
+++ b/drivers/hwmon/max31760.c
@@ -0,0 +1,1430 @@
+/* Maxim Integrated MAX31760 Precision Fan-Speed Controller driver
+ *
+ * Copyright (C) 2017 John Muir <john@jmuir.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/ctype.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+
+#define DRIVER_NAME "max31760"
+
+#define MAX31760_REG_CR1 0x00 /* Control Register 1 */
+#define MAX31760_CR1_TIS 0x01 /* Temperature Index Source */
+#define MAX31760_CR1_MTI 0x02 /* Maximum Temperature Index */
+#define MAX31760_CR1_PPS 0x04 /* PWM Polarity */
+#define MAX31760_CR1_DRV 0x18 /* PWM Frequency */
+#define MAX31760_DRV_33HZ 0x00
+#define MAX31760_DRV_150HZ 0x08
+#define MAX31760_DRV_1500HZ 0x10
+#define MAX31760_DRV_25KHZ MAX31760_CR1_DRV
+#define MAX31760_CR1_HYST 0x20 /* Lookup Table Hysteresis: 2C or 4C */
+#define MAX31760_CR1_POR 0x40 /* Software Power-On Reset */
+#define MAX31760_CR1_ALTMSK 0x80 /* Alert Mask */
+#define MAX31760_REG_CR2 0x01 /* Control Register 2 */
+#define MAX31760_CR2_DFC 0x01 /* Direct Fan Control */
+#define MAX31760_CR2_FSST 0x02 /* Fan Sense Signal Type */
+#define MAX31760_CR2_RDPS 0x04 /* RD Polarity Selection */
+#define MAX31760_CR2_FSEN 0x08 /* FS Input Enable */
+#define MAX31760_CR2_FFMODE 0x10 /* FF Functionality Selection */
+#define MAX31760_CR2_SPEN 0x20 /* Spin-up Enable */
+#define MAX31760_CR2_ALERTS 0x40 /* Alerts Functionality Selection */
+#define MAX31760_CR2_STBY 0x80 /* Standby Mode Enable */
+#define MAX31760_REG_CR3 0x02 /* Control Register 3 */
+#define MAX31760_CR3_TACH1E 0x01 /* Tachometer 1 Enable */
+#define MAX31760_CR3_TACH2E 0x02 /* Tachometer 2 Enable */
+#define MAX31760_CR3_PSEN 0x04 /* Pulse Stretch Enable */
+#define MAX31760_CR3_TACHFL 0x08 /* Fan Fail When 100% Duty Cycle Only */
+#define MAX31760_CR3_RAMP 0x30 /* PWM Duty-Cycle Ramp Rate */
+#define MAX31760_RAMP_SLOW 0x00
+#define MAX31760_RAMP_SMED 0x10
+#define MAX31760_RAMP_MEDF 0x20
+#define MAX31760_RAMP_FAST MAX31760_CR3_RAMP
+#define MAX31760_CR3_FF_0 0x40 /* 0 Duty-Cycle Fan-Fail Detection */
+#define MAX31760_CR3_CLR_FF 0x80 /* Clear Fan Fail */
+#define MAX31760_REG_FFDC 0x03 /* Fan Fault Duty Cycle */
+#define MAX31760_REG_MASK 0x04 /* Alert Mask Register */
+#define MAX31760_MASK_TACH1AM 0x01 /* TACH1 Alarm Mask */
+#define MAX31760_MASK_TACH2AM 0x02 /* TACH2 Alarm Mask */
+#define MAX31760_MASK_ROTAM 0x04 /* Remote Overtemperature Alarm Mask */
+#define MAX31760_MASK_RHAM 0x08 /* Remote High Temperature Alarm Mask */
+#define MAX31760_MASK_LOTAM 0x10 /* Local Overtemperature Alarm Mask */
+#define MAX31760_MASK_LHAM 0x20 /* Local High Temperature Alarm Mask */
+#define MAX31760_REG_IFR 0x05 /* Ideality Factor Register */
+#define MAX31760_IFR_MASK 0x3f /* Mask for value of the IFR */
+#define MAX31760_REG_RHSH 0x06 /* Remote High Set-point MSB */
+#define MAX31760_REG_RHSL 0x07 /* Remote High Set-point LSB */
+#define MAX31760_REG_LOTSH 0x08 /* Local Overtemperature Set-point MSB */
+#define MAX31760_REG_LOTSL 0x09 /* Local Overtemperature Set-point LSB */
+#define MAX31760_REG_ROTSH 0x0a /* Remote Overtemperature Set-point MSB */
+#define MAX31760_REG_ROTSL 0x0b /* Remote Overtemperature Set-point LSB */
+#define MAX31760_REG_LHSH 0x0c /* Local High Set-point MSB */
+#define MAX31760_REG_LHSL 0x0d /* Local High Set-point LSB */
+#define MAX31760_REG_TCTH 0x0e /* TACH Count Threshold Register, MSB */
+#define MAX31760_REG_TCTL 0x0f /* TACH Count Threshold Register, LSB */
+#define MAX31760_REG_USER 0x10 /* 8 bytes General Purpose User Memory */
+#define MAX31760_REG_USER0 0x10 /* Custom Control Register USER0 */
+#define MAX31760_USER0_PULSE1 0x07 /* Fan1 Pulses per revolution */
+#define MAX31760_USER0_PULSE2 0x38 /* Fan2 Pulses per revolution */
+#define MAX31760_REG_LUT 0x20 /* 48-Byte Lookup Table (LUT) */
+#define MAX31760_LUT_COUNT 48
+#define MAX31760_REG_PWMR 0x50 /* Direct Duty-Cycle Control Register */
+
+#define MAX31760_REG_PWMV 0x51 /* Current PWM Duty-Cycle Register */
+#define MAX31760_REG_TC1H 0x52 /* TACH1 Count Register, MSB */
+#define MAX31760_REG_TC1L 0x53 /* TACH1 Count Register, LSB */
+#define MAX31760_REG_TC2H 0x54 /* TACH2 Count Register, MSB */
+#define MAX31760_REG_TC2L 0x55 /* TACH2 Count Register, LSB */
+#define MAX31760_REG_RTH 0x56 /* Remote Temperature Reading Register, MSB */
+#define MAX31760_REG_RTL 0x57 /* Remote Temperature Reading Register, LSB */
+#define MAX31760_REG_LTH 0x58 /* Local Temperature Reading Register, MSB */
+#define MAX31760_REG_LTL 0x59 /* Local Temperature Reading Register, LSB */
+#define MAX31760_REG_SR 0x5a /* Status Register */
+#define MAX31760_SR_TACH1A 0x01 /* TACH1 Alarm */
+#define MAX31760_SR_TACH2A 0x02 /* TACH2 Alarm */
+#define MAX31760_SR_ROTA 0x04 /* Remote Overtemperature Alarm */
+#define MAX31760_SR_RHA 0x08 /* Remote High Temperature Alarm */
+#define MAX31760_SR_LOTA 0x10 /* Local Overtemperature Alarm */
+#define MAX31760_SR_LHA 0x20 /* Local High Temperature Alarm */
+#define MAX31760_SR_RDFA 0x40 /* Remote Diode Fault Alarm */
+#define MAX31760_SR_PC 0x80 /* Program Corrupt Bit */
+
+#define MAX31760_REG_EEX 0x5b /* Load EEPROM to RAM; Write RAM to EEPROM */
+#define MAX31760_EEX_LW 0x80 /* Load from or write to EEPROM */
+#define MAX31760_EEX_BLKS 0x1F /* Blocks to load/write */
+
+#define MAX31760_TEMP_MIN_MC -128000 /* Minimum Millicelcius */
+#define MAX31760_TEMP_LUT_MIN_MC -40000
+#define MAX31760_TEMP_MAX_MC 127875 /* Maximum Millicelcius */
+#define MAX31760_TEMP_HIGH_HYST 1000 /* 1C hysteresis on high temp alarms. */
+#define MAX31760_TEMP_OVER_HYST 10000 /* 10C hysteresis on over temp alarms. */
+#define MAX31760_LUT_HYST_CLEAR 2000
+#define MAX31760_LYT_HYST_THRESH 3000
+#define MAX31760_LUT_HYST_SET 4000
+
+#define MAX31760_NUM_FANS 2
+#define MAX31760_FAN_PULSES_DEF 2
+#define MAX31760_FAN_PULSES_MAX 8
+#define MAX31760_PWM_ENABLE_FULL 0
+#define MAX31760_PWM_ENABLE_MANUAL 1
+#define MAX31760_PWM_ENABLE_AUTO 2
+#define MAX31760_NUM_TEMPS 2
+
+#define MAX31760_LUT_AUTO_ATTRS 3
+#define MAX31760_LUT_AUTO_ATTR_COUNT (MAX31760_LUT_COUNT * \
+ MAX31760_LUT_AUTO_ATTRS)
+#define MAX31760_LUT_NAME_SIZE 32 /* Fit: pwm1_auto_pointXX_temp_hyst\0. */
+
+struct max31760_dev_attr {
+ struct sensor_device_attribute sdattr;
+ char name[MAX31760_LUT_NAME_SIZE];
+};
+
+struct max31760 {
+ struct regmap *regmap;
+ int fan_pulses[MAX31760_NUM_FANS];
+ const char *fan_label[MAX31760_NUM_FANS];
+ const char *temp_label[MAX31760_NUM_TEMPS];
+ struct max31760_dev_attr lut_dev_attrs[MAX31760_LUT_AUTO_ATTR_COUNT];
+ struct attribute *lut_attrs[MAX31760_LUT_AUTO_ATTR_COUNT + 1];
+ struct attribute_group lut_group;
+ const struct attribute_group *attr_groups[4];
+};
+
+static bool max31760_readable_reg(struct device *dev, unsigned int reg)
+{
+ return reg != MAX31760_REG_EEX;
+}
+
+static bool max31760_writeable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case MAX31760_REG_PWMV ... MAX31760_REG_SR:
+ return false;
+ default:
+ return true;
+ }
+}
+
+static bool max31760_volatile_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case MAX31760_REG_MASK:
+ case MAX31760_REG_PWMR ... MAX31760_REG_EEX:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static const struct regmap_config max31760_regmap_config = {
+ /* Device has an EEPROM to store the register values, so don't define
+ * reg_defaults: read the current values from the hardware.
+ */
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = MAX31760_REG_EEX,
+ .writeable_reg = max31760_writeable_reg,
+ .readable_reg = max31760_readable_reg,
+ .volatile_reg = max31760_volatile_reg,
+ .val_format_endian = REGMAP_ENDIAN_BIG,
+ .cache_type = REGCACHE_RBTREE,
+ .use_single_rw = true,
+};
+
+/* Convert 11-bit MAX31760 register value to milliCelsius */
+static inline int max31760_temp_reg_to_mC(s16 val)
+{
+ return (val & ~0x0f) * 1000 / 256;
+}
+
+/* Convert milliCelsius to left adjusted 11-bit MAX31760 register value */
+static inline u16 max31760_mC_to_temp_reg(int val)
+{
+ return (val * 256) / 1000;
+}
+
+/* Convert tachometer value to RPM. */
+static inline long max31760_rpm_from_tach(u16 tach_count, int pulses)
+{
+ return 60L * 100000L / (long)tach_count / (long)pulses;
+}
+
+/* Convert RPM to tachometer value. */
+static inline u16 max31760_tach_from_rpm(long rpm, int pulses)
+{
+ long tach = 60L * 100000L / rpm / (long)pulses;
+
+ if (tach < 0)
+ tach = 0;
+ else if (tach > (long)USHRT_MAX)
+ tach = USHRT_MAX;
+
+ return tach;
+}
+
+static int max31760_read_word(struct regmap *regmap, unsigned int regmsb,
+ u16 *word)
+{
+ int err;
+ unsigned int msb_val;
+ unsigned int lsb_val;
+
+ err = regmap_read(regmap, regmsb, &msb_val);
+ if (err < 0)
+ return err;
+ err = regmap_read(regmap, regmsb + 1, &lsb_val);
+ if (err < 0)
+ return err;
+
+ *word = ((msb_val << 8) & 0xff00) | (lsb_val & 0xff);
+ return 0;
+}
+
+static int max31760_write_word(struct regmap *regmap, unsigned int regmsb,
+ u16 word)
+{
+ int err;
+ unsigned int val;
+
+ val = (word >> 8) & 0xff;
+ err = regmap_write(regmap, regmsb, val);
+ if (err < 0)
+ return err;
+
+ val = word & 0xff;
+ return regmap_write(regmap, regmsb + 1, val);
+}
+
+static int max31760_read_alarm(struct device *dev, unsigned int srflag,
+ unsigned int maskflag, long *val)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ unsigned int srval;
+ unsigned int maskval;
+ int err;
+
+ err = regmap_read(max31760->regmap, MAX31760_REG_SR, &srval);
+ if (err < 0)
+ return err;
+ err = regmap_read(max31760->regmap, MAX31760_REG_MASK, &maskval);
+ if (err < 0)
+ return err;
+
+ *val = !!((srval & srflag) | (maskval & maskflag));
+ return 0;
+}
+
+static int max31760_read_temp(struct device *dev, u32 attr, int channel,
+ long *val)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ unsigned int reg;
+ unsigned int regval;
+ unsigned int srflag;
+ unsigned int maskflag;
+ u16 temp;
+ int err;
+ int hyst = 0;
+
+ switch (attr) {
+ case hwmon_temp_emergency_hyst:
+ hyst = MAX31760_TEMP_OVER_HYST;
+ /* fallthrough */
+ case hwmon_temp_max_hyst:
+ if (attr == hwmon_temp_max_hyst)
+ hyst = MAX31760_TEMP_HIGH_HYST;
+ /* fallthrough */
+ case hwmon_temp_input:
+ case hwmon_temp_max:
+ case hwmon_temp_emergency:
+ switch (attr) {
+ case hwmon_temp_input:
+ reg = channel ? MAX31760_REG_RTH : MAX31760_REG_LTH;
+ break;
+ case hwmon_temp_max_hyst:
+ case hwmon_temp_max:
+ reg = channel ? MAX31760_REG_RHSH : MAX31760_REG_LHSH;
+ break;
+ case hwmon_temp_emergency_hyst:
+ case hwmon_temp_emergency:
+ reg = channel ? MAX31760_REG_ROTSH : MAX31760_REG_LOTSH;
+ break;
+ }
+ err = max31760_read_word(max31760->regmap, reg, &temp);
+ if (err < 0)
+ return err;
+ *val = max31760_temp_reg_to_mC(temp) - hyst;
+ break;
+ case hwmon_temp_max_alarm:
+ case hwmon_temp_emergency_alarm:
+ switch (attr) {
+ case hwmon_temp_max_alarm:
+ srflag = channel ? MAX31760_SR_RHA : MAX31760_SR_LHA;
+ maskflag = channel ? MAX31760_MASK_RHAM :
+ MAX31760_MASK_LHAM;
+ break;
+ case hwmon_temp_emergency_alarm:
+ srflag = channel ? MAX31760_SR_ROTA : MAX31760_SR_LOTA;
+ maskflag = channel ? MAX31760_MASK_RHAM :
+ MAX31760_MASK_LHAM;
+ break;
+ }
+ return max31760_read_alarm(dev, srflag, maskflag, val);
+ case hwmon_temp_fault:
+ err = regmap_read(max31760->regmap, MAX31760_REG_SR, ®val);
+ if (err < 0)
+ return err;
+ *val = !!(regval & MAX31760_SR_RDFA);
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int max31760_read_fan(struct device *dev, u32 attr, int channel,
+ long *val)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ u16 tach_count;
+ unsigned int reg;
+ unsigned int regval;
+ unsigned int srflag;
+ unsigned int maskflag;
+ int err;
+
+ switch (attr) {
+ case hwmon_fan_input:
+ case hwmon_fan_min:
+ switch (attr) {
+ case hwmon_fan_input:
+ reg = channel ? MAX31760_REG_TC2H : MAX31760_REG_TC1H;
+ break;
+ case hwmon_fan_min:
+ reg = MAX31760_REG_TCTH;
+ break;
+ }
+ err = max31760_read_word(max31760->regmap, reg, &tach_count);
+ if (err)
+ return err;
+ *val = max31760_rpm_from_tach(tach_count,
+ max31760->fan_pulses[channel]);
+ break;
+ case hwmon_fan_fault:
+ /* TODO: Read FF/FS GPIO input when available. */
+ /* fallthrough */
+ case hwmon_fan_min_alarm:
+ srflag = channel ? MAX31760_SR_TACH2A : MAX31760_SR_TACH1A;
+ maskflag = channel ? MAX31760_MASK_TACH2AM :
+ MAX31760_MASK_TACH1AM;
+ return max31760_read_alarm(dev, srflag, maskflag, val);
+ case hwmon_fan_pulses:
+ err = regmap_read(max31760->regmap, MAX31760_REG_USER0,
+ ®val);
+ if (err)
+ return err;
+ if (channel)
+ *val = (regval & MAX31760_USER0_PULSE2) >> 3;
+ else
+ *val = regval & MAX31760_USER0_PULSE1;
+ if (*val == 0)
+ *val = MAX31760_FAN_PULSES_DEF;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+static int max31760_read_pwm(struct device *dev, u32 attr, int channel,
+ long *val)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ unsigned int regval;
+ int err;
+
+ switch (attr) {
+ case hwmon_pwm_input:
+ /* Note that this is the current value, not the value stored to
+ * the duty-cycle register.
+ */
+ err = regmap_read(max31760->regmap, MAX31760_REG_PWMV, ®val);
+ if (err)
+ return err;
+ *val = regval;
+ break;
+ case hwmon_pwm_enable:
+ err = regmap_read(max31760->regmap, MAX31760_REG_CR2, ®val);
+ if (err)
+ return err;
+ if (regval & MAX31760_CR2_DFC)
+ *val = MAX31760_PWM_ENABLE_MANUAL;
+ else
+ *val = MAX31760_PWM_ENABLE_AUTO;
+ break;
+ case hwmon_pwm_freq:
+ err = regmap_read(max31760->regmap, MAX31760_REG_CR1, ®val);
+ if (err)
+ return err;
+ switch (regval & MAX31760_CR1_DRV) {
+ case MAX31760_DRV_33HZ:
+ default:
+ *val = 33;
+ break;
+ case MAX31760_DRV_150HZ:
+ *val = 150;
+ break;
+ case MAX31760_DRV_1500HZ:
+ *val = 1500;
+ break;
+ case MAX31760_DRV_25KHZ:
+ *val = 25000;
+ break;
+ }
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int max31760_read(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, long *val)
+{
+ switch (type) {
+ case hwmon_temp:
+ return max31760_read_temp(dev, attr, channel, val);
+ case hwmon_fan:
+ return max31760_read_fan(dev, attr, channel, val);
+ case hwmon_pwm:
+ return max31760_read_pwm(dev, attr, channel, val);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int max31760_read_string(struct device *dev,
+ enum hwmon_sensor_types type, u32 attr,
+ int channel, const char **str)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+
+ switch (type) {
+ case hwmon_temp:
+ if (attr != hwmon_temp_label)
+ return -EOPNOTSUPP;
+ *str = max31760->temp_label[channel];
+ break;
+ case hwmon_fan:
+ if (attr != hwmon_fan_label)
+ return -EOPNOTSUPP;
+ *str = max31760->fan_label[channel];
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int max31760_write_temp_reg(struct regmap *regmap,
+ unsigned int regmsb, long temp)
+{
+ u16 word;
+
+ temp = clamp_val(temp, MAX31760_TEMP_MIN_MC, MAX31760_TEMP_MAX_MC);
+ word = max31760_mC_to_temp_reg(temp);
+
+ return max31760_write_word(regmap, regmsb, word);
+}
+
+static int max31760_write_temp(struct device *dev, u32 attr, int channel,
+ long val)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+
+ switch (attr) {
+ case hwmon_temp_max:
+ return max31760_write_temp_reg(max31760->regmap,
+ channel ? MAX31760_REG_RHSH :
+ MAX31760_REG_LHSH,
+ val);
+ case hwmon_temp_emergency:
+ return max31760_write_temp_reg(max31760->regmap,
+ channel ? MAX31760_REG_ROTSH :
+ MAX31760_REG_LOTSH,
+ val);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static void max31760_update_fan_pulses(struct max31760 *max31760, int channel,
+ int pulses)
+{
+ if (pulses > MAX31760_FAN_PULSES_MAX)
+ pulses = MAX31760_FAN_PULSES_MAX;
+ else if (pulses <= 0)
+ pulses = MAX31760_FAN_PULSES_DEF;
+ max31760->fan_pulses[channel] = pulses;
+}
+
+static int max31760_write_fan(struct device *dev, u32 attr, int channel,
+ long val)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ unsigned int regval;
+ unsigned int mask;
+ u16 tach;
+
+ switch (attr) {
+ case hwmon_fan_min:
+ tach = max31760_tach_from_rpm(val,
+ max31760->fan_pulses[channel]);
+ return max31760_write_word(max31760->regmap, MAX31760_REG_TCTH,
+ tach);
+ case hwmon_fan_pulses:
+ max31760_update_fan_pulses(max31760, channel, val);
+ regval = (unsigned int)max31760->fan_pulses[channel];
+ if (channel) {
+ regval <<= 3;
+ mask = MAX31760_USER0_PULSE2;
+ } else {
+ mask = MAX31760_USER0_PULSE1;
+ }
+ return regmap_update_bits(max31760->regmap, MAX31760_REG_USER0,
+ mask, regval);
+ default:
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+static int max31760_write_pwm(struct device *dev, u32 attr, int channel,
+ long val)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ unsigned int regval;
+ int err;
+
+ switch (attr) {
+ case hwmon_pwm_input:
+ regval = (unsigned int)val & 0xff;
+ return regmap_write(max31760->regmap, MAX31760_REG_PWMR,
+ regval);
+ case hwmon_pwm_enable:
+ switch (val) {
+ case MAX31760_PWM_ENABLE_FULL:
+ err = regmap_write(max31760->regmap, MAX31760_REG_PWMR,
+ 0xff);
+ if (err)
+ return err;
+ /* fallthrough */
+ case MAX31760_PWM_ENABLE_MANUAL:
+ return regmap_update_bits(max31760->regmap,
+ MAX31760_REG_CR2,
+ MAX31760_CR2_DFC,
+ MAX31760_CR2_DFC);
+ default:
+ case MAX31760_PWM_ENABLE_AUTO:
+ return regmap_update_bits(max31760->regmap,
+ MAX31760_REG_CR2,
+ MAX31760_CR2_DFC, 0);
+ }
+ break;
+ case hwmon_pwm_freq:
+ if (val < 91)
+ regval = MAX31760_DRV_33HZ;
+ else if (val < 825)
+ regval = MAX31760_DRV_150HZ;
+ else if (val < 11000)
+ regval = MAX31760_DRV_1500HZ;
+ else
+ regval = MAX31760_DRV_25KHZ;
+ return regmap_update_bits(max31760->regmap, MAX31760_REG_CR1,
+ MAX31760_CR1_DRV, regval);
+ }
+ return 0;
+}
+
+static int max31760_write(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, long val)
+{
+ switch (type) {
+ case hwmon_temp:
+ return max31760_write_temp(dev, attr, channel, val);
+ case hwmon_fan:
+ return max31760_write_fan(dev, attr, channel, val);
+ case hwmon_pwm:
+ return max31760_write_pwm(dev, attr, channel, val);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static umode_t max31760_is_visible(const void *dvrdata,
+ enum hwmon_sensor_types type,
+ u32 attr, int channel)
+{
+ struct max31760 *max31760 = (struct max31760 *)dvrdata;
+
+ switch (type) {
+ case hwmon_temp:
+ switch (attr) {
+ case hwmon_temp_input:
+ case hwmon_temp_max_hyst:
+ case hwmon_temp_max_alarm:
+ case hwmon_temp_emergency_hyst:
+ case hwmon_temp_emergency_alarm:
+ case hwmon_temp_fault:
+ return 0444;
+ case hwmon_temp_label:
+ if (max31760->temp_label[channel])
+ return 0444;
+ return 0;
+ case hwmon_temp_max:
+ case hwmon_temp_emergency:
+ return 0644;
+ }
+ break;
+ case hwmon_fan:
+ switch (attr) {
+ case hwmon_fan_input:
+ case hwmon_fan_fault:
+ case hwmon_fan_min_alarm:
+ return 0444;
+ case hwmon_fan_label:
+ if (max31760->fan_label[channel])
+ return 0444;
+ return 0;
+ case hwmon_fan_min:
+ case hwmon_fan_pulses:
+ return 0644;
+ }
+ break;
+ case hwmon_pwm:
+ switch (attr) {
+ case hwmon_pwm_input:
+ case hwmon_pwm_enable:
+ case hwmon_pwm_freq:
+ return 0644;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static u32 max31760_chip_config[] = {
+ HWMON_C_REGISTER_TZ,
+ 0
+};
+
+static const struct hwmon_channel_info max31760_chip = {
+ .type = hwmon_chip,
+ .config = max31760_chip_config,
+};
+
+static u32 max31760_temp_config[] = {
+ /* Local temperature sensor:
+ * Local high set point (LHS) -> MAX,
+ * Local over-temperature set point (LOTS) -> EMERGENCY
+ */
+ HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_MAX | HWMON_T_EMERGENCY |
+ HWMON_T_MAX_ALARM | HWMON_T_EMERGENCY_ALARM |
+ HWMON_T_MAX_HYST | HWMON_T_EMERGENCY_HYST,
+ /* Remote temperature sensor:
+ * Remote high set point (RHS) -> MAX,
+ * Remote over-temperature set point (ROTS) -> EMERGENCY
+ */
+ HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_FAULT | HWMON_T_MAX |
+ HWMON_T_EMERGENCY | HWMON_T_MAX_ALARM |
+ HWMON_T_EMERGENCY_ALARM | HWMON_T_MAX_HYST |
+ HWMON_T_EMERGENCY_HYST,
+ 0
+};
+
+static const struct hwmon_channel_info max31760_temp = {
+ .type = hwmon_temp,
+ .config = max31760_temp_config,
+};
+
+static u32 max31760_fan_config[] = {
+ HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MIN_ALARM | HWMON_F_PULSES |
+ HWMON_F_FAULT | HWMON_F_LABEL,
+ HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MIN_ALARM | HWMON_F_PULSES |
+ HWMON_F_FAULT | HWMON_F_LABEL,
+ 0
+};
+
+static const struct hwmon_channel_info max31760_fan = {
+ .type = hwmon_fan,
+ .config = max31760_fan_config,
+};
+
+static u32 max31760_pwm_config[] = {
+ HWMON_PWM_INPUT | HWMON_PWM_ENABLE | HWMON_PWM_FREQ,
+ 0
+};
+
+static const struct hwmon_channel_info max31760_pwm = {
+ .type = hwmon_pwm,
+ .config = max31760_pwm_config,
+};
+
+static const struct hwmon_channel_info *max31760_info[] = {
+ &max31760_chip,
+ &max31760_temp,
+ &max31760_fan,
+ &max31760_pwm,
+ NULL
+};
+
+static const struct hwmon_ops max31760_hwmon_ops = {
+ .is_visible = max31760_is_visible,
+ .read = max31760_read,
+ .read_string = max31760_read_string,
+ .write = max31760_write,
+};
+
+static const struct hwmon_chip_info max31760_chip_info = {
+ .ops = &max31760_hwmon_ops,
+ .info = max31760_info,
+};
+
+static ssize_t max31760_pwm_auto_channels_temp_show(
+ struct device *dev, struct device_attribute *devattr, char *buf)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ unsigned int regval;
+ int channels;
+ int err;
+
+ err = regmap_read(max31760->regmap, MAX31760_REG_CR1, ®val);
+ if (err < 0)
+ return err;
+
+ /* Auto channels is a bit-field. TIS bit clear: temp1 (local) is used
+ * for the LUT. TIS bit set: temp2 (remote) is used for the LUT.
+ * MTI bit set: maximum temp from both is used, TIS bit is ignored.
+ */
+ if (regval & MAX31760_CR1_MTI)
+ channels = 3;
+ else if (regval & MAX31760_CR1_TIS)
+ channels = 2;
+ else
+ channels = 1;
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", channels);
+}
+
+static ssize_t max31760_pwm_auto_channels_temp_store(
+ struct device *dev, struct device_attribute *devattr,
+ const char *buf, size_t count)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ unsigned int regval;
+ unsigned int mask;
+ unsigned long channels;
+ int err;
+
+ err = kstrtoul(buf, 10, &channels);
+ if (err < 0)
+ return err;
+
+ switch (channels & 0x3) {
+ case 3:
+ mask = MAX31760_CR1_MTI;
+ regval = MAX31760_CR1_MTI;
+ break;
+ case 1:
+ mask = MAX31760_CR1_TIS | MAX31760_CR1_MTI;
+ regval = 0;
+ break;
+ default:
+ case 2:
+ mask = MAX31760_CR1_TIS | MAX31760_CR1_MTI;
+ regval = MAX31760_CR1_TIS;
+ break;
+ }
+
+ err = regmap_update_bits(max31760->regmap, MAX31760_REG_CR1, mask,
+ regval);
+ if (err < 0)
+ return err;
+
+ return count;
+}
+
+static ssize_t max31760_pwm_auto_point_pwm_show(
+ struct device *dev, struct device_attribute *devattr, char *buf)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ struct sensor_device_attribute *sensor_dev_attr =
+ to_sensor_dev_attr(devattr);
+ unsigned int reg = MAX31760_REG_LUT + sensor_dev_attr->index;
+ unsigned int regval;
+ int err;
+
+ err = regmap_read(max31760->regmap, reg, ®val);
+ if (err < 0)
+ return err;
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", regval);
+}
+
+static ssize_t max31760_pwm_auto_point_pwm_store(
+ struct device *dev, struct device_attribute *devattr,
+ const char *buf, size_t count)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ struct sensor_device_attribute *sensor_dev_attr =
+ to_sensor_dev_attr(devattr);
+ unsigned int reg = MAX31760_REG_LUT + sensor_dev_attr->index;
+ unsigned int regval;
+ unsigned long pwm;
+ int err;
+
+ err = kstrtoul(buf, 10, &pwm);
+ if (err < 0)
+ return err;
+ regval = pwm & 0xff;
+
+ err = regmap_write(max31760->regmap, reg, regval);
+ if (err < 0)
+ return err;
+
+ return count;
+}
+
+static int max31760_pwm_auto_point_temp(int index)
+{
+ if (index == 0)
+ return MAX31760_TEMP_LUT_MIN_MC;
+ else
+ return (16 + index * 2) * 1000;
+}
+
+static ssize_t max31760_pwm_auto_point_temp_show(
+ struct device *dev, struct device_attribute *devattr, char *buf)
+{
+ struct sensor_device_attribute *sensor_dev_attr =
+ to_sensor_dev_attr(devattr);
+ int temp = max31760_pwm_auto_point_temp(sensor_dev_attr->index);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", temp);
+}
+
+static ssize_t max31760_pwm_auto_point_temp_hyst_show(
+ struct device *dev, struct device_attribute *devattr, char *buf)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ struct sensor_device_attribute *sensor_dev_attr =
+ to_sensor_dev_attr(devattr);
+ int temp = max31760_pwm_auto_point_temp(sensor_dev_attr->index);
+ unsigned int regval;
+ int err;
+
+ err = regmap_read(max31760->regmap, MAX31760_REG_CR1, ®val);
+ if (err < 0)
+ return err;
+
+ if (regval & MAX31760_CR1_HYST)
+ temp -= MAX31760_LUT_HYST_SET;
+ else
+ temp -= MAX31760_LUT_HYST_CLEAR;
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", temp);
+}
+
+static ssize_t max31760_pwm_auto_point_temp_hyst_store(
+ struct device *dev, struct device_attribute *devattr,
+ const char *buf, size_t count)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ struct sensor_device_attribute *sensor_dev_attr =
+ to_sensor_dev_attr(devattr);
+ int temp = max31760_pwm_auto_point_temp(sensor_dev_attr->index);
+ unsigned int regval;
+ long hyst;
+ int err;
+
+ err = kstrtol(buf, 10, &hyst);
+ if (err < 0)
+ return err;
+
+ temp -= hyst;
+ if (temp >= MAX31760_LYT_HYST_THRESH)
+ regval = MAX31760_CR1_HYST;
+ else
+ regval = 0;
+ err = regmap_update_bits(max31760->regmap, MAX31760_REG_CR1,
+ MAX31760_CR1_HYST, regval);
+ if (err < 0)
+ return err;
+ return count;
+}
+
+static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, 0644,
+ max31760_pwm_auto_channels_temp_show,
+ max31760_pwm_auto_channels_temp_store, 0);
+static struct attribute *max31760_attrs[] = {
+ &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr,
+ NULL
+};
+static const struct attribute_group max31760_group = {
+ .attrs = max31760_attrs,
+};
+
+static ssize_t max31760_control_store(struct device *dev,
+ struct device_attribute *devattr,
+ const char *buf, size_t count)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ int err;
+
+ if (sysfs_streq(buf, "reset")) {
+ err = regmap_update_bits(max31760->regmap, MAX31760_REG_CR1,
+ MAX31760_CR1_POR, MAX31760_CR1_POR);
+ if (err < 0)
+ return err;
+ } else if (sysfs_streq(buf, "clearff")) {
+ err = regmap_update_bits(max31760->regmap, MAX31760_REG_CR3,
+ MAX31760_CR3_CLR_FF,
+ MAX31760_CR3_CLR_FF);
+ if (err < 0)
+ return err;
+ } else {
+ return -EINVAL;
+ }
+
+ return count;
+}
+
+static ssize_t max31760_eeprom_read_store(struct device *dev,
+ struct device_attribute *devattr,
+ const char *buf, size_t count)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ unsigned long sections;
+ unsigned int regval;
+ int err;
+
+ err = kstrtoul(buf, 10, §ions);
+ if (err < 0)
+ return err;
+
+ if (sections == 0)
+ regval = MAX31760_EEX_BLKS;
+ else
+ regval = sections & MAX31760_EEX_BLKS;
+ regval |= MAX31760_EEX_LW;
+
+ err = regmap_write(max31760->regmap, MAX31760_REG_EEX, regval);
+ if (err < 0)
+ return err;
+
+ return count;
+}
+
+static ssize_t max31760_eeprom_write_store(struct device *dev,
+ struct device_attribute *devattr,
+ const char *buf, size_t count)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ unsigned long sections;
+ unsigned int regval;
+ int err;
+
+ err = kstrtoul(buf, 10, §ions);
+ if (err < 0)
+ return err;
+
+ if (sections == 0)
+ regval = MAX31760_EEX_BLKS;
+ else
+ regval = sections & MAX31760_EEX_BLKS;
+
+ err = regmap_write(max31760->regmap, MAX31760_REG_EEX, regval);
+ if (err < 0)
+ return err;
+
+ return count;
+}
+
+static ssize_t max31760_pwm_fan_fault_show(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ unsigned int regval;
+ int err;
+
+ err = regmap_read(max31760->regmap, MAX31760_REG_FFDC, ®val);
+ if (err < 0)
+ return err;
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", regval);
+}
+
+static ssize_t max31760_pwm_fan_fault_store(struct device *dev,
+ struct device_attribute *devattr,
+ const char *buf, size_t count)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ unsigned int regval;
+ unsigned long val;
+ int err;
+
+ err = kstrtoul(buf, 10, &val);
+ if (err)
+ return err;
+ regval = val & 0xff;
+
+ err = regmap_write(max31760->regmap, MAX31760_REG_FFDC, regval);
+ if (err < 0)
+ return err;
+ return count;
+}
+
+static ssize_t max31760_pwm_ramp_rate_show(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ unsigned int regval;
+ int err;
+
+ err = regmap_read(max31760->regmap, MAX31760_REG_CR3, ®val);
+ if (err < 0)
+ return err;
+ switch (regval & MAX31760_CR3_RAMP) {
+ case MAX31760_RAMP_SLOW:
+ regval = 8;
+ break;
+ case MAX31760_RAMP_SMED:
+ regval = 16;
+ break;
+ case MAX31760_RAMP_MEDF:
+ regval = 32;
+ break;
+ case MAX31760_RAMP_FAST:
+ regval = 255;
+ break;
+ }
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", regval);
+}
+
+static ssize_t max31760_pwm_ramp_rate_store(struct device *dev,
+ struct device_attribute *devattr,
+ const char *buf, size_t count)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ unsigned int regval;
+ unsigned long val;
+ int err;
+
+ err = kstrtoul(buf, 10, &val);
+ if (err)
+ return err;
+ if (val <= 12)
+ regval = MAX31760_RAMP_SLOW;
+ else if (val <= 24)
+ regval = MAX31760_RAMP_SMED;
+ else if (val <= 143)
+ regval = MAX31760_RAMP_MEDF;
+ else
+ regval = MAX31760_RAMP_FAST;
+
+ err = regmap_update_bits(max31760->regmap, MAX31760_REG_CR3,
+ MAX31760_CR3_RAMP, regval);
+ if (err < 0)
+ return err;
+ return count;
+}
+
+static SENSOR_DEVICE_ATTR(control, 0200, NULL, max31760_control_store, 0);
+static SENSOR_DEVICE_ATTR(eeprom_read, 0200, NULL, max31760_eeprom_read_store,
+ 0);
+static SENSOR_DEVICE_ATTR(eeprom_write, 0200, NULL, max31760_eeprom_write_store,
+ 0);
+static SENSOR_DEVICE_ATTR(pwm1_fan_fault, 0644, max31760_pwm_fan_fault_show,
+ max31760_pwm_fan_fault_store, 0);
+static SENSOR_DEVICE_ATTR(pwm1_ramp_rate, 0644, max31760_pwm_ramp_rate_show,
+ max31760_pwm_ramp_rate_store, 0);
+
+static struct attribute *max31760_custom_attrs[] = {
+ &sensor_dev_attr_control.dev_attr.attr,
+ &sensor_dev_attr_eeprom_read.dev_attr.attr,
+ &sensor_dev_attr_eeprom_write.dev_attr.attr,
+ &sensor_dev_attr_pwm1_fan_fault.dev_attr.attr,
+ &sensor_dev_attr_pwm1_ramp_rate.dev_attr.attr,
+ NULL
+};
+static const struct attribute_group max31760_custom_group = {
+ .name = "custom",
+ .attrs = max31760_custom_attrs,
+};
+
+static void max31760_setup_attr_groups(struct device *dev)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ struct max31760_dev_attr *lut_dev_attr = max31760->lut_dev_attrs;
+ struct device_attribute *dev_attr;
+ int attr_index = 0;
+ int i;
+
+ for (i = 0; i < MAX31760_LUT_COUNT; i++, lut_dev_attr++) {
+ snprintf(lut_dev_attr->name, MAX31760_LUT_NAME_SIZE,
+ "pwm1_auto_point%02d_pwm", i);
+ lut_dev_attr->sdattr.index = i;
+ dev_attr = &lut_dev_attr->sdattr.dev_attr;
+ dev_attr->attr.name = lut_dev_attr->name;
+ dev_attr->attr.mode = 0644;
+ dev_attr->show = max31760_pwm_auto_point_pwm_show;
+ dev_attr->store = max31760_pwm_auto_point_pwm_store;
+ max31760->lut_attrs[attr_index++] =
+ &lut_dev_attr->sdattr.dev_attr.attr;
+ }
+
+ for (i = 0; i < MAX31760_LUT_COUNT; i++, lut_dev_attr++) {
+ snprintf(lut_dev_attr->name, MAX31760_LUT_NAME_SIZE,
+ "pwm1_auto_point%02d_temp", i);
+ lut_dev_attr->sdattr.index = i;
+ dev_attr = &lut_dev_attr->sdattr.dev_attr;
+ dev_attr->attr.name = lut_dev_attr->name;
+ dev_attr->attr.mode = 0444;
+ dev_attr->show = max31760_pwm_auto_point_temp_show;
+ max31760->lut_attrs[attr_index++] =
+ &lut_dev_attr->sdattr.dev_attr.attr;
+ }
+
+ for (i = 0; i < MAX31760_LUT_COUNT; i++, lut_dev_attr++) {
+ snprintf(lut_dev_attr->name, MAX31760_LUT_NAME_SIZE,
+ "pwm1_auto_point%02d_temp_hyst", i);
+ lut_dev_attr->sdattr.index = i;
+ dev_attr = &lut_dev_attr->sdattr.dev_attr;
+ dev_attr->attr.name = lut_dev_attr->name;
+ dev_attr->attr.mode = 0644;
+ dev_attr->show = max31760_pwm_auto_point_temp_hyst_show;
+ dev_attr->store = max31760_pwm_auto_point_temp_hyst_store;
+ max31760->lut_attrs[attr_index++] =
+ &lut_dev_attr->sdattr.dev_attr.attr;
+ }
+
+ max31760->lut_group.attrs = max31760->lut_attrs;
+ max31760->attr_groups[0] = &max31760->lut_group;
+ max31760->attr_groups[1] = &max31760_group;
+ max31760->attr_groups[2] = &max31760_custom_group;
+}
+
+static int max31760_update_from_registers(struct device *dev)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ long val;
+ int i;
+ int err;
+
+ for (i = 0; i < MAX31760_NUM_FANS; i++) {
+ err = max31760_read_fan(dev, hwmon_fan_pulses, i, &val);
+ if (err)
+ return err;
+ max31760->fan_pulses[i] = val;
+ }
+
+ /* Clear standby bit in case it is set. */
+ return regmap_update_bits(max31760->regmap, MAX31760_REG_CR2,
+ MAX31760_CR2_STBY, 0);
+}
+
+static int max31760_of_init(struct device *dev)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ const char *label;
+ int err;
+ u32 val;
+
+ err = device_property_read_u32(dev, "maxim,fan1-enabled", &val);
+ if (!err) {
+ err = regmap_update_bits(max31760->regmap, MAX31760_REG_CR3,
+ MAX31760_CR3_TACH1E,
+ val ? MAX31760_CR3_TACH1E : 0);
+ if (err)
+ return err;
+ }
+
+ err = device_property_read_u32(dev, "maxim,fan2-enabled", &val);
+ if (!err) {
+ err = regmap_update_bits(max31760->regmap, MAX31760_REG_CR3,
+ MAX31760_CR3_TACH2E,
+ val ? MAX31760_CR3_TACH2E : 0);
+ if (err)
+ return err;
+ }
+
+ err = device_property_read_string(dev, "maxim,fan1-label", &label);
+ if (!err)
+ max31760->fan_label[0] = label;
+
+ err = device_property_read_string(dev, "maxim,fan2-label", &label);
+ if (!err)
+ max31760->fan_label[1] = label;
+
+ err = device_property_read_u32(dev, "maxim,fan-fail-full-only",
+ &val);
+ if (!err) {
+ err = regmap_update_bits(max31760->regmap, MAX31760_REG_CR3,
+ MAX31760_CR3_TACHFL,
+ val ? MAX31760_CR3_TACHFL : 0);
+ if (err)
+ return err;
+ }
+
+ err = device_property_read_u32(dev, "maxim,fan-spin-up-enabled", &val);
+ if (!err) {
+ err = regmap_update_bits(max31760->regmap, MAX31760_REG_CR2,
+ MAX31760_CR2_SPEN,
+ val ? MAX31760_CR2_SPEN : 0);
+ if (err)
+ return err;
+ }
+
+ err = device_property_read_u32(dev, "maxim,fan-rd-signal", &val);
+ if (!err) {
+ err = regmap_update_bits(max31760->regmap, MAX31760_REG_CR2,
+ MAX31760_CR2_FSST,
+ val ? MAX31760_CR2_FSST : 0);
+ if (err)
+ return err;
+ }
+
+ err = device_property_read_u32(dev, "maxim,fan-rd-polarity", &val);
+ if (!err) {
+ err = regmap_update_bits(max31760->regmap, MAX31760_REG_CR2,
+ MAX31760_CR2_RDPS,
+ val ? MAX31760_CR2_RDPS : 0);
+ if (err)
+ return err;
+ }
+
+ err = device_property_read_u32(dev, "maxim,fan-signal-enabled", &val);
+ if (!err) {
+ err = regmap_update_bits(max31760->regmap, MAX31760_REG_CR2,
+ MAX31760_CR2_FSEN,
+ val ? MAX31760_CR2_FSEN : 0);
+ if (err)
+ return err;
+ }
+
+ err = device_property_read_u32(dev, "maxim,pwm-polarity", &val);
+ if (!err) {
+ err = regmap_update_bits(max31760->regmap, MAX31760_REG_CR1,
+ MAX31760_CR1_PPS,
+ val ? MAX31760_CR1_PPS : 0);
+ if (err)
+ return err;
+ }
+
+ err = device_property_read_u32(dev, "maxim,pwm-pulse-stretch-enabled",
+ &val);
+ if (!err) {
+ err = regmap_update_bits(max31760->regmap, MAX31760_REG_CR3,
+ MAX31760_CR3_PSEN,
+ val ? MAX31760_CR3_PSEN : 0);
+ if (err)
+ return err;
+ }
+
+ err = device_property_read_u32(dev, "maxim,pwm-zero-fan-can-fail",
+ &val);
+ if (!err) {
+ err = regmap_update_bits(max31760->regmap, MAX31760_REG_CR3,
+ MAX31760_CR3_FF_0,
+ val ? MAX31760_CR3_FF_0 : 0);
+ if (err)
+ return err;
+ }
+
+ err = device_property_read_string(dev, "maxim,temp1-label", &label);
+ if (!err)
+ max31760->temp_label[0] = label;
+
+ err = device_property_read_string(dev, "maxim,temp2-label", &label);
+ if (!err)
+ max31760->temp_label[1] = label;
+
+ err = device_property_read_u32(dev, "maxim,temp2-ideality", &val);
+ if (!err) {
+ err = regmap_write(max31760->regmap, MAX31760_REG_IFR,
+ val & 0x3f);
+ if (err)
+ return err;
+ }
+
+ /* Firmware configuration parameters planned:
+ * maxim,fan-fail-interrupt -> MAX31760_CR2_FFMODE
+ * maxim,temp-alert-interrupt -> MAX31760_CR2_ALERTS (default true)
+ */
+
+ /* Put ALERT pin into comparator mode: interrupts aren't supported. */
+ return regmap_update_bits(max31760->regmap, MAX31760_REG_CR2,
+ MAX31760_CR2_ALERTS, MAX31760_CR2_ALERTS);
+}
+
+static int max31760_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct device *dev = &client->dev;
+ struct device *hwmon_dev;
+ struct max31760 *max31760;
+ int err;
+
+ max31760 = devm_kzalloc(dev, sizeof(*max31760), GFP_KERNEL);
+ if (!max31760)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, max31760);
+
+ max31760->regmap = devm_regmap_init_i2c(client,
+ &max31760_regmap_config);
+ if (IS_ERR(max31760->regmap)) {
+ err = PTR_ERR(max31760->regmap);
+ dev_err(dev, "regmap init failed: %d", err);
+ return err;
+ }
+
+ err = max31760_of_init(dev);
+ if (err) {
+ dev_err(dev, "failed to initialize from firmware: %d", err);
+ return err;
+ }
+
+ err = max31760_update_from_registers(dev);
+ if (err) {
+ dev_err(dev, "failed to update from registers: %d", err);
+ return err;
+ }
+
+ max31760_setup_attr_groups(dev);
+ hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
+ max31760,
+ &max31760_chip_info,
+ max31760->attr_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+static int __maybe_unused max31760_suspend(struct device *dev)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+
+ return regmap_update_bits(max31760->regmap, MAX31760_REG_CR2,
+ MAX31760_CR2_STBY, MAX31760_CR2_STBY);
+}
+
+static int __maybe_unused max31760_resume(struct device *dev)
+{
+ struct max31760 *max31760 = dev_get_drvdata(dev);
+ int err;
+
+ err = regmap_update_bits(max31760->regmap, MAX31760_REG_CR2,
+ MAX31760_CR2_STBY, 0);
+ if (err)
+ dev_err(dev, "Could not clear Standby bit: %d", err);
+ return err;
+}
+
+static SIMPLE_DEV_PM_OPS(max31760_dev_pm_ops, max31760_suspend,
+ max31760_resume);
+
+static const struct i2c_device_id max31760_i2c_ids[] = {
+ { "max31760", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, max31760_i2c_ids);
+
+#ifdef CONFIG_OF
+static const struct of_device_id max31760_of_ids[] = {
+ { .compatible = "maxim,max31760", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, max31760_of_ids);
+#endif
+
+static struct i2c_driver max31760_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .pm = &max31760_dev_pm_ops,
+ .of_match_table = of_match_ptr(max31760_of_ids),
+ },
+ .probe = max31760_probe,
+ .id_table = max31760_i2c_ids,
+};
+
+module_i2c_driver(max31760_driver);
+
+MODULE_AUTHOR("John Muir <john@jmuir.com>");
+MODULE_DESCRIPTION("Maxim Integrated MAX31760 Precision Fan-Speed Controller Driver");
+MODULE_LICENSE("GPL");
--
2.12.2.715.g7642488e1d-goog
^ permalink raw reply related
* [PATCH 0/2] Add Maxim Integrated MAX31760 fan controller driver.
From: John Muir @ 2017-04-04 19:20 UTC (permalink / raw)
To: Jean Delvare, Guenter Roeck, Jonathan Corbet, Rob Herring,
Pawel Moll, Ian Campbell, Kumar Gala, devicetree, linux-hwmon,
linux-doc
Cc: John Muir, Anatol Pomazau, Mark Segal
Add a device driver for the MAX31760 I2C device with a hwmon interface and
a few open firmware device properties.
John Muir (2):
hwmon: Add MAX31760 fan controller driver.
devicetree: Document the max31760 device binding.
.../devicetree/bindings/hwmon/max31760.txt | 58 +
Documentation/hwmon/max31760 | 41 +
drivers/hwmon/Kconfig | 10 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/max31760.c | 1430 ++++++++++++++++++++
5 files changed, 1540 insertions(+)
create mode 100644 Documentation/devicetree/bindings/hwmon/max31760.txt
create mode 100644 Documentation/hwmon/max31760
create mode 100644 drivers/hwmon/max31760.c
--
2.12.2.715.g7642488e1d-goog
^ permalink raw reply
* Re: [PATCH v2 2/2] of/pci: Fix memory leak in of_pci_get_host_bridge_resources
From: Bjorn Helgaas @ 2017-04-04 19:18 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Rob Herring, Jeffy Chen,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
toshi.kani-ZPxbGqLxI0U, Shawn Lin, Brian Norris, Doug Anderson,
Frank Rowand, devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <CAE_wzQ9ZVDiDGP4k_2i2KL4JxtRn_S7gjFXUTYZncMLx2m77gQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Thu, Mar 23, 2017 at 5:58 PM, Dmitry Torokhov <dtor-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org> wrote:
> On Thu, Mar 23, 2017 at 3:07 PM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>> On Thu, Mar 23, 2017 at 3:12 AM, Jeffy Chen <jeffy.chen-TNX95d0MmH7DzftRWevZcw@public.gmane.org> wrote:
>>> Currently we only free the allocated resource struct when error.
>>> This would cause memory leak after pci_free_resource_list.
>>>
>>> Signed-off-by: Jeffy Chen <jeffy.chen-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
>>> ---
>>>
>>> Changes in v2:
>>> Don't change the resource_list_create_entry's behavior.
>>>
>>> drivers/of/of_pci.c | 57 +++++++++++++++++++++++------------------------------
>>> 1 file changed, 25 insertions(+), 32 deletions(-)
>>>
>>> diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
>>> index 0ee42c3..a0ec246 100644
>>> --- a/drivers/of/of_pci.c
>>> +++ b/drivers/of/of_pci.c
>>> @@ -190,8 +190,7 @@ int of_pci_get_host_bridge_resources(struct device_node *dev,
>>> struct list_head *resources, resource_size_t *io_base)
>>> {
>>> struct resource_entry *window;
>>> - struct resource *res;
>>> - struct resource *bus_range;
>>> + struct resource res;
>>> struct of_pci_range range;
>>> struct of_pci_range_parser parser;
>>> char range_type[4];
>>> @@ -200,24 +199,24 @@ int of_pci_get_host_bridge_resources(struct device_node *dev,
>>> if (io_base)
>>> *io_base = (resource_size_t)OF_BAD_ADDR;
>>>
>>> - bus_range = kzalloc(sizeof(*bus_range), GFP_KERNEL);
>>> - if (!bus_range)
>>> - return -ENOMEM;
>>> -
>>> pr_info("host bridge %s ranges:\n", dev->full_name);
>>>
>>> - err = of_pci_parse_bus_range(dev, bus_range);
>>> + err = of_pci_parse_bus_range(dev, &res);
>>> if (err) {
>>> - bus_range->start = busno;
>>> - bus_range->end = bus_max;
>>> - bus_range->flags = IORESOURCE_BUS;
>>> - pr_info(" No bus range found for %s, using %pR\n",
>>> - dev->full_name, bus_range);
>>> + res.start = busno;
>>> + res.end = bus_max;
>>> + res.flags = IORESOURCE_BUS;
>>> + pr_info(" No bus range found for %s\n", dev->full_name);
>>> } else {
>>> - if (bus_range->end > bus_range->start + bus_max)
>>> - bus_range->end = bus_range->start + bus_max;
>>> + if (res.end > res.start + bus_max)
>>> + res.end = res.start + bus_max;
>>> + }
>>> + window = pci_add_resource(resources, NULL);
>>> + if (!window) {
>>> + err = -ENOMEM;
>>> + goto parse_failed;
>>> }
>>> - pci_add_resource(resources, bus_range);
>>> + *window->res = res;
>>
>> Well, now this seems racy. You add a blank resource to the list first
>> and then fill it in.
>>
>
> Huh? There is absolutely no guarantees for concurrent access here.
> pcI_add_resource_offset() first adds a resource and then modifies
> offset. Here we add an empty resource and then fill it in.
I don't really like this pattern either. Even if there's no actual
racy behavior, it takes more analysis than necessary to figure that
out.
pci_add_resource_offset() allocates a resource list entry, sets the
offset, then adds it to the list. It doesn't update a resource entry
that might be visible to anybody else. Here we do update a resource
that is already visible to others because it's already on the list.
Bjorn
BTW, please CC linux-pci on the entire series so it's easier to
review. I don't know where you envision having this applied, but I
only apply things to the PCI tree after they appear on linux-pci.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v4 19/23] drivers/fsi: Add GPIO based FSI master (fwd)
From: Christopher Bostic @ 2017-04-04 19:10 UTC (permalink / raw)
To: Julia Lawall
Cc: joel-U3u1mxZcP9KHXe+LvDLADg, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
andrew-zrmu5oMJ5Fs, alistair-Y4h6yKqj69EXC2x5gXVKYQ,
benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r, Edward A . James,
Jeremy Kerr, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, linux-I+IVW8TIWO2tmTQ+vhA3Yw,
rostedt-nx8X9YLhiw1AfugRpC6u6w, mingo-H+wXaHxf7aLQT0dZR+AlfA,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
kbuild-all-JC7UmRfGjtg
In-Reply-To: <alpine.DEB.2.20.1703302337590.2105@hadrien>
On 3/30/17 4:39 PM, Julia Lawall wrote:
> Is master on line 514 allocated with kmalloc, or the devm call on line
> 522?
Hi Julia,
Its allocated with the devm call on line 522. The kfree on line 514
wouldn't be necessary in that case - will remove.
Thanks for pointing that out.
Chris
> julia
>
> ---------- Forwarded message ----------
> Date: Fri, 31 Mar 2017 00:15:09 +0800
> From: kbuild test robot <fengguang.wu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> To: kbuild-JC7UmRfGjtg@public.gmane.org
> Cc: Julia Lawall <julia.lawall-L2FTfq7BK8M@public.gmane.org>
> Subject: Re: [PATCH v4 19/23] drivers/fsi: Add GPIO based FSI master
>
> Hi Chris,
>
> [auto build test WARNING on linus/master]
> [also build test WARNING on v4.11-rc4 next-20170330]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url: https://github.com/0day-ci/linux/commits/Christopher-Bostic/FSI-device-driver-implementation/20170330-184914
> :::::: branch date: 5 hours ago
> :::::: commit date: 5 hours ago
>
>>> drivers/fsi/fsi-master-gpio.c:514:1-6: WARNING: invalid free of devm_ allocated data
> git remote add linux-review https://github.com/0day-ci/linux
> git remote update linux-review
> git checkout f4bd3b6a41c7a59e9ce2e65947a4d3dfc2ee4a29
> vim +514 drivers/fsi/fsi-master-gpio.c
>
> f4bd3b6a Chris Bostic 2017-03-29 498 {
> f4bd3b6a Chris Bostic 2017-03-29 499 struct fsi_master_gpio *master = to_fsi_master_gpio(_master);
> f4bd3b6a Chris Bostic 2017-03-29 500
> f4bd3b6a Chris Bostic 2017-03-29 501 if (link != 0)
> f4bd3b6a Chris Bostic 2017-03-29 502 return -ENODEV;
> f4bd3b6a Chris Bostic 2017-03-29 503 if (master->gpio_enable)
> f4bd3b6a Chris Bostic 2017-03-29 504 gpiod_set_value(master->gpio_enable, 1);
> f4bd3b6a Chris Bostic 2017-03-29 505
> f4bd3b6a Chris Bostic 2017-03-29 506 return 0;
> f4bd3b6a Chris Bostic 2017-03-29 507 }
> f4bd3b6a Chris Bostic 2017-03-29 508
> f4bd3b6a Chris Bostic 2017-03-29 509 static void fsi_master_gpio_release(struct device *dev)
> f4bd3b6a Chris Bostic 2017-03-29 510 {
> f4bd3b6a Chris Bostic 2017-03-29 511 struct fsi_master_gpio *master = to_fsi_master_gpio(
> f4bd3b6a Chris Bostic 2017-03-29 512 dev_to_fsi_master(dev));
> f4bd3b6a Chris Bostic 2017-03-29 513
> f4bd3b6a Chris Bostic 2017-03-29 @514 kfree(master);
> f4bd3b6a Chris Bostic 2017-03-29 515 }
> f4bd3b6a Chris Bostic 2017-03-29 516
> f4bd3b6a Chris Bostic 2017-03-29 517 static int fsi_master_gpio_probe(struct platform_device *pdev)
> f4bd3b6a Chris Bostic 2017-03-29 518 {
> f4bd3b6a Chris Bostic 2017-03-29 519 struct fsi_master_gpio *master;
> f4bd3b6a Chris Bostic 2017-03-29 520 struct gpio_desc *gpio;
> f4bd3b6a Chris Bostic 2017-03-29 521
> f4bd3b6a Chris Bostic 2017-03-29 522 master = devm_kzalloc(&pdev->dev, sizeof(*master), GFP_KERNEL);
>
> ---
> 0-DAY kernel test infrastructure Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all Intel Corporation
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 3/3] arm64: allwinner: a64: enable EHCI0/OHCI0 controller for Pine64
From: Icenowy Zheng @ 2017-04-04 18:45 UTC (permalink / raw)
To: Maxime Ripard, Chen-Yu Tsai, Kishon Vijay Abraham I
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170404184518.33610-1-icenowy-h8G6r0blFSE@public.gmane.org>
The upper USB port of Pine64 board is connected to the SoC's USB0 port,
which can now switch from the MUSB controller to the EHCI/OHCI pair.
Enable the EHCI/OHCI pair in the Pine64 device tree.
Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
---
arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
index c680ed385da3..4782add50b94 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
@@ -66,6 +66,10 @@
};
};
+&ehci0 {
+ status = "okay";
+};
+
&ehci1 {
status = "okay";
};
@@ -91,6 +95,10 @@
status = "okay";
};
+&ohci0 {
+ status = "okay";
+};
+
&ohci1 {
status = "okay";
};
--
2.12.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 2/3] arm64: allwinner: a64: add USB0 OHCI/EHCI related devicetree parts
From: Icenowy Zheng @ 2017-04-04 18:45 UTC (permalink / raw)
To: Maxime Ripard, Chen-Yu Tsai, Kishon Vijay Abraham I
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170404184518.33610-1-icenowy-h8G6r0blFSE@public.gmane.org>
As we added USB0 route auto switching support for A64, add related
device tree parts to the A64 DTSI file (EHCI0/OHCI0 controllers and the
pmu0 memory area for PHY).
Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
---
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 1c64ea2d23f9..a8916df99048 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -179,8 +179,10 @@
usbphy: phy@01c19400 {
compatible = "allwinner,sun50i-a64-usb-phy";
reg = <0x01c19400 0x14>,
+ <0x01c1a800 0x4>,
<0x01c1b800 0x4>;
reg-names = "phy_ctrl",
+ "pmu0",
"pmu1";
clocks = <&ccu CLK_USB_PHY0>,
<&ccu CLK_USB_PHY1>;
@@ -194,6 +196,28 @@
#phy-cells = <1>;
};
+ ehci0: usb@01c1a000 {
+ compatible = "allwinner,sun50i-a64-ehci", "generic-ehci";
+ reg = <0x01c1a000 0x100>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_OHCI0>,
+ <&ccu CLK_BUS_EHCI0>,
+ <&ccu CLK_USB_OHCI0>;
+ resets = <&ccu RST_BUS_OHCI0>,
+ <&ccu RST_BUS_EHCI0>;
+ status = "disabled";
+ };
+
+ ohci0: usb@01c1a400 {
+ compatible = "allwinner,sun50i-a64-ohci", "generic-ohci";
+ reg = <0x01c1a400 0x100>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_OHCI0>,
+ <&ccu CLK_USB_OHCI0>;
+ resets = <&ccu RST_BUS_OHCI0>;
+ status = "disabled";
+ };
+
ehci1: usb@01c1b000 {
compatible = "allwinner,sun50i-a64-ehci", "generic-ehci";
reg = <0x01c1b000 0x100>;
--
2.12.2
^ permalink raw reply related
* [PATCH 1/3] phy: sun4i-usb: enable PHY0 dual route switching for A64 USB PHY
From: Icenowy Zheng @ 2017-04-04 18:45 UTC (permalink / raw)
To: Maxime Ripard, Chen-Yu Tsai, Kishon Vijay Abraham I
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
Allwinner A64 SoC features a switchable PHY0 like the one in H3, which
can switch between a MUSB controller and a pair of OHCI/EHCI controller.
Enable PHY0 route auto switching for A64.
Signed-off-by: Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>
---
drivers/phy/phy-sun4i-usb.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
index f86a2574b953..bbf06cfe5898 100644
--- a/drivers/phy/phy-sun4i-usb.c
+++ b/drivers/phy/phy-sun4i-usb.c
@@ -858,6 +858,7 @@ static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
.phyctl_offset = REG_PHYCTL_A33,
.dedicated_clocks = true,
.enable_pmu_unk1 = true,
+ .phy0_dual_route = true,
};
static const struct of_device_id sun4i_usb_phy_of_match[] = {
--
2.12.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH 0/2] ARM: dts: keystone: Add support for new K2G evm
From: Franklin S Cooper Jr @ 2017-04-04 18:42 UTC (permalink / raw)
To: Santosh Shilimkar, ssantosh-DgEjT+Ai2ygdnm+yROfE0A,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, linux-I+IVW8TIWO2tmTQ+vhA3Yw
In-Reply-To: <b3f2604f-2649-6319-3689-fbd84fa926bb-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>
On 04/04/2017 10:33 AM, Santosh Shilimkar wrote:
> On 4/3/2017 9:44 AM, santosh.shilimkar-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org wrote:
>> Hi Franklin,
>>
>> On 3/30/17 8:29 AM, Franklin S Cooper Jr wrote:
>>> This patchset adds support for new K2G Industrial Communication Engine
>>> evm. For now only a bare minimal dts which will allow ram boot.
>>> Additional
>>> peripherals will be added when base K2G SoC patches are upstreamed
>>> allowing
>>> peripherals to be enabled.
>>>
>>
>>> ARM: keystone: Create new binding for K2G ICE evm
>>> ARM: dts: keystone: Add minimum support for K2G ICE evm
>>>
>> Can you clarify Rob's comment on second patch and re-post the updated
>> patch with his ack if you agree ? Will apply the series.
>>
> Just to be clear, you need to send v2 with Rob's comment addressed
> for me to pick it up.
Will do.
>
> Regards,
> Snatosh
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v4 6/6] ARM: dts: sun7i: Add can0_pins_a pinctrl settings
From: Patrick Menschel @ 2017-04-04 18:36 UTC (permalink / raw)
To: robh+dt, mark.rutland, linux, maxime.ripard, wens, devicetree,
linux-arm-kernel, linux-kernel, linux-can
Cc: Patrick Menschel
In-Reply-To: <1491330992-9876-1-git-send-email-menschel.p@posteo.de>
The A20 SoC has an on-board CAN controller. This patch adds
the pinctrl settings for pins PH20 and PH21.
This patch is adapted from the description in
Documentation/devicetree/bindings/net/can/sun4i_can.txt
Signed-off-by: Patrick Menschel <menschel.p@posteo.de>
---
arch/arm/boot/dts/sun7i-a20.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index edf85ca..31aaa02 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -1096,6 +1096,11 @@
#interrupt-cells = <3>;
#gpio-cells = <3>;
+ can0_pins_a: can0@0 {
+ pins = "PH20", "PH21";
+ function = "can";
+ };
+
clk_out_a_pins_a: clk_out_a@0 {
pins = "PI12";
function = "clk_out_a";
--
2.7.4
^ permalink raw reply related
* [PATCH v4 5/6] ARM: dts: sun7i: Add CAN node
From: Patrick Menschel @ 2017-04-04 18:36 UTC (permalink / raw)
To: robh+dt, mark.rutland, linux, maxime.ripard, wens, devicetree,
linux-arm-kernel, linux-kernel, linux-can
Cc: Patrick Menschel
In-Reply-To: <1491330992-9876-1-git-send-email-menschel.p@posteo.de>
The A20 SoC has an on-board CAN controller.
This patch adds the device node.
The CAN controller is inherited from the A10 SoC and uses the same driver.
This patch is adapted from the description in
Documentation/devicetree/bindings/net/can/sun4i_can.txt
Signed-off-by: Patrick Menschel <menschel.p@posteo.de>
---
arch/arm/boot/dts/sun7i-a20.dtsi | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 100b4e9..edf85ca 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -1598,6 +1598,15 @@
#size-cells = <0>;
};
+ can0: can@01c2bc00 {
+ compatible = "allwinner,sun7i-a20-can",
+ "allwinner,sun4i-a10-can";
+ reg = <0x01c2bc00 0x400>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb1_gates 4>;
+ status = "disabled";
+ };
+
i2c4: i2c@01c2c000 {
compatible = "allwinner,sun7i-a20-i2c",
"allwinner,sun4i-a10-i2c";
--
2.7.4
^ permalink raw reply related
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