* [PATCH 2/2] devicetree: bindings: add missing Marvell Kirkwood SoC documentation
From: Andrew Lunn @ 2014-02-25 19:05 UTC (permalink / raw)
To: Jason Cooper; +Cc: linux ARM, devicetree-u79uwXL29TY76Z2rM5mHXA, Andrew Lunn
In-Reply-To: <1393355142-7811-1-git-send-email-andrew-g2DYL2Zd6BY@public.gmane.org>
Marvell Dove SoC binding was not documented, yet. Add the
documentation including the supported SoCs and boards.
Signed-off-by: Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org>
---
.../devicetree/bindings/arm/marvell,kirkwood.txt | 97 ++++++++++++++++++++++
1 file changed, 97 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/marvell,kirkwood.txt
diff --git a/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt b/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt
new file mode 100644
index 000000000000..925ecbf6e7b7
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt
@@ -0,0 +1,97 @@
+Marvell Kirkwood SoC Family Device Tree Bindings
+------------------------------------------------
+
+Boards with a SoC of the Marvell Kirkwook family, eg 88f6281
+
+* Required root node properties:
+compatible: must contain "marvell,kirkwood"
+
+In addition, the above compatible shall be extended with the specific
+SoC. Currently known SoC compatibles are:
+
+"marvell,kirkwood-88f6192"
+"marvell,kirkwood-88f6281"
+"marvell,kirkwood-88f6282"
+"marvell,kirkwood-88f6283"
+"marvell,kirkwood-88f6702"
+"marvell,kirkwood-98DX4122"
+
+And in addition, the compatible shall be extended with the specific
+board. Currently known boards are:
+
+"buffalo,lschlv2"
+"buffalo,lsxhl"
+"buffalo,lsxl"
+"dlink,dns-320"
+"dlink,dns-320-a1"
+"dlink,dns-325"
+"dlink,dns-325-a1"
+"dlink,dns-kirkwood"
+"excito,b3"
+"globalscale,dreamplug-003-ds2001"
+"globalscale,guruplug"
+"globalscale,guruplug-server-plus"
+"globalscale,sheevaplug"
+"globalscale,sheevaplug"
+"globalscale,sheevaplug-esata"
+"globalscale,sheevaplug-esata-rev13"
+"iom,iconnect"
+"iom,iconnect-1.1"
+"iom,ix2-200"
+"keymile,km_kirkwood"
+"lacie,cloudbox"
+"lacie,inetspace_v2"
+"lacie,laplug"
+"lacie,netspace_lite_v2"
+"lacie,netspace_max_v2"
+"lacie,netspace_mini_v2"
+"lacie,netspace_v2"
+"marvell,db-88f6281-bp"
+"marvell,db-88f6282-bp"
+"marvell,mv88f6281gtw-ge"
+"marvell,rd88f6281"
+"marvell,rd88f6281"
+"marvell,rd88f6281-a0"
+"marvell,rd88f6281-a1"
+"mpl,cec4"
+"mpl,cec4-10"
+"netgear,readynas"
+"netgear,readynas"
+"netgear,readynas-duo-v2"
+"netgear,readynas-nv+-v2"
+"plathome,openblocks-a6"
+"plathome,openblocks-a7"
+"raidsonic,ib-nas6210"
+"raidsonic,ib-nas6210-b"
+"raidsonic,ib-nas6220"
+"raidsonic,ib-nas6220-b"
+"raidsonic,ib-nas62x0"
+"seagate,dockstar"
+"seagate,goflexnet"
+"synology,ds109"
+"synology,ds110jv10"
+"synology,ds110jv20"
+"synology,ds110jv30"
+"synology,ds111"
+"synology,ds209"
+"synology,ds210jv10"
+"synology,ds210jv20"
+"synology,ds212"
+"synology,ds212jv10"
+"synology,ds212jv20"
+"synology,ds212pv10"
+"synology,ds409"
+"synology,ds409slim"
+"synology,ds410j"
+"synology,ds411"
+"synology,ds411j"
+"synology,ds411slim"
+"synology,ds413jv10"
+"synology,rs212"
+"synology,rs409"
+"synology,rs411"
+"synology,rs812"
+"usi,topkick"
+"usi,topkick-1281P2"
+"zyxel,nsa310"
+"zyxel,nsa310a"
--
1.8.5.3
--
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 v5 2/4] devicetree: bindings: Document Krait CPU/L1 EDAC
From: Kumar Gala @ 2014-02-25 20:48 UTC (permalink / raw)
To: Lorenzo Pieralisi
Cc: Stephen Boyd, Borislav Petkov, linux-kernel@vger.kernel.org,
linux-arm-msm@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org,
Mark Rutland, devicetree@vger.kernel.org
In-Reply-To: <20140225111655.GA6855@e102568-lin.cambridge.arm.com>
On Feb 25, 2014, at 5:16 AM, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> Hi Stephen,
>
> On Wed, Feb 19, 2014 at 12:20:43AM +0000, Stephen Boyd wrote:
>> (Sorry, this discussion stalled due to merge window + life events)
>
> Sorry for the delay in replying on my side too.
>
>> On 01/17, Lorenzo Pieralisi wrote:
>>> On Thu, Jan 16, 2014 at 07:26:17PM +0000, Stephen Boyd wrote:
>>>> On 01/16, Lorenzo Pieralisi wrote:
>>>>> On Thu, Jan 16, 2014 at 06:05:05PM +0000, Stephen Boyd wrote:
>>>>>> On 01/16, Lorenzo Pieralisi wrote:
>>>>>>> Do we really want to do that ? I am not sure. A cpus node is supposed to
>>>>>>> be a container node, we should not define this binding just because we
>>>>>>> know the kernel creates a platform device for it then.
>>>>>>
>>>>>> This is just copying more of the ePAPR spec into this document.
>>>>>> It just so happens that having a compatible field here allows a
>>>>>> platform device to be created. I don't see why that's a problem.
>>>>>
>>>>> I do not see why you cannot define a node like pmu or arch-timer and stick
>>>>> a compatible property in there. cpus node does not represent a device, and
>>>>> must not be created as a platform device, that's my opinion.
>>>>>
>>>>
>>>> I had what you're suggesting before in the original revision of
>>>> this patch. Please take a look at the original patch series[1]. I
>>>> suppose it could be tweaked slightly to still have a cache node
>>>> for the L2 interrupt and the next-level-cache pointer from the
>>>> CPUs.
>>>
>>> Ok, sorry, we are running around in circles here, basically you moved
>>> the node to cpus according to reviews. I still think that treating cpus
>>> as a device is not a great idea, even though I am in the same
>>> position with C-states and probably will add C-state tables in the cpus
>>> node.
>>>
>>> http://comments.gmane.org/gmane.linux.power-management.general/41012
>>>
>>> I just would like to see under cpus nodes and properties that apply to
>>> all ARM systems, and avoid defining properties (eg interrupts) that
>>> have different meanings for different ARM cores.
>>>
>>> The question related to why the kernel should create a platform device
>>> out of cpus is still open. I really do not want to block your series
>>> for these simple issues but we have to make a decision and stick to that,
>>> I am fine either way if we have a plan.
>>>
>>
>> Do you just want a backup plan in case we don't make a platform
>> device out of the cpus node? I believe we can always add code
>> somewhere to create a platform device at runtime if we detect the
>> cpus node has a compatible string equal to "qcom,krait". We could
>> probably change this driver's module_init() to scan the DT for
>> such a compatible string and create the platform device right
>> there. If we get more than one interrupt in the cpus node we can
>> add interrupt-names and then have software look for interrupts by
>> name instead of number.
>
> As I mentioned, I do not like the idea of adding compatible properties
> just to force the kernel to create platform devices out of device tree
> nodes. On top of that I would avoid adding a compatible property
> to the cpus node (after all properties like enable-method are common for all
> cpus but still duplicated), my only concern being backward compatibility
> here (ie if we do that for interrupts, we should do that also for other
> common cpu nodes properties, otherwise we have different rules for
> different properties).
>
> I think you can then add interrupts to cpu nodes ("qcom,krait" specific),
> and as you mentioned create a platform device for that.
>
> Thanks,
> Lorenzo
So I agree with the statement about adding compatibles just to create platform devices is wrong. However its seems perfectly reasonable for a cpu node to have a compatible property. I don’t see why a CPU is any different from any other device described in a DT.
- k
--
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply
* Re: [PATCH 2/2] ARM: dts: duovero-parlor: Add HDMI output
From: Russell King - ARM Linux @ 2014-02-25 20:56 UTC (permalink / raw)
To: Laurent Pinchart
Cc: Sebastian Reichel, Javier Martinez Canillas, Tomi Valkeinen,
Florian Vaussard, Benoît Cousson, Tony Lindgren,
devicetree@vger.kernel.org, linux-omap@vger.kernel.org,
Ash Charles, linux-arm-kernel@lists.infradead.org
In-Reply-To: <2364124.7r818M0xAj@avalon>
On Tue, Feb 25, 2014 at 05:51:21PM +0100, Laurent Pinchart wrote:
> I don't think all physical connectors require a DT binding per-se, but they
> need to be represented in DT as they're part of the hardware. We could push
> connector-related information to the nodes of all chips that have interfaces
> wired directly to connectors, but that would result in more complex DT
> bindings and core. I believe modeling connectors using separate DT nodes is be
> best, and would allow easier support for more complex connectors that carry
> multiple streams/signals in parallel (video, audio, DDC, ...).
There is some sanity to representing physical connectors in DT, but it's
not for the reason you mention above. If you consider that it's possible
on PCs to find out what connectors are on the motherboard and where they
are located, this is very useful information to be stored and presented.
However, the idea that you combine streams at connectors is not a
universal truth, and is certainly false for HDMI. HDMI combines video
and audio at the encoder stage, not at the connector stage, and many
HDMI encoders will provide everything required for driving the connector.
However, my major objection here is not really that: my major objection
is using something as generic as "hdmi-connector" as a compatible string.
The reason is that we have to remember that DT is not just "a Linux thing".
It's /supposed/ to be an OS independent representation of the hardware.
If we invent something generic called a "hdmi-connector" then we had
better first do a thorough search to make sure we're not trampling on
anything which is standardized or becoming a standard - if there is,
we should work with them - and if that's not possible, then we need to
distingush ourselves from them.
What we can't do is go around inventing generic stuff without having our
eyes wide open.
So, here's a good question to probe how far this has been thought through
already: what has been done to discuss the creation of this generic
"hdmi-connector" thing with the various parties who are interested in
HDMI outputs under DRM using device tree?
If that hasn't happened, that's quite a failing - it means that we're
on the road to having two _implementation specific_ DT representations
for the same hardware - one for fbdev and one for DRM. That really
isn't on.
Yes, it then opens a pandora's box of problems about how we determine
whether DRM or fbdev should bind to the DT nodes, but that should be
an entirely separate issue (and, ideally of course, both should use
the same sub-drivers for the components.)
--
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.
^ permalink raw reply
* Re: [RFC PATCH 1/6] PM / Voltagedomain: Add generic clk notifier handler for regulator based dynamic voltage scaling
From: Nishanth Menon @ 2014-02-25 20:56 UTC (permalink / raw)
To: Mike Turquette, Rafael J. Wysocki, Viresh Kumar, MyungJoo Ham,
Mark Brown
Cc: devicetree, linux-pm, linux-doc, linux-kernel, cpufreq,
linux-omap, linux-arm-kernel
In-Reply-To: <20140225055142.22529.21814@quantum>
Hi Mike,
On 02/24/2014 11:51 PM, Mike Turquette wrote:
> Quoting Nishanth Menon (2014-02-18 12:32:18)
>> From: Mike Turquette <mturquette@linaro.org>
>>
>> This patch provides helper functions for drivers that wish to scale
>> voltage through the clock rate-change notifiers. The approach taken
>> is that the user-driver(cpufreq/devfreq) do not care about the
>> details of the OPP table, nor does it care about handling the voltage
>> regulator directly.
>>
>> By using the clk notifier flags, we are able to sequence the operations
>> in the right order. The current logic is heavily influenced by
>> implementation done in cpufreq-cpu0.
>>
>> [nm@ti.com: Fixes in logic, and broken out from clk to allow building
>> a generic voltagedomain solution independent of cpufreq]
>> Signed-off-by: Nishanth Menon <nm@ti.com>
>> Signed-off-by: Mike Turquette <mturquette@linaro.org>
>
> Not-signed-off-by: Mike Turquette <mturquette@linaro.org>
>
> I haven't reviewed this series and it is a pretty big deviation from my
> original RFC. You can have authorship of the patches if you want.
Sure, I had send a private note requesting clarification about the
authorship, but I guess I can take this as the response :).
>
> I'm not sure about trying to capture the "voltdm" as a core concept. It
> feels a bit unwieldy to me.
Considering it is a simple collation of regulators and SoC specific
"magic" which have to be operated in tandem to clock operation, Why
does it seem unwieldy? Usage of multiple voltage planes in a single
voltage domain concept does not seem unique to TI processors either:
For example, imx6q-cpufreq.c uses 3 regulators (arm, pu, soc),
s5pv210-cpufreq.c uses two regulators (vddarm, vddint), ideally OMAP
implementation would use two (vdd_mpu, vbb_mpu).
> I have wondered about making an abstract
> "performance domain" which is the dvfs analogue to generic power
> domains. This a reasonable split since gpd are good for idle power
> savings (e.g. clock gate, power gate, sleep state, etc) and "perf
> domains" would be good for active power savings (dvfs).
>
> Having a generic container for performance domains might make a good
> place to stuff all of this glue logic that we keep running into (e.g.
> CPU and GPU max frequencies that are related), and it might make another
> nice knob for the thermal folks to use.
This sounds like one level higher abstraction that we are speaking of
here? I was'nt intending to solve the bigger picture problem here -
just an abstraction level that might allow reusablity for multiple
SoCs. In fact, having an abstraction away for voltage domain(which may
consist of multiple regulators and any SoC specific magic) purely
allows us to move towards a direction you mention here.
>
> For the case of the OMAP voltage domains, it would be a place to stuff
> all of the VC/VP -> ABB -> Smart Reflex AVS stuff.
>
Unfortunately, I dont completely comprehend objection we have to this
approach (other than an higher level abstraction is needed) and if we
do have an objection, what is the alternate approach should be for
representing hardware which this series attempts to present.
--
Regards,
Nishanth Menon
^ permalink raw reply
* Re: [PATCHv2 01/16] iommu/omap: convert to devm_* interfaces
From: Laurent Pinchart @ 2014-02-25 21:10 UTC (permalink / raw)
To: Suman Anna
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Tony Lindgren,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-omap-u79uwXL29TY76Z2rM5mHXA, Florian Vaussard
In-Reply-To: <1392315347-32967-2-git-send-email-s-anna-l0cyMroinI0@public.gmane.org>
Hi Suman,
Thank you for the patch.
On Thursday 13 February 2014 12:15:32 Suman Anna wrote:
> Use the various devm_ interfaces to simplify the cleanup in
> probe and remove functions.
>
> Signed-off-by: Florian Vaussard <florian.vaussard-p8DiymsW2f8@public.gmane.org>
> Signed-off-by: Suman Anna <s-anna-l0cyMroinI0@public.gmane.org>
Acked-by: Laurent Pinchart <laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>
> ---
> drivers/iommu/omap-iommu.c | 52 ++++++++----------------------------------
> 1 file changed, 10 insertions(+), 42 deletions(-)
>
> diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
> index bcd78a7..fff2ffd 100644
> --- a/drivers/iommu/omap-iommu.c
> +++ b/drivers/iommu/omap-iommu.c
> @@ -941,7 +941,7 @@ static int omap_iommu_probe(struct platform_device
> *pdev) struct resource *res;
> struct iommu_platform_data *pdata = pdev->dev.platform_data;
>
> - obj = kzalloc(sizeof(*obj) + MMU_REG_SIZE, GFP_KERNEL);
> + obj = devm_kzalloc(&pdev->dev, sizeof(*obj) + MMU_REG_SIZE, GFP_KERNEL);
> if (!obj)
> return -ENOMEM;
>
> @@ -958,33 +958,18 @@ static int omap_iommu_probe(struct platform_device
> *pdev) INIT_LIST_HEAD(&obj->mmap);
>
> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> - if (!res) {
> - err = -ENODEV;
> - goto err_mem;
> - }
> -
> - res = request_mem_region(res->start, resource_size(res),
> - dev_name(&pdev->dev));
> - if (!res) {
> - err = -EIO;
> - goto err_mem;
> - }
> -
> - obj->regbase = ioremap(res->start, resource_size(res));
> - if (!obj->regbase) {
> - err = -ENOMEM;
> - goto err_ioremap;
> - }
> + obj->regbase = devm_ioremap_resource(obj->dev, res);
> + if (IS_ERR(obj->regbase))
> + return PTR_ERR(obj->regbase);
>
> irq = platform_get_irq(pdev, 0);
> - if (irq < 0) {
> - err = -ENODEV;
> - goto err_irq;
> - }
> - err = request_irq(irq, iommu_fault_handler, IRQF_SHARED,
> - dev_name(&pdev->dev), obj);
> + if (irq < 0)
> + return -ENODEV;
> +
> + err = devm_request_irq(obj->dev, irq, iommu_fault_handler, IRQF_SHARED,
> + dev_name(obj->dev), obj);
> if (err < 0)
> - goto err_irq;
> + return err;
> platform_set_drvdata(pdev, obj);
>
> pm_runtime_irq_safe(obj->dev);
> @@ -992,34 +977,17 @@ static int omap_iommu_probe(struct platform_device
> *pdev)
>
> dev_info(&pdev->dev, "%s registered\n", obj->name);
> return 0;
> -
> -err_irq:
> - iounmap(obj->regbase);
> -err_ioremap:
> - release_mem_region(res->start, resource_size(res));
> -err_mem:
> - kfree(obj);
> - return err;
> }
>
> static int omap_iommu_remove(struct platform_device *pdev)
> {
> - int irq;
> - struct resource *res;
> struct omap_iommu *obj = platform_get_drvdata(pdev);
>
> iopgtable_clear_entry_all(obj);
>
> - irq = platform_get_irq(pdev, 0);
> - free_irq(irq, obj);
> - res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> - release_mem_region(res->start, resource_size(res));
> - iounmap(obj->regbase);
> -
> pm_runtime_disable(obj->dev);
>
> dev_info(&pdev->dev, "%s removed\n", obj->name);
> - kfree(obj);
> return 0;
> }
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: [PATCHv2 02/16] iommu/omap: omap_iommu_attach() should return ENODEV, not NULL
From: Laurent Pinchart @ 2014-02-25 21:13 UTC (permalink / raw)
To: Suman Anna
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Tony Lindgren,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-omap-u79uwXL29TY76Z2rM5mHXA, Florian Vaussard
In-Reply-To: <1392315347-32967-3-git-send-email-s-anna-l0cyMroinI0@public.gmane.org>
Hi Suman,
Thank you for the patch.
On Thursday 13 February 2014 12:15:33 Suman Anna wrote:
> From: Florian Vaussard <florian.vaussard-p8DiymsW2f8@public.gmane.org>
>
> omap_iommu_attach() returns NULL or ERR_PTR in case of error, but
> omap_iommu_attach_dev() only checks for IS_ERR. Thus a NULL return value (in
> case driver_find_device fails) will cause the kernel to panic when
> omap_iommu_attach_dev() dereferences the pointer.
>
> In such case, omap_iommu_attach() should return ENODEV, not NULL.
>
> Signed-off-by: Florian Vaussard <florian.vaussard-p8DiymsW2f8@public.gmane.org>
> Acked-by: Suman Anna <s-anna-l0cyMroinI0@public.gmane.org>
> ---
> drivers/iommu/omap-iommu.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
> index fff2ffd..6272c36 100644
> --- a/drivers/iommu/omap-iommu.c
> +++ b/drivers/iommu/omap-iommu.c
> @@ -863,7 +863,7 @@ static int device_match_by_alias(struct device *dev,
> void *data) **/
> static struct omap_iommu *omap_iommu_attach(const char *name, u32 *iopgd)
> {
> - int err = -ENOMEM;
> + int err = -ENODEV;
> struct device *dev;
> struct omap_iommu *obj;
>
> @@ -871,7 +871,7 @@ static struct omap_iommu *omap_iommu_attach(const char
> *name, u32 *iopgd) (void *)name,
> device_match_by_alias);
> if (!dev)
> - return NULL;
> + return ERR_PTR(err);
I would return ERR_PTR(-ENODEV) here, and remove the initialization at
declaration of err above.
>
> obj = to_iommu(dev);
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: [PATCHv2 07/16] iommu/omap: allow enable/disable even without pdata
From: Laurent Pinchart @ 2014-02-25 21:15 UTC (permalink / raw)
To: Suman Anna
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Tony Lindgren,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-omap-u79uwXL29TY76Z2rM5mHXA, Florian Vaussard
In-Reply-To: <1392315347-32967-8-git-send-email-s-anna-l0cyMroinI0@public.gmane.org>
Hi Suman,
Thank you for the patch.
On Thursday 13 February 2014 12:15:38 Suman Anna wrote:
> From: Florian Vaussard <florian.vaussard-p8DiymsW2f8@public.gmane.org>
>
> When booting with a devicetree, no platform data is provided.
> Do not prematurely exit iommu_enable() and iommu_disable() in
> such a case.
>
> Note: As OMAP do not yet has a proper reset controller driver,
> IOMMUs requiring a reset signal should use pdata-quirks as a
> transitional solution.
>
> Signed-off-by: Florian Vaussard <florian.vaussard-p8DiymsW2f8@public.gmane.org>
This looks good to me, but you should move this patch before 04/16, otherwise
you'll break bisection.
Acked-by: Laurent Pinchart <laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>
> ---
> drivers/iommu/omap-iommu.c | 10 ++--------
> 1 file changed, 2 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
> index f6afe8f..7672eb4 100644
> --- a/drivers/iommu/omap-iommu.c
> +++ b/drivers/iommu/omap-iommu.c
> @@ -149,13 +149,10 @@ static int iommu_enable(struct omap_iommu *obj)
> struct platform_device *pdev = to_platform_device(obj->dev);
> struct iommu_platform_data *pdata = pdev->dev.platform_data;
>
> - if (!pdata)
> - return -EINVAL;
> -
> if (!arch_iommu)
> return -ENODEV;
>
> - if (pdata->deassert_reset) {
> + if (pdata && pdata->deassert_reset) {
> err = pdata->deassert_reset(pdev, pdata->reset_name);
> if (err) {
> dev_err(obj->dev, "deassert_reset failed: %d\n", err);
> @@ -175,14 +172,11 @@ static void iommu_disable(struct omap_iommu *obj)
> struct platform_device *pdev = to_platform_device(obj->dev);
> struct iommu_platform_data *pdata = pdev->dev.platform_data;
>
> - if (!pdata)
> - return;
> -
> arch_iommu->disable(obj);
>
> pm_runtime_put_sync(obj->dev);
>
> - if (pdata->assert_reset)
> + if (pdata && pdata->assert_reset)
> pdata->assert_reset(pdev, pdata->reset_name);
> }
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: [PATCHv2 08/16] ARM: OMAP3: remove deprecated CONFIG_OMAP_IOMMU_IVA2
From: Laurent Pinchart @ 2014-02-25 21:17 UTC (permalink / raw)
To: Suman Anna
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Paul Walmsley, Tony Lindgren,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-omap-u79uwXL29TY76Z2rM5mHXA, Florian Vaussard
In-Reply-To: <1392315347-32967-9-git-send-email-s-anna-l0cyMroinI0@public.gmane.org>
On Thursday 13 February 2014 12:15:39 Suman Anna wrote:
> From: Florian Vaussard <florian.vaussard-p8DiymsW2f8@public.gmane.org>
>
> CONFIG_OMAP_IOMMU_IVA2 was defined originally to avoid conflicting
> usage by tidspbridge and other iommu users. The same can be achieved
> by marking the DT node disabled, so remove this obsolete flag and
> the corresponding hwmod data can be enabled.
>
> Cc: Paul Walmsley <paul-DWxLp4Yu+b8AvxtiuMwx3w@public.gmane.org>
> Signed-off-by: Florian Vaussard <florian.vaussard-p8DiymsW2f8@public.gmane.org>
> [s-anna-l0cyMroinI0@public.gmane.org: revise commit log]
> Signed-off-by: Suman Anna <s-anna-l0cyMroinI0@public.gmane.org>
Acked-by: Laurent Pinchart <laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>
> ---
> arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 8 --------
> arch/arm/plat-omap/Kconfig | 3 ---
> 2 files changed, 11 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 4c3b1e6..81dd071 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> @@ -3029,8 +3029,6 @@ static struct omap_hwmod omap3xxx_mmu_isp_hwmod = {
> .flags = HWMOD_NO_IDLEST,
> };
>
> -#ifdef CONFIG_OMAP_IOMMU_IVA2
> -
> /* mmu iva */
>
> static struct omap_mmu_dev_attr mmu_iva_dev_attr = {
> @@ -3082,8 +3080,6 @@ static struct omap_hwmod omap3xxx_mmu_iva_hwmod = {
> .flags = HWMOD_NO_IDLEST,
> };
>
> -#endif
> -
> /* l4_per -> gpio4 */
> static struct omap_hwmod_addr_space omap3xxx_gpio4_addrs[] = {
> {
> @@ -3855,9 +3851,7 @@ static struct omap_hwmod_ocp_if
> *omap34xx_hwmod_ocp_ifs[] __initdata = { &omap3xxx_l4_core__hdq1w,
> &omap3xxx_sad2d__l3,
> &omap3xxx_l4_core__mmu_isp,
> -#ifdef CONFIG_OMAP_IOMMU_IVA2
> &omap3xxx_l3_main__mmu_iva,
> -#endif
> &omap34xx_l4_core__ssi,
> NULL
> };
> @@ -3881,9 +3875,7 @@ static struct omap_hwmod_ocp_if
> *omap36xx_hwmod_ocp_ifs[] __initdata = { &omap3xxx_l4_core__hdq1w,
> &omap3xxx_sad2d__l3,
> &omap3xxx_l4_core__mmu_isp,
> -#ifdef CONFIG_OMAP_IOMMU_IVA2
> &omap3xxx_l3_main__mmu_iva,
> -#endif
> NULL
> };
>
> diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
> index 436ea97..02fc10d 100644
> --- a/arch/arm/plat-omap/Kconfig
> +++ b/arch/arm/plat-omap/Kconfig
> @@ -86,9 +86,6 @@ config OMAP_MUX_WARNINGS
> to change the pin multiplexing setup. When there are no warnings
> printed, it's safe to deselect OMAP_MUX for your product.
>
> -config OMAP_IOMMU_IVA2
> - bool
> -
> config OMAP_MPU_TIMER
> bool "Use mpu timer"
> depends on ARCH_OMAP1
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: [PATCHv2 03/16] Documentation: dt: add OMAP iommu bindings
From: Laurent Pinchart @ 2014-02-25 21:26 UTC (permalink / raw)
To: Suman Anna
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Tony Lindgren,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-omap-u79uwXL29TY76Z2rM5mHXA, Florian Vaussard
In-Reply-To: <1392315347-32967-4-git-send-email-s-anna-l0cyMroinI0@public.gmane.org>
Hi Suman,
Thank you for the patch.
On Thursday 13 February 2014 12:15:34 Suman Anna wrote:
> From: Florian Vaussard <florian.vaussard-p8DiymsW2f8@public.gmane.org>
>
> This patch adds the iommu bindings for all OMAP2+ SoCs. Apart from
> the standard bindings used by OMAP peripherals, this patch uses a
> 'dma-window' (already used by Tegra SMMU) and adds two OMAP custom
> bindings - 'ti,#tlb-entries' and 'ti,iommu-bus-err-back'.
>
> Signed-off-by: Florian Vaussard <florian.vaussard-p8DiymsW2f8@public.gmane.org>
> [s-anna-l0cyMroinI0@public.gmane.org: split bindings document, add dra7 and bus error back]
> Signed-off-by: Suman Anna <s-anna-l0cyMroinI0@public.gmane.org>
> ---
> .../devicetree/bindings/iommu/ti,omap-iommu.txt | 28 +++++++++++++++++++
> 1 file changed, 28 insertions(+)
> create mode 100644
> Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt
>
> diff --git a/Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt
> b/Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt new file mode
> 100644
> index 0000000..116492d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt
> @@ -0,0 +1,28 @@
> +OMAP2+ IOMMU
> +
> +Required properties:
> +- compatible : Should be one of,
> + "ti,omap2-iommu" for OMAP2/OMAP3 IOMMU instances
> + "ti,omap4-iommu" for OMAP4/OMAP5 IOMMU instances
> + "ti,dra7-iommu" for DRA7xx IOMMU instances
> +- ti,hwmods : Name of the hwmod associated with the IOMMU instance
> +- reg : Address space for the configuration registers
> +- interrupts : Interrupt specifier for the IOMMU instance
> +- dma-window : IOVA start address and length
Isn't the dma window more of a system configuration property than a hardware
property ? How do you expect it to be set ?
> +Optional properties:
> +- ti,#tlb-entries : Number of entries in the translation look-aside buffer.
> + Should be either 8 or 32 (default: 32)
> +- ti,iommu-bus-err-back : Indicates the IOMMU instance supports throwing
> + back a bus error response on MMU faults.
Do these features vary per IOMMU instance or per IOMMU model ? In the latter
case they could be inferred from the compatible string by the driver without
requiring them to be explicit in DT (whether you want to do so is left to you
though).
> +Example:
> + /* OMAP3 ISP MMU */
> + mmu_isp: mmu@480bd400 {
> + compatible = "ti,omap2-iommu";
> + reg = <0x480bd400 0x80>;
> + interrupts = <24>;
> + ti,hwmods = "mmu_isp";
> + ti,#tlb-entries = <8>;
> + dma-window = <0 0xfffff000>;
> + };
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: [PATCH v4] can: xilinx CAN controller support.
From: Marc Kleine-Budde @ 2014-02-25 21:26 UTC (permalink / raw)
To: Kedareswara rao Appana, wg, michal.simek, grant.likely, robh+dt,
linux-can
Cc: netdev, linux-arm-kernel, linux-kernel, devicetree,
Kedareswara rao Appana
In-Reply-To: <74d607e9-ac9c-4a9b-ac49-e84ae49d20c2@TX2EHSMHS031.ehs.local>
[-- Attachment #1: Type: text/plain, Size: 45754 bytes --]
On 02/24/2014 05:25 AM, Kedareswara rao Appana wrote:
> This patch adds xilinx CAN controller support.
> This driver supports both ZYNQ CANPS and Soft IP
> AXI CAN controller.
>
> Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
Looks quite good. Just the tx_complete routine is a bit fishy. Comments
inline.
> ---
> This patch is rebased on the 3.14 rc4 kernel.
> Changes for v4:
> - Added check for the tx fifo full interrupt condition in
> Tx interrupt routine.
> - Added be io helper functions.
Which combinations of endianess have you tested (Kernel/Hardware)?
> - Moved the clock enable/disable to probe/remove because of
> Added big endian support for AXI CAN controller case(reading
> a register during the probe for that we need to enable clock).
Just disable the clock in the end of probe(). See inline comments
> Changes for v3:
> - Updated the driver with review comments.
> - Modified the transmit logic as per Marc suggestion.
> - Enabling the clocks when the interface is up to reduce the
> Power consumption.
> Changes for v2:
> - Updated with the review comments.
> - Removed the unnecessary debug prints.
> - include tx,rx fifo depths in ZYNQ CANPS case also.
> ---
> .../devicetree/bindings/net/can/xilinx_can.txt | 45 +
> drivers/net/can/Kconfig | 7 +
> drivers/net/can/Makefile | 1 +
> drivers/net/can/xilinx_can.c | 1162 ++++++++++++++++++++
> 4 files changed, 1215 insertions(+), 0 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/net/can/xilinx_can.txt
> create mode 100644 drivers/net/can/xilinx_can.c
>
> diff --git a/Documentation/devicetree/bindings/net/can/xilinx_can.txt b/Documentation/devicetree/bindings/net/can/xilinx_can.txt
> new file mode 100644
> index 0000000..0e57103
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/can/xilinx_can.txt
> @@ -0,0 +1,45 @@
> +Xilinx Axi CAN/Zynq CANPS controller Device Tree Bindings
> +---------------------------------------------------------
> +
> +Required properties:
> +- compatible : Should be "xlnx,zynq-can-1.00.a" for Zynq CAN
> + controllers and "xlnx,axi-can-1.00.a" for Axi CAN
> + controllers.
> +- reg : Physical base address and size of the Axi CAN/Zynq
> + CANPS registers map.
> +- interrupts : Property with a value describing the interrupt
> + number.
> +- interrupt-parent : Must be core interrupt controller
> +- clock-names : List of input clock names - "ref_clk", "aper_clk"
> + (See clock bindings for details. Two clocks are
> + required for Zynq CAN. For Axi CAN
> + case it is one(ref_clk)).
> +- clocks : Clock phandles (see clock bindings for details).
> +- tx-fifo-depth : Can Tx fifo depth.
> +- rx-fifo-depth : Can Rx fifo depth.
> +
> +
> +Example:
> +
> +For Zynq CANPS Dts file:
> + zynq_can_0: zynq-can@e0008000 {
> + compatible = "xlnx,zynq-can-1.00.a";
> + clocks = <&clkc 19>, <&clkc 36>;
> + clock-names = "ref_clk", "aper_clk";
> + reg = <0xe0008000 0x1000>;
> + interrupts = <0 28 4>;
> + interrupt-parent = <&intc>;
> + tx-fifo-depth = <0x40>;
> + rx-fifo-depth = <0x40>;
> + };
> +For Axi CAN Dts file:
> + axi_can_0: axi-can@40000000 {
> + compatible = "xlnx,axi-can-1.00.a";
> + clocks = <&clkc 0>;
> + clock-names = "ref_clk" ;
> + reg = <0x40000000 0x10000>;
> + interrupt-parent = <&intc>;
> + interrupts = <0 59 1>;
> + tx-fifo-depth = <0x40>;
> + rx-fifo-depth = <0x40>;
> + };
> diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
> index 9e7d95d..b180239 100644
> --- a/drivers/net/can/Kconfig
> +++ b/drivers/net/can/Kconfig
> @@ -125,6 +125,13 @@ config CAN_GRCAN
> endian syntheses of the cores would need some modifications on
> the hardware level to work.
>
> +config CAN_XILINXCAN
> + tristate "Xilinx CAN"
> + depends on ARCH_ZYNQ || MICROBLAZE
> + ---help---
> + Xilinx CAN driver. This driver supports both soft AXI CAN IP and
> + Zynq CANPS IP.
> +
> source "drivers/net/can/mscan/Kconfig"
>
> source "drivers/net/can/sja1000/Kconfig"
> diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
> index c744039..0b8e11e 100644
> --- a/drivers/net/can/Makefile
> +++ b/drivers/net/can/Makefile
> @@ -25,5 +25,6 @@ obj-$(CONFIG_CAN_JANZ_ICAN3) += janz-ican3.o
> obj-$(CONFIG_CAN_FLEXCAN) += flexcan.o
> obj-$(CONFIG_PCH_CAN) += pch_can.o
> obj-$(CONFIG_CAN_GRCAN) += grcan.o
> +obj-$(CONFIG_CAN_XILINXCAN) += xilinx_can.o
>
> ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
> diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
> new file mode 100644
> index 0000000..7564bef
> --- /dev/null
> +++ b/drivers/net/can/xilinx_can.c
> @@ -0,0 +1,1162 @@
> +/* Xilinx CAN device driver
> + *
> + * Copyright (C) 2012 - 2014 Xilinx, Inc.
> + * Copyright (C) 2009 PetaLogix. All rights reserved.
> + *
> + * Description:
> + * This driver is developed for Axi CAN IP and for Zynq CANPS Controller.
> + * 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/errno.h>
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/netdevice.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/skbuff.h>
> +#include <linux/string.h>
> +#include <linux/types.h>
> +#include <linux/can/dev.h>
> +#include <linux/can/error.h>
> +#include <linux/can/led.h>
> +
> +#define DRIVER_NAME "XILINX_CAN"
> +
> +/* CAN registers set */
> +enum xcan_reg {
> + XCAN_SRR_OFFSET = 0x00, /* Software reset */
> + XCAN_MSR_OFFSET = 0x04, /* Mode select */
> + XCAN_BRPR_OFFSET = 0x08, /* Baud rate prescaler */
> + XCAN_BTR_OFFSET = 0x0C, /* Bit timing */
> + XCAN_ECR_OFFSET = 0x10, /* Error counter */
> + XCAN_ESR_OFFSET = 0x14, /* Error status */
> + XCAN_SR_OFFSET = 0x18, /* Status */
> + XCAN_ISR_OFFSET = 0x1C, /* Interrupt status */
> + XCAN_IER_OFFSET = 0x20, /* Interrupt enable */
> + XCAN_ICR_OFFSET = 0x24, /* Interrupt clear */
> + XCAN_TXFIFO_ID_OFFSET = 0x30,/* TX FIFO ID */
> + XCAN_TXFIFO_DLC_OFFSET = 0x34, /* TX FIFO DLC */
> + XCAN_TXFIFO_DW1_OFFSET = 0x38, /* TX FIFO Data Word 1 */
> + XCAN_TXFIFO_DW2_OFFSET = 0x3C, /* TX FIFO Data Word 2 */
> + XCAN_RXFIFO_ID_OFFSET = 0x50, /* RX FIFO ID */
> + XCAN_RXFIFO_DLC_OFFSET = 0x54, /* RX FIFO DLC */
> + XCAN_RXFIFO_DW1_OFFSET = 0x58, /* RX FIFO Data Word 1 */
> + XCAN_RXFIFO_DW2_OFFSET = 0x5C, /* RX FIFO Data Word 2 */
> +};
> +
> +/* CAN register bit masks - XCAN_<REG>_<BIT>_MASK */
> +#define XCAN_SRR_CEN_MASK 0x00000002 /* CAN enable */
> +#define XCAN_SRR_RESET_MASK 0x00000001 /* Soft Reset the CAN core */
> +#define XCAN_MSR_LBACK_MASK 0x00000002 /* Loop back mode select */
> +#define XCAN_MSR_SLEEP_MASK 0x00000001 /* Sleep mode select */
> +#define XCAN_BRPR_BRP_MASK 0x000000FF /* Baud rate prescaler */
> +#define XCAN_BTR_SJW_MASK 0x00000180 /* Synchronous jump width */
> +#define XCAN_BTR_TS2_MASK 0x00000070 /* Time segment 2 */
> +#define XCAN_BTR_TS1_MASK 0x0000000F /* Time segment 1 */
> +#define XCAN_ECR_REC_MASK 0x0000FF00 /* Receive error counter */
> +#define XCAN_ECR_TEC_MASK 0x000000FF /* Transmit error counter */
> +#define XCAN_ESR_ACKER_MASK 0x00000010 /* ACK error */
> +#define XCAN_ESR_BERR_MASK 0x00000008 /* Bit error */
> +#define XCAN_ESR_STER_MASK 0x00000004 /* Stuff error */
> +#define XCAN_ESR_FMER_MASK 0x00000002 /* Form error */
> +#define XCAN_ESR_CRCER_MASK 0x00000001 /* CRC error */
> +#define XCAN_SR_TXFLL_MASK 0x00000400 /* TX FIFO is full */
> +#define XCAN_SR_ESTAT_MASK 0x00000180 /* Error status */
> +#define XCAN_SR_ERRWRN_MASK 0x00000040 /* Error warning */
> +#define XCAN_SR_NORMAL_MASK 0x00000008 /* Normal mode */
> +#define XCAN_SR_LBACK_MASK 0x00000002 /* Loop back mode */
> +#define XCAN_SR_CONFIG_MASK 0x00000001 /* Configuration mode */
> +#define XCAN_IXR_TXFEMP_MASK 0x00004000 /* TX FIFO Empty */
> +#define XCAN_IXR_WKUP_MASK 0x00000800 /* Wake up interrupt */
> +#define XCAN_IXR_SLP_MASK 0x00000400 /* Sleep interrupt */
> +#define XCAN_IXR_BSOFF_MASK 0x00000200 /* Bus off interrupt */
> +#define XCAN_IXR_ERROR_MASK 0x00000100 /* Error interrupt */
> +#define XCAN_IXR_RXNEMP_MASK 0x00000080 /* RX FIFO NotEmpty intr */
> +#define XCAN_IXR_RXOFLW_MASK 0x00000040 /* RX FIFO Overflow intr */
> +#define XCAN_IXR_RXOK_MASK 0x00000010 /* Message received intr */
> +#define XCAN_IXR_TXFLL_MASK 0x00000004 /* Tx FIFO Full intr */
> +#define XCAN_IXR_TXOK_MASK 0x00000002 /* TX successful intr */
> +#define XCAN_IXR_ARBLST_MASK 0x00000001 /* Arbitration lost intr */
> +#define XCAN_IDR_ID1_MASK 0xFFE00000 /* Standard msg identifier */
> +#define XCAN_IDR_SRR_MASK 0x00100000 /* Substitute remote TXreq */
> +#define XCAN_IDR_IDE_MASK 0x00080000 /* Identifier extension */
> +#define XCAN_IDR_ID2_MASK 0x0007FFFE /* Extended message ident */
> +#define XCAN_IDR_RTR_MASK 0x00000001 /* Remote TX request */
> +#define XCAN_DLCR_DLC_MASK 0xF0000000 /* Data length code */
> +
> +#define XCAN_INTR_ALL (XCAN_IXR_TXOK_MASK | XCAN_IXR_BSOFF_MASK |\
> + XCAN_IXR_WKUP_MASK | XCAN_IXR_SLP_MASK | \
> + XCAN_IXR_RXNEMP_MASK | XCAN_IXR_ERROR_MASK | \
> + XCAN_IXR_ARBLST_MASK | XCAN_IXR_RXOK_MASK)
> +
> +/* CAN register bit shift - XCAN_<REG>_<BIT>_SHIFT */
> +#define XCAN_BTR_SJW_SHIFT 7 /* Synchronous jump width */
> +#define XCAN_BTR_TS2_SHIFT 4 /* Time segment 2 */
> +#define XCAN_IDR_ID1_SHIFT 21 /* Standard Messg Identifier */
> +#define XCAN_IDR_ID2_SHIFT 1 /* Extended Message Identifier */
> +#define XCAN_DLCR_DLC_SHIFT 28 /* Data length code */
> +#define XCAN_ESR_REC_SHIFT 8 /* Rx Error Count */
> +
> +/* CAN frame length constants */
> +#define XCAN_ECHO_SKB_MAX 64
> +#define XCAN_FRAME_MAX_DATA_LEN 8
> +#define XCAN_TIMEOUT (1 * HZ)
> +
> +/**
> + * struct xcan_priv - This definition define CAN driver instance
> + * @can: CAN private data structure.
> + * @tx_head: Tx CAN packets ready to send on the queue
> + * @tx_tail: Tx CAN packets successfully sended on the queue
> + * @xcan_echo_skb_max_tx: Maximum number packets the driver can send
> + * @xcan_echo_skb_max_rx: Maximum number packets the driver can receive
> + * @napi: NAPI structure
> + * @read_reg: For reading data from CAN registers
> + * @write_reg: For writing data to CAN registers
> + * @dev: Network device data structure
> + * @reg_base: Ioremapped address to registers
> + * @irq_flags: For request_irq()
> + * @aperclk: Pointer to struct clk
> + * @devclk: Pointer to struct clk
> + */
> +struct xcan_priv {
> + struct can_priv can;
> + unsigned int tx_head;
> + unsigned int tx_tail;
> + u32 xcan_echo_skb_max_tx;
To make the nameing more uniform, you can rename it into "tx_max".
> + u32 xcan_echo_skb_max_rx;
I think the _rx value is only needed inside the probe function, right?
Then you can remove it from the priv struct.
> + struct napi_struct napi;
> + u32 (*read_reg)(const struct xcan_priv *priv, enum xcan_reg reg);
> + void (*write_reg)(const struct xcan_priv *priv, enum xcan_reg reg,
> + u32 val);
> + struct net_device *dev;
> + void __iomem *reg_base;
> + unsigned long irq_flags;
> + struct clk *aperclk;
> + struct clk *devclk;
> +};
> +
> +/* CAN Bittiming constants as per Xilinx CAN specs */
> +static const struct can_bittiming_const xcan_bittiming_const = {
> + .name = DRIVER_NAME,
> + .tseg1_min = 1,
> + .tseg1_max = 16,
> + .tseg2_min = 1,
> + .tseg2_max = 8,
> + .sjw_max = 4,
> + .brp_min = 1,
> + .brp_max = 256,
> + .brp_inc = 1,
> +};
> +
> +/**
> + * xcan_write_reg_le - Write a value to the device register little endian
> + * @priv: Driver private data structure
> + * @reg: Register offset
> + * @val: Value to write at the Register offset
> + *
> + * Write data to the paricular CAN register
> + */
> +static void xcan_write_reg_le(const struct xcan_priv *priv, enum xcan_reg reg,
> + u32 val)
> +{
> + iowrite32(val, priv->reg_base + reg);
> +}
> +
> +/**
> + * xcan_read_reg_le - Read a value from the device register little endian
> + * @priv: Driver private data structure
> + * @reg: Register offset
> + *
> + * Read data from the particular CAN register
> + * Return: value read from the CAN register
> + */
> +static u32 xcan_read_reg_le(const struct xcan_priv *priv, enum xcan_reg reg)
> +{
> + return ioread32(priv->reg_base + reg);
> +}
> +
> +/**
> + * xcan_write_reg_be - Write a value to the device register big endian
> + * @priv: Driver private data structure
> + * @reg: Register offset
> + * @val: Value to write at the Register offset
> + *
> + * Write data to the paricular CAN register
> + */
> +static void xcan_write_reg_be(const struct xcan_priv *priv, enum xcan_reg reg,
> + u32 val)
> +{
> + iowrite32be(val, priv->reg_base + reg);
> +}
> +
> +/**
> + * xcan_read_reg_be - Read a value from the device register big endian
> + * @priv: Driver private data structure
> + * @reg: Register offset
> + *
p> + * Read data from the particular CAN register
> + * Return: value read from the CAN register
> + */
> +static u32 xcan_read_reg_be(const struct xcan_priv *priv, enum xcan_reg reg)
> +{
> + return ioread32be(priv->reg_base + reg);
> +}
> +
> +/**
> + * set_reset_mode - Resets the CAN device mode
> + * @ndev: Pointer to net_device structure
> + *
> + * This is the driver reset mode routine.The driver
> + * enters into configuration mode.
> + *
> + * Return: 0 on success and failure value on error
> + */
> +static int set_reset_mode(struct net_device *ndev)
> +{
> + struct xcan_priv *priv = netdev_priv(ndev);
> + unsigned long timeout;
> +
> + priv->can.state = CAN_STATE_STOPPED;
> +
> + timeout = jiffies + XCAN_TIMEOUT;
> + while (!(priv->read_reg(priv, XCAN_SR_OFFSET) & XCAN_SR_CONFIG_MASK)) {
> + if (time_after(jiffies, timeout)) {
> + netdev_warn(ndev, "timedout waiting for config mode\n");
> + return -ETIMEDOUT;
> + }
> + usleep_range(500, 10000);
> + }
> +
> + return 0;
> +}
> +
> +/**
> + * xcan_set_bittiming - CAN set bit timing routine
> + * @ndev: Pointer to net_device structure
> + *
> + * This is the driver set bittiming routine.
> + * Return: 0 on success and failure value on error
> + */
> +static int xcan_set_bittiming(struct net_device *ndev)
> +{
> + struct xcan_priv *priv = netdev_priv(ndev);
> + struct can_bittiming *bt = &priv->can.bittiming;
> + u32 btr0, btr1;
> + u32 is_config_mode;
> +
> + /* Check whether Xilinx CAN is in configuration mode.
> + * It cannot set bit timing if Xilinx CAN is not in configuration mode.
> + */
> + is_config_mode = priv->read_reg(priv, XCAN_SR_OFFSET) &
> + XCAN_SR_CONFIG_MASK;
> + if (!is_config_mode) {
> + netdev_alert(ndev,
> + "Cannot set bittiming can is not in config mode\n");
> + return -EPERM;
> + }
> +
> + /* Setting Baud Rate prescalar value in BRPR Register */
> + btr0 = (bt->brp - 1) & XCAN_BRPR_BRP_MASK;
> +
> + /* Setting Time Segment 1 in BTR Register */
> + btr1 = (bt->prop_seg + bt->phase_seg1 - 1) & XCAN_BTR_TS1_MASK;
Both masks should not be needed as the values are inside the range you
specified. If you cut the values, the bit timing will not be correct anyway.
> +
> + /* Setting Time Segment 2 in BTR Register */
> + btr1 |= (bt->phase_seg2 - 1) << XCAN_BTR_TS2_SHIFT;
> +
> + /* Setting Synchronous jump width in BTR Register */
> + btr1 |= (bt->sjw - 1) << XCAN_BTR_SJW_SHIFT;
> +
> + priv->write_reg(priv, XCAN_BRPR_OFFSET, btr0);
> + priv->write_reg(priv, XCAN_BTR_OFFSET, btr1);
> +
> + netdev_dbg(ndev, "BRPR=0x%08x, BTR=0x%08x\n",
> + priv->read_reg(priv, XCAN_BRPR_OFFSET),
> + priv->read_reg(priv, XCAN_BTR_OFFSET));
> +
> + return 0;
> +}
> +
> +/**
> + * xcan_chip_start - This the drivers start routine
> + * @ndev: Pointer to net_device structure
> + *
> + * This is the drivers start routine.
> + * Based on the State of the CAN device it puts
> + * the CAN device into a proper mode.
> + *
> + * Return: 0 on success and failure value on error
> + */
> +static int xcan_chip_start(struct net_device *ndev)
> +{
> + struct xcan_priv *priv = netdev_priv(ndev);
> + u32 err;
> + unsigned long timeout;
> +
> + /* Check if it is in reset mode */
> + err = set_reset_mode(ndev);
> + if (err < 0)
> + return err;
> +
> + /* Enable interrupts */
> + priv->write_reg(priv, XCAN_IER_OFFSET, XCAN_INTR_ALL);
> +
> + /* Check whether it is loopback mode or normal mode */
> + if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
> + /* Put device into loopback mode */
> + priv->write_reg(priv, XCAN_MSR_OFFSET, XCAN_MSR_LBACK_MASK);
> + else
> + /* The device is in normal mode */
> + priv->write_reg(priv, XCAN_MSR_OFFSET, 0);
> +
> + if (priv->can.state == CAN_STATE_STOPPED) {
> + /* Enable Xilinx CAN */
> + priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_CEN_MASK);
> + priv->can.state = CAN_STATE_ERROR_ACTIVE;
> + timeout = jiffies + XCAN_TIMEOUT;
> + if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
> + while ((priv->read_reg(priv, XCAN_SR_OFFSET)
> + & XCAN_SR_LBACK_MASK) == 0) {
> + if (time_after(jiffies, timeout)) {
> + netdev_warn(ndev,
> + "timedout for loopback mode\n");
> + return -ETIMEDOUT;
> + }
> + usleep_range(500, 10000);
> + }
> + } else {
> + while ((priv->read_reg(priv, XCAN_SR_OFFSET)
> + & XCAN_SR_NORMAL_MASK) == 0) {
> + if (time_after(jiffies, timeout)) {
> + netdev_warn(ndev,
> + "timedout for normal mode\n");
> + return -ETIMEDOUT;
> + }
> + usleep_range(500, 10000);
> + }
> + }
> + netdev_dbg(ndev, "status:#x%08x\n",
> + priv->read_reg(priv, XCAN_SR_OFFSET));
> + }
> + priv->can.state = CAN_STATE_ERROR_ACTIVE;
> + return 0;
> +}
> +
> +/**
> + * xcan_do_set_mode - This sets the mode of the driver
> + * @ndev: Pointer to net_device structure
> + * @mode: Tells the mode of the driver
> + *
> + * This check the drivers state and calls the
> + * the corresponding modes to set.
> + *
> + * Return: 0 on success and failure value on error
> + */
> +static int xcan_do_set_mode(struct net_device *ndev, enum can_mode mode)
> +{
> + int ret;
> +
> + switch (mode) {
> + case CAN_MODE_START:
> + ret = xcan_chip_start(ndev);
> + if (ret < 0)
> + netdev_err(ndev, "xcan_chip_start failed!\n");
> + netif_wake_queue(ndev);
> + break;
> + default:
> + ret = -EOPNOTSUPP;
> + break;
> + }
> +
> + return ret;
> +}
> +
> +/**
> + * xcan_start_xmit - Starts the transmission
> + * @skb: sk_buff pointer that contains data to be Txed
> + * @ndev: Pointer to net_device structure
> + *
> + * This function is invoked from upper layers to initiate transmission. This
> + * function uses the next available free txbuff and populates their fields to
> + * start the transmission.
> + *
> + * Return: 0 on success and failure value on error
> + */
> +static int xcan_start_xmit(struct sk_buff *skb, struct net_device *ndev)
> +{
> + struct xcan_priv *priv = netdev_priv(ndev);
> + struct net_device_stats *stats = &ndev->stats;
> + struct can_frame *cf = (struct can_frame *)skb->data;
> + u32 id, dlc, data[2] = {0, 0};
> +
> + if (can_dropped_invalid_skb(ndev, skb))
> + return NETDEV_TX_OK;
> +
> + /* Check if the TX buffer is full */
> + if (unlikely(priv->read_reg(priv, XCAN_SR_OFFSET) &
> + XCAN_SR_TXFLL_MASK)) {
> + netif_stop_queue(ndev);
> + netdev_err(ndev, "BUG!, TX FIFO full when queue awake!\n");
> + return NETDEV_TX_BUSY;
> + }
> +
> + /* Watch carefully on the bit sequence */
> + if (cf->can_id & CAN_EFF_FLAG) {
> + /* Extended CAN ID format */
> + id = ((cf->can_id & CAN_EFF_MASK) << XCAN_IDR_ID2_SHIFT) &
> + XCAN_IDR_ID2_MASK;
> + id |= (((cf->can_id & CAN_EFF_MASK) >>
> + (CAN_EFF_ID_BITS-CAN_SFF_ID_BITS)) <<
> + XCAN_IDR_ID1_SHIFT) & XCAN_IDR_ID1_MASK;
> +
> + /* The substibute remote TX request bit should be "1"
> + * for extended frames as in the Xilinx CAN datasheet
> + */
> + id |= XCAN_IDR_IDE_MASK | XCAN_IDR_SRR_MASK;
> +
> + if (cf->can_id & CAN_RTR_FLAG)
> + /* Extended frames remote TX request */
> + id |= XCAN_IDR_RTR_MASK;
> + } else {
> + /* Standard CAN ID format */
> + id = ((cf->can_id & CAN_SFF_MASK) << XCAN_IDR_ID1_SHIFT) &
> + XCAN_IDR_ID1_MASK;
> +
> + if (cf->can_id & CAN_RTR_FLAG)
> + /* Extended frames remote TX request */
Copy/paste error in the coment
> + id |= XCAN_IDR_SRR_MASK;
> + }
> +
> + dlc = cf->can_dlc << XCAN_DLCR_DLC_SHIFT;
> +
> + if (cf->can_dlc > 0)
> + data[0] = be32_to_cpup((__be32 *)(cf->data + 0));
> + if (cf->can_dlc > 4)
> + data[1] = be32_to_cpup((__be32 *)(cf->data + 4));
> +
> + can_put_echo_skb(skb, ndev, priv->tx_head % priv->xcan_echo_skb_max_tx);
> + priv->tx_head++;
> +
> + /* Write the Frame to Xilinx CAN TX FIFO */
> + priv->write_reg(priv, XCAN_TXFIFO_ID_OFFSET, id);
> + /* If the CAN frame is RTR frame this write triggers tranmission */
> + priv->write_reg(priv, XCAN_TXFIFO_DLC_OFFSET, dlc);
> + if (!(cf->can_id & CAN_RTR_FLAG)) {
> + priv->write_reg(priv, XCAN_TXFIFO_DW1_OFFSET, data[0]);
> + /* If the CAN frame is Standard/Extended frame this
> + * write triggers tranmission
> + */
> + priv->write_reg(priv, XCAN_TXFIFO_DW2_OFFSET, data[1]);
> + stats->tx_bytes += cf->can_dlc;
> + }
> +
> + /* Check if the TX buffer is full */
> + if ((priv->tx_head - priv->tx_tail) == priv->xcan_echo_skb_max_tx)
> + netif_stop_queue(ndev);
> +
> + return NETDEV_TX_OK;
> +}
> +
> +/**
> + * xcan_rx - Is called from CAN isr to complete the received
> + * frame processing
> + * @ndev: Pointer to net_device structure
> + *
> + * This function is invoked from the CAN isr(poll) to process the Rx frames. It
> + * does minimal processing and invokes "netif_receive_skb" to complete further
> + * processing.
> + * Return: 0 on success and negative error value on error
> + */
> +static int xcan_rx(struct net_device *ndev)
> +{
> + struct xcan_priv *priv = netdev_priv(ndev);
> + struct net_device_stats *stats = &ndev->stats;
> + struct can_frame *cf;
> + struct sk_buff *skb;
> + u32 id_xcan, dlc, data[2] = {0, 0};
> +
> + skb = alloc_can_skb(ndev, &cf);
> + if (!skb)
> + return -ENOMEM;
> +
> + /* Read a frame from Xilinx zynq CANPS */
> + id_xcan = priv->read_reg(priv, XCAN_RXFIFO_ID_OFFSET);
> + dlc = priv->read_reg(priv, XCAN_RXFIFO_DLC_OFFSET) >>
> + XCAN_DLCR_DLC_SHIFT;
> +
> + /* Change Xilinx CAN data length format to socketCAN data format */
> + cf->can_dlc = get_can_dlc(dlc);
> +
> + /* Change Xilinx CAN ID format to socketCAN ID format */
> + if (id_xcan & XCAN_IDR_IDE_MASK) {
> + /* The received frame is an Extended format frame */
> + cf->can_id = (id_xcan & XCAN_IDR_ID1_MASK) >> 3;
> + cf->can_id |= (id_xcan & XCAN_IDR_ID2_MASK) >>
> + XCAN_IDR_ID2_SHIFT;
> + cf->can_id |= CAN_EFF_FLAG;
> + if (id_xcan & XCAN_IDR_RTR_MASK)
> + cf->can_id |= CAN_RTR_FLAG;
> + } else {
> + /* The received frame is a standard format frame */
> + cf->can_id = (id_xcan & XCAN_IDR_ID1_MASK) >>
> + XCAN_IDR_ID1_SHIFT;
> + if (id_xcan & XCAN_IDR_RTR_MASK)
> + cf->can_id |= CAN_RTR_FLAG;
> + }
> +
> + if (!(id_xcan & XCAN_IDR_RTR_MASK)) {
> + data[0] = priv->read_reg(priv, XCAN_RXFIFO_DW1_OFFSET);
> + data[1] = priv->read_reg(priv, XCAN_RXFIFO_DW2_OFFSET);
> +
> + /* Change Xilinx CAN data format to socketCAN data format */
> + *(__be32 *)(cf->data) = cpu_to_be32(data[0]);
> + if (cf->can_dlc > 4)
> + *(__be32 *)(cf->data + 4) = cpu_to_be32(data[1]);
> + }
> + can_led_event(ndev, CAN_LED_EVENT_RX);
> +
> + netif_receive_skb(skb);
> +
> + stats->rx_bytes += cf->can_dlc;
> + stats->rx_packets++;
> + return 0;
> +}
> +
> +/**
> + * xcan_err_interrupt - error frame Isr
> + * @ndev: net_device pointer
> + * @isr: interrupt status register value
> + *
> + * This is the CAN error interrupt and it will
> + * check the the type of error and forward the error
> + * frame to upper layers.
> + */
> +static void xcan_err_interrupt(struct net_device *ndev, u32 isr)
> +{
> + struct xcan_priv *priv = netdev_priv(ndev);
> + struct net_device_stats *stats = &ndev->stats;
> + struct can_frame *cf;
> + struct sk_buff *skb;
> + u32 err_status, status;
> +
> + skb = alloc_can_err_skb(ndev, &cf);
> + if (!skb) {
> + netdev_err(ndev, "alloc_can_err_skb() failed!\n");
> + return;
> + }
> +
> + err_status = priv->read_reg(priv, XCAN_ESR_OFFSET);
> + priv->write_reg(priv, XCAN_ESR_OFFSET, err_status);
> + status = priv->read_reg(priv, XCAN_SR_OFFSET);
> +
> + if (isr & XCAN_IXR_BSOFF_MASK) {
> + priv->can.state = CAN_STATE_BUS_OFF;
> + cf->can_id |= CAN_ERR_BUSOFF;
> + priv->can.can_stats.bus_off++;
> + /* Leave device in Config Mode in bus-off state */
> + priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_RESET_MASK);
> + can_bus_off(ndev);
> + } else if ((status & XCAN_SR_ESTAT_MASK) == XCAN_SR_ESTAT_MASK) {
> + cf->can_id |= CAN_ERR_CRTL;
> + priv->can.state = CAN_STATE_ERROR_PASSIVE;
> + priv->can.can_stats.error_passive++;
> + cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE |
> + CAN_ERR_CRTL_TX_PASSIVE;
> + } else if (status & XCAN_SR_ERRWRN_MASK) {
> + cf->can_id |= CAN_ERR_CRTL;
> + priv->can.state = CAN_STATE_ERROR_WARNING;
> + priv->can.can_stats.error_warning++;
> + cf->data[1] |= CAN_ERR_CRTL_RX_WARNING |
> + CAN_ERR_CRTL_TX_WARNING;
> + }
> +
> + /* Check for Arbitration lost interrupt */
> + if (isr & XCAN_IXR_ARBLST_MASK) {
> + cf->can_id |= CAN_ERR_LOSTARB;
> + cf->data[0] = CAN_ERR_LOSTARB_UNSPEC;
> + priv->can.can_stats.arbitration_lost++;
> + }
> +
> + /* Check for RX FIFO Overflow interrupt */
> + if (isr & XCAN_IXR_RXOFLW_MASK) {
> + cf->can_id |= CAN_ERR_CRTL;
> + cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
> + stats->rx_over_errors++;
> + stats->rx_errors++;
> + priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_RESET_MASK);
> + }
> +
> + /* Check for error interrupt */
> + if (isr & XCAN_IXR_ERROR_MASK) {
> + cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
> + cf->data[2] |= CAN_ERR_PROT_UNSPEC;
> +
> + /* Check for Ack error interrupt */
> + if (err_status & XCAN_ESR_ACKER_MASK) {
> + cf->can_id |= CAN_ERR_ACK;
> + cf->data[3] |= CAN_ERR_PROT_LOC_ACK;
> + stats->tx_errors++;
> + }
> +
> + /* Check for Bit error interrupt */
> + if (err_status & XCAN_ESR_BERR_MASK) {
> + cf->can_id |= CAN_ERR_PROT;
> + cf->data[2] = CAN_ERR_PROT_BIT;
> + stats->tx_errors++;
> + }
> +
> + /* Check for Stuff error interrupt */
> + if (err_status & XCAN_ESR_STER_MASK) {
> + cf->can_id |= CAN_ERR_PROT;
> + cf->data[2] = CAN_ERR_PROT_STUFF;
> + stats->rx_errors++;
> + }
> +
> + /* Check for Form error interrupt */
> + if (err_status & XCAN_ESR_FMER_MASK) {
> + cf->can_id |= CAN_ERR_PROT;
> + cf->data[2] = CAN_ERR_PROT_FORM;
> + stats->rx_errors++;
> + }
> +
> + /* Check for CRC error interrupt */
> + if (err_status & XCAN_ESR_CRCER_MASK) {
> + cf->can_id |= CAN_ERR_PROT;
> + cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ |
> + CAN_ERR_PROT_LOC_CRC_DEL;
> + stats->rx_errors++;
> + }
> + priv->can.can_stats.bus_error++;
> + }
> +
> + netif_rx(skb);
> + stats->rx_packets++;
> + stats->rx_bytes += cf->can_dlc;
> +
> + netdev_dbg(ndev, "%s: error status register:0x%x\n",
> + __func__, priv->read_reg(priv, XCAN_ESR_OFFSET));
> +}
> +
> +/**
> + * xcan_state_interrupt - It will check the state of the CAN device
> + * @ndev: net_device pointer
> + * @isr: interrupt status register value
> + *
> + * This will checks the state of the CAN device
> + * and puts the device into appropriate state.
> + */
> +static void xcan_state_interrupt(struct net_device *ndev, u32 isr)
> +{
> + struct xcan_priv *priv = netdev_priv(ndev);
> +
> + /* Check for Sleep interrupt if set put CAN device in sleep state */
> + if (isr & XCAN_IXR_SLP_MASK)
> + priv->can.state = CAN_STATE_SLEEPING;
> +
> + /* Check for Wake up interrupt if set put CAN device in Active state */
> + if (isr & XCAN_IXR_WKUP_MASK)
> + priv->can.state = CAN_STATE_ERROR_ACTIVE;
> +}
> +
> +/**
> + * xcan_rx_poll - Poll routine for rx packets (NAPI)
> + * @napi: napi structure pointer
> + * @quota: Max number of rx packets to be processed.
> + *
> + * This is the poll routine for rx part.
> + * It will process the packets maximux quota value.
> + *
> + * Return: number of packets received
> + */
> +static int xcan_rx_poll(struct napi_struct *napi, int quota)
> +{
> + struct net_device *ndev = napi->dev;
> + struct xcan_priv *priv = netdev_priv(ndev);
> + u32 isr, ier;
> + int work_done = 0;
> +
> + isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
> + while ((isr & XCAN_IXR_RXNEMP_MASK) && (work_done < quota)) {
> + if (isr & XCAN_IXR_RXOK_MASK) {
> + priv->write_reg(priv, XCAN_ICR_OFFSET,
> + XCAN_IXR_RXOK_MASK);
> + if (xcan_rx(ndev) < 0)
> + return work_done;
> + work_done++;
> + } else {
> + priv->write_reg(priv, XCAN_ICR_OFFSET,
> + XCAN_IXR_RXNEMP_MASK);
> + break;
> + }
> + priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_RXNEMP_MASK);
> + isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
> + }
> +
> + if (work_done < quota) {
> + napi_complete(napi);
> + ier = priv->read_reg(priv, XCAN_IER_OFFSET);
> + ier |= (XCAN_IXR_RXOK_MASK | XCAN_IXR_RXNEMP_MASK);
> + priv->write_reg(priv, XCAN_IER_OFFSET, ier);
> + }
> + return work_done;
> +}
> +
> +/**
> + * xcan_tx_interrupt - Tx Done Isr
> + * @ndev: net_device pointer
> + * @isr: Interrupt status register value
> + */
> +static void xcan_tx_interrupt(struct net_device *ndev, u32 isr)
> +{
> + struct xcan_priv *priv = netdev_priv(ndev);
> + struct net_device_stats *stats = &ndev->stats;
> +
> + stats->tx_packets++;
Your tx_packats is only incremented once, even if there is more than one
frame transmitted.
This loop looks broken. Can you explain how it works.
What it shoud do is:
We have put (priv->tx_head - priv->tx_tail) CAN frames into the FIFO.
This means at maximum there could be this amount of CAN frames which
have been successfully transmitted. For every cycle in this while loop
you should:
a) check if a CAN frame has successfully been transmitted
(as this CAN core uses a FIFO it should be "oldest")
A read_reg() of some kind is missing in your loop.
b) if needed, remove this event from the FIFO or
mark the interrupt as done. Whatever you hardware needs.
c) update your statistics
d) Use can_get_echo_skb to push this frame into the networking stack
e) As a CAN frame has been transmitted successfully, wake the tx_queue.
> + while (priv->tx_head - priv->tx_tail > 0) {
> + if (isr & XCAN_IXR_TXFLL_MASK) {
> + priv->write_reg(priv, XCAN_ICR_OFFSET,
> + XCAN_IXR_TXFLL_MASK);
> + netif_stop_queue(ndev);
Why do you stop the queue here? A CAN frame has successfully been
transmitted, there should be room in the FIFO.
> + break;
> + }
> + can_get_echo_skb(ndev, priv->tx_tail %
> + priv->xcan_echo_skb_max_tx);
> + priv->tx_tail++;
> + }
> +
> + netif_wake_queue(ndev);
> + can_led_event(ndev, CAN_LED_EVENT_TX);
> +}
> +
> +/**
> + * xcan_interrupt - CAN Isr
> + * @irq: irq number
> + * @dev_id: device id poniter
> + *
> + * This is the xilinx CAN Isr. It checks for the type of interrupt
> + * and invokes the corresponding ISR.
> + *
> + * Return:
> + * IRQ_NONE - If CAN device is in sleep mode, IRQ_HANDLED otherwise
> + */
> +static irqreturn_t xcan_interrupt(int irq, void *dev_id)
> +{
> + struct net_device *ndev = (struct net_device *)dev_id;
> + struct xcan_priv *priv = netdev_priv(ndev);
> + u32 isr, ier;
> +
> + /* Get the interrupt status from Xilinx CAN */
> + isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
> + if (!isr)
> + return IRQ_NONE;
> +
> + netdev_dbg(ndev, "%s: isr:#x%08x, err:#x%08x\n", __func__,
> + isr, priv->read_reg(priv, XCAN_ESR_OFFSET));
> +
> + /* Check for the type of interrupt and Processing it */
> + if (isr & (XCAN_IXR_SLP_MASK | XCAN_IXR_WKUP_MASK)) {
> + priv->write_reg(priv, XCAN_ICR_OFFSET, (XCAN_IXR_SLP_MASK |
> + XCAN_IXR_WKUP_MASK));
> + xcan_state_interrupt(ndev, isr);
> + }
> +
> + /* Check for Tx interrupt and Processing it */
> + if (isr & XCAN_IXR_TXOK_MASK) {
> + priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXOK_MASK);
> + xcan_tx_interrupt(ndev, isr);
> + }
> +
> + /* Check for the type of error interrupt and Processing it */
> + if (isr & (XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK |
> + XCAN_IXR_BSOFF_MASK | XCAN_IXR_ARBLST_MASK)) {
> + priv->write_reg(priv, XCAN_ICR_OFFSET, (XCAN_IXR_ERROR_MASK |
> + XCAN_IXR_RXOFLW_MASK | XCAN_IXR_BSOFF_MASK |
> + XCAN_IXR_ARBLST_MASK));
> + xcan_err_interrupt(ndev, isr);
> + }
> +
> + /* Check for the type of receive interrupt and Processing it */
> + if (isr & (XCAN_IXR_RXNEMP_MASK | XCAN_IXR_RXOK_MASK)) {
> + ier = priv->read_reg(priv, XCAN_IER_OFFSET);
> + ier &= ~(XCAN_IXR_RXNEMP_MASK | XCAN_IXR_RXOK_MASK);
> + priv->write_reg(priv, XCAN_IER_OFFSET, ier);
> + napi_schedule(&priv->napi);
> + }
> + return IRQ_HANDLED;
> +}
> +
> +/**
> + * xcan_stop - Driver stop routine
> + * @ndev: Pointer to net_device structure
> + *
> + * This is the drivers stop routine. It will disable the
> + * interrupts and put the device into configuration mode.
> + */
> +static void xcan_stop(struct net_device *ndev)
please name it chip_stop as it's the inverse of chip_start
> +{
> + struct xcan_priv *priv = netdev_priv(ndev);
> + u32 ier;
> +
> + /* Disable interrupts and leave the can in configuration mode */
> + ier = priv->read_reg(priv, XCAN_IER_OFFSET);
> + ier &= ~XCAN_INTR_ALL;
> + priv->write_reg(priv, XCAN_IER_OFFSET, ier);
> + priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_RESET_MASK);
> + priv->can.state = CAN_STATE_STOPPED;
> +}
> +
> +/**
> + * xcan_open - Driver open routine
> + * @ndev: Pointer to net_device structure
> + *
> + * This is the driver open routine.
> + * Return: 0 on success and failure value on error
> + */
> +static int xcan_open(struct net_device *ndev)
> +{
> + struct xcan_priv *priv = netdev_priv(ndev);
> + int ret;
> +
enable clocks
> + ret = request_irq(ndev->irq, xcan_interrupt, priv->irq_flags,
> + ndev->name, (void *)ndev);
nitpick: the (void *) cast is not needed.
> + if (ret < 0) {
> + netdev_err(ndev, "Irq allocation for CAN failed\n");
> + return ret;
> + }
> +
> + /* Set chip into reset mode */
> + ret = set_reset_mode(ndev);
> + if (ret < 0) {
> + netdev_err(ndev, "mode resetting failed failed!\n");
> + free_irq(ndev->irq, ndev);
> + return ret;
> + }
> +
> + /* Common open */
> + ret = open_candev(ndev);
> + if (ret) {
> + free_irq(ndev->irq, ndev);
> + return ret;
> + }
> +
> + ret = xcan_chip_start(ndev);
> + if (ret < 0)
free irq missing....better introduce a label at the end of the function
and use goto to clean up.
> + netdev_err(ndev, "xcan_chip_start failed!\n");
> +
> +
> + can_led_event(ndev, CAN_LED_EVENT_OPEN);
> + napi_enable(&priv->napi);
> + netif_start_queue(ndev);
> +
> + return 0;
> +}
> +
> +/**
> + * xcan_close - Driver close routine
> + * @ndev: Pointer to net_device structure
> + *
> + * Return: 0 always
> + */
> +static int xcan_close(struct net_device *ndev)
> +{
> + struct xcan_priv *priv = netdev_priv(ndev);
> +
> + netif_stop_queue(ndev);
> + napi_disable(&priv->napi);
> + xcan_stop(ndev);
> + free_irq(ndev->irq, ndev);
> + close_candev(ndev);
> +
add stop clocks somewhere here
> + can_led_event(ndev, CAN_LED_EVENT_STOP);
> +
> + return 0;
> +}
> +
> +/**
> + * xcan_get_berr_counter - error counter routine
> + * @ndev: Pointer to net_device structure
> + * @bec: Pointer to can_berr_counter structure
> + *
> + * This is the driver error counter routine.
> + * Return: 0 always
> + */
> +static int xcan_get_berr_counter(const struct net_device *ndev,
> + struct can_berr_counter *bec)
> +{
> + struct xcan_priv *priv = netdev_priv(ndev);
If you leave the clock switched off after probe (see below), you
probalby have to enable the clocks here.
> +
> + bec->txerr = priv->read_reg(priv, XCAN_ECR_OFFSET) & XCAN_ECR_TEC_MASK;
> + bec->rxerr = ((priv->read_reg(priv, XCAN_ECR_OFFSET) &
> + XCAN_ECR_REC_MASK) >> XCAN_ESR_REC_SHIFT);
> +
and disable here again.
> + return 0;
> +}
> +
> +static const struct net_device_ops xcan_netdev_ops = {
> + .ndo_open = xcan_open,
> + .ndo_stop = xcan_close,
> + .ndo_start_xmit = xcan_start_xmit,
> +};
> +
> +#ifdef CONFIG_PM_SLEEP
> +/**
> + * xcan_suspend - Suspend method for the driver
> + * @_dev: Address of the platform_device structure
> + *
> + * Put the driver into low power mode.
> + * Return: 0 always
> + */
> +static int xcan_suspend(struct device *_dev)
> +{
> + struct platform_device *pdev = container_of(_dev,
> + struct platform_device, dev);
> + struct net_device *ndev = platform_get_drvdata(pdev);
> + struct xcan_priv *priv = netdev_priv(ndev);
> +
> + if (netif_running(ndev)) {
> + netif_stop_queue(ndev);
> + netif_device_detach(ndev);
> + }
> +
> + priv->write_reg(priv, XCAN_MSR_OFFSET, XCAN_MSR_SLEEP_MASK);
> + priv->can.state = CAN_STATE_SLEEPING;
> +
> + clk_disable(priv->aperclk);
> + clk_disable(priv->devclk);
> +
> + return 0;
> +}
> +
> +/**
> + * xcan_resume - Resume from suspend
> + * @dev: Address of the platformdevice structure
> + *
> + * Resume operation after suspend.
> + * Return: 0 on success and failure value on error
> + */
> +static int xcan_resume(struct device *dev)
> +{
> + struct platform_device *pdev = container_of(dev,
> + struct platform_device, dev);
> + struct net_device *ndev = platform_get_drvdata(pdev);
> + struct xcan_priv *priv = netdev_priv(ndev);
> + int ret;
> +
> + ret = clk_enable(priv->aperclk);
> + if (ret) {
> + dev_err(dev, "Cannot enable clock.\n");
> + return ret;
> + }
> + ret = clk_enable(priv->devclk);
> + if (ret) {
> + dev_err(dev, "Cannot enable clock.\n");
please disable aperclk
> + return ret;
> + }
> +
> + priv->write_reg(priv, XCAN_MSR_OFFSET, 0);
> + priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_CEN_MASK);
> + priv->can.state = CAN_STATE_ERROR_ACTIVE;
> +
> + if (netif_running(ndev)) {
> + netif_device_attach(ndev);
> + netif_start_queue(ndev);
> + }
> +
> + return 0;
> +}
> +#endif
> +
> +static SIMPLE_DEV_PM_OPS(xcan_dev_pm_ops, xcan_suspend, xcan_resume);
> +
> +/**
> + * xcan_probe - Platform registration call
> + * @pdev: Handle to the platform device structure
> + *
> + * This function does all the memory allocation and registration for the CAN
> + * device.
> + *
> + * Return: 0 on success and failure value on error
> + */
> +static int xcan_probe(struct platform_device *pdev)
> +{
> + struct resource *res; /* IO mem resources */
> + struct net_device *ndev;
> + struct xcan_priv *priv;
> + int ret;
> +
> + /* Create a CAN device instance */
> + ndev = alloc_candev(sizeof(struct xcan_priv), XCAN_ECHO_SKB_MAX);
> + if (!ndev)
> + return -ENOMEM;
> +
> + priv = netdev_priv(ndev);
> + priv->dev = ndev;
> + priv->can.bittiming_const = &xcan_bittiming_const;
> + priv->can.do_set_bittiming = xcan_set_bittiming;
> + priv->can.do_set_mode = xcan_do_set_mode;
> + priv->can.do_get_berr_counter = xcan_get_berr_counter;
> + priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
> + CAN_CTRLMODE_BERR_REPORTING;
> +
> + /* Get IRQ for the device */
> + ndev->irq = platform_get_irq(pdev, 0);
> + ndev->flags |= IFF_ECHO; /* We support local echo */
> +
> + platform_set_drvdata(pdev, ndev);
> + SET_NETDEV_DEV(ndev, &pdev->dev);
> + ndev->netdev_ops = &xcan_netdev_ops;
> +
> + /* Get the virtual base address for the device */
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + priv->reg_base = devm_ioremap_resource(&pdev->dev, res);
> + if (IS_ERR(priv->reg_base)) {
> + ret = PTR_ERR(priv->reg_base);
> + goto err_free;
> + }
> + ndev->mem_start = res->start;
> + ndev->mem_end = res->end;
Please don't assign mem_start and _end.
> +
> + ret = of_property_read_u32(pdev->dev.of_node, "tx-fifo-depth",
> + &priv->xcan_echo_skb_max_tx);
> + if (ret < 0)
> + goto err_free;
> +
> + ret = of_property_read_u32(pdev->dev.of_node, "rx-fifo-depth",
> + &priv->xcan_echo_skb_max_rx);
> + if (ret < 0)
> + goto err_free;
> +
> + /* Getting the CAN devclk info */
> + priv->devclk = devm_clk_get(&pdev->dev, "ref_clk");
> + if (IS_ERR(priv->devclk)) {
> + dev_err(&pdev->dev, "Device clock not found.\n");
> + ret = PTR_ERR(priv->devclk);
> + goto err_free;
> + }
> +
> + /* Check for type of CAN device */
> + if (of_device_is_compatible(pdev->dev.of_node,
> + "xlnx,zynq-can-1.00.a")) {
> + priv->aperclk = devm_clk_get(&pdev->dev, "aper_clk");
> + if (IS_ERR(priv->aperclk)) {
> + dev_err(&pdev->dev, "aper clock not found\n");
> + ret = PTR_ERR(priv->aperclk);
> + goto err_free;
> + }
> + } else {
> + priv->aperclk = priv->devclk;
> + }
> +
> + ret = clk_prepare_enable(priv->devclk);
> + if (ret) {
> + dev_err(&pdev->dev, "unable to enable device clock\n");
> + goto err_free;
> + }
> +
> + ret = clk_prepare_enable(priv->aperclk);
> + if (ret) {
> + dev_err(&pdev->dev, "unable to enable aper clock\n");
> + goto err_unprepar_disabledev;
> + }
> +
> + priv->write_reg = xcan_write_reg_le;
> + priv->read_reg = xcan_read_reg_le;
> +
> + if (priv->read_reg(priv, XCAN_SR_OFFSET) != XCAN_SR_CONFIG_MASK) {
> + priv->write_reg = xcan_write_reg_be;
> + priv->read_reg = xcan_read_reg_be;
> + }
> +
> + priv->can.clock.freq = clk_get_rate(priv->devclk);
> +
> + netif_napi_add(ndev, &priv->napi, xcan_rx_poll,
> + priv->xcan_echo_skb_max_rx);
please align with the opening bracket
> +
> + ret = register_candev(ndev);
> + if (ret) {
> + dev_err(&pdev->dev, "fail to register failed (err=%d)\n", ret);
> + goto err_unprepar_disableaper;
> + }
> +
> + devm_can_led_init(ndev);
> + dev_info(&pdev->dev,
> + "reg_base=0x%p irq=%d clock=%d, tx fifo depth:%d\n",
> + priv->reg_base, ndev->irq, priv->can.clock.freq,
> + priv->xcan_echo_skb_max_tx);
please use netdev_dbg
please disable the clocks here, as they are not used until open().
> +
> + return 0;
> +
> +err_unprepar_disableaper:
> + clk_disable_unprepare(priv->aperclk);
> +err_unprepar_disabledev:
> + clk_disable_unprepare(priv->devclk);
> +err_free:
> + free_candev(ndev);
> +
> + return ret;
> +}
> +
> +/**
> + * xcan_remove - Unregister the device after releasing the resources
> + * @pdev: Handle to the platform device structure
> + *
> + * This function frees all the resources allocated to the device.
> + * Return: 0 always
> + */
> +static int xcan_remove(struct platform_device *pdev)
> +{
> + struct net_device *ndev = platform_get_drvdata(pdev);
> + struct xcan_priv *priv = netdev_priv(ndev);
> +
> + if (set_reset_mode(ndev) < 0)
> + netdev_err(ndev, "mode resetting failed!\n");
> +
> + unregister_candev(ndev);
> + netif_napi_del(&priv->napi);
> + clk_disable_unprepare(priv->aperclk);
> + clk_disable_unprepare(priv->devclk);
> + free_candev(ndev);
> +
> + return 0;
> +}
> +
> +/* Match table for OF platform binding */
> +static struct of_device_id xcan_of_match[] = {
> + { .compatible = "xlnx,zynq-can-1.00.a", },
> + { .compatible = "xlnx,axi-can-1.00.a", },
> + { /* end of list */ },
> +};
> +MODULE_DEVICE_TABLE(of, xcan_of_match);
> +
> +static struct platform_driver xcan_driver = {
> + .probe = xcan_probe,
> + .remove = xcan_remove,
> + .driver = {
> + .owner = THIS_MODULE,
> + .name = DRIVER_NAME,
> + .pm = &xcan_dev_pm_ops,
> + .of_match_table = xcan_of_match,
> + },
> +};
> +
> +module_platform_driver(xcan_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Xilinx Inc");
> +MODULE_DESCRIPTION("Xilinx CAN interface");
>
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 242 bytes --]
^ permalink raw reply
* [PATCH 0/4] ARM: dts: keystone: Add support for K2H and K2E SOCs/EVMs
From: Santosh Shilimkar @ 2014-02-25 21:50 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Santosh Shilimkar,
Olof Johansson, Arnd Bergmann, Rob Herring, Kumar Gala,
Mark Rutland
Series adds support for two Keystone2 SOCs called Lammar(K2L) and Edision(K2E)
with respective EVMs. As seen from changes, just device tree updates are needed
to support the SOCs and EVMs which is the goal with DT :)
Kyetsone2 Edision SOC(K2E):
- It is a Quad Cortex A15 based SoC with 1 DSP.
- Standard peripherals such as i2c, spi, uart, timer, etc similar to K2H.
- Additional instances of PCIE and USB
- No wireless hardware accelerators.
Keystone2 Lamarr SOC(K2L):
- It is a dual Cortex A15 core based SoC with 4 DSPs.
- Standard peripherals such as i2c, spi, uart, timer, pcie etc., similar to K2H
- Different set of wireless hardware w.r.t K2H.
Series has been boot tested on K2L and K2E EVMs.
Cc: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
Cc: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
Cc: Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: Kumar Gala <galak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Cc: Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>
Murali Karicheri (4):
ARM: dts: keystone: update for supporting K2L/K2E EVMs
ARM: dts: keystone: preparatory patch to support K2L and K2E SOCs
ARM: dts: keystone: add support for K2 Lamarr SoC and EVM
ARM: dts: keystone: add support for k2 Edison SoC and EVM
.../devicetree/bindings/arm/keystone/keystone.txt | 10 +
arch/arm/boot/dts/k2e-clocks.dtsi | 78 ++++
arch/arm/boot/dts/k2e-evm.dts | 60 +++
arch/arm/boot/dts/k2e.dtsi | 80 ++++
arch/arm/boot/dts/k2hk-clocks.dtsi | 426 ++++++++++++++++++++
arch/arm/boot/dts/k2hk-evm.dts | 6 +-
arch/arm/boot/dts/k2hk.dtsi | 46 +++
arch/arm/boot/dts/k2l-clocks.dtsi | 267 ++++++++++++
arch/arm/boot/dts/k2l-evm.dts | 37 ++
arch/arm/boot/dts/k2l.dtsi | 55 +++
arch/arm/boot/dts/keystone-clocks.dtsi | 405 -------------------
arch/arm/boot/dts/keystone.dtsi | 31 --
arch/arm/mach-keystone/keystone.c | 3 +
13 files changed, 1066 insertions(+), 438 deletions(-)
create mode 100644 arch/arm/boot/dts/k2e-clocks.dtsi
create mode 100644 arch/arm/boot/dts/k2e-evm.dts
create mode 100644 arch/arm/boot/dts/k2e.dtsi
create mode 100644 arch/arm/boot/dts/k2hk-clocks.dtsi
create mode 100644 arch/arm/boot/dts/k2hk.dtsi
create mode 100644 arch/arm/boot/dts/k2l-clocks.dtsi
create mode 100644 arch/arm/boot/dts/k2l-evm.dts
create mode 100644 arch/arm/boot/dts/k2l.dtsi
Regards,
Santosh
--
1.7.9.5
--
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 1/4] ARM: dts: keystone: update for supporting K2L/K2E EVMs
From: Santosh Shilimkar @ 2014-02-25 21:50 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Murali Karicheri,
Olof Johansson, Arnd Bergmann, Rob Herring, Kumar Gala,
Mark Rutland, Santosh Shilimkar
In-Reply-To: <1393365035-20083-1-git-send-email-santosh.shilimkar-l0cyMroinI0@public.gmane.org>
From: Murali Karicheri <m-karicheri2-l0cyMroinI0@public.gmane.org>
This patch add compatibility strings for k2hk, k2l and k2e EVMs
Cc: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
Cc: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
Cc: Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: Kumar Gala <galak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Cc: Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>
Signed-off-by: Murali Karicheri <m-karicheri2-l0cyMroinI0@public.gmane.org>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar-l0cyMroinI0@public.gmane.org>
---
.../devicetree/bindings/arm/keystone/keystone.txt | 10 ++++++++++
arch/arm/mach-keystone/keystone.c | 3 +++
2 files changed, 13 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/keystone/keystone.txt b/Documentation/devicetree/bindings/arm/keystone/keystone.txt
index 63c0e6a..ad16e7a 100644
--- a/Documentation/devicetree/bindings/arm/keystone/keystone.txt
+++ b/Documentation/devicetree/bindings/arm/keystone/keystone.txt
@@ -8,3 +8,13 @@ Required properties:
- compatible: All TI specific devices present in Keystone SOC should be in
the form "ti,keystone-*". Generic devices like gic, arch_timers, ns16550
type UART should use the specified compatible for those devices.
+
+Boards:
+- Keystone 2 Hawking/Kepler EVM
+ compatible = "ti,k2hk-evm"
+
+- Keystone 2 Lamarr EVM
+ compatible = "ti,k2l-evm"
+
+- Keystone 2 Edison EVM
+ compatible = "ti,k2e-evm"
diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c
index 6e6bb7d..aa0d212 100644
--- a/arch/arm/mach-keystone/keystone.c
+++ b/arch/arm/mach-keystone/keystone.c
@@ -47,6 +47,9 @@ static void __init keystone_init(void)
static const char *keystone_match[] __initconst = {
"ti,keystone-evm",
+ "ti,k2hk-evm",
+ "ti,k2l-evm",
+ "ti,k2e-evm",
NULL,
};
--
1.7.9.5
--
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/4] ARM: dts: keystone: preparatory patch to support K2L and K2E SOCs
From: Santosh Shilimkar @ 2014-02-25 21:50 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Murali Karicheri,
Olof Johansson, Arnd Bergmann, Rob Herring, Kumar Gala,
Mark Rutland, Santosh Shilimkar
In-Reply-To: <1393365035-20083-1-git-send-email-santosh.shilimkar-l0cyMroinI0@public.gmane.org>
From: Murali Karicheri <m-karicheri2-l0cyMroinI0@public.gmane.org>
Current keystone.dtsi includes SoC specific definitions for K2HK
SoCs. In order to support two addition keystone devices, k2 Edison
and K2 Lamarr and corresponding EVMs, This patch restructure the
dts files for the following:-
- All clock nodes that are only available in k2hk SoC are moved
from keystone-clocks.dtsi to a new k2hk-clocks.dtsi include file
- The CPU nodes are now part of the soc specific k2hk.dtsi.
- Change the compatibility string to ti,k2hk-evm and change
the model name accordingly
- Finally include k2hk-clocks.dtsi in k2hk.dtsi and that in
k2hk-evm.dts
Cc: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
Cc: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
Cc: Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: Kumar Gala <galak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Cc: Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>
Signed-off-by: Murali Karicheri <m-karicheri2-l0cyMroinI0@public.gmane.org>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar-l0cyMroinI0@public.gmane.org>
---
arch/arm/boot/dts/k2hk-clocks.dtsi | 426 ++++++++++++++++++++++++++++++++
arch/arm/boot/dts/k2hk-evm.dts | 6 +-
arch/arm/boot/dts/k2hk.dtsi | 46 ++++
arch/arm/boot/dts/keystone-clocks.dtsi | 405 ------------------------------
arch/arm/boot/dts/keystone.dtsi | 31 ---
5 files changed, 476 insertions(+), 438 deletions(-)
create mode 100644 arch/arm/boot/dts/k2hk-clocks.dtsi
create mode 100644 arch/arm/boot/dts/k2hk.dtsi
diff --git a/arch/arm/boot/dts/k2hk-clocks.dtsi b/arch/arm/boot/dts/k2hk-clocks.dtsi
new file mode 100644
index 0000000..4eed84f
--- /dev/null
+++ b/arch/arm/boot/dts/k2hk-clocks.dtsi
@@ -0,0 +1,426 @@
+/*
+ * Copyright 2013-2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 Kepler/Hawking SoC clock nodes
+ *
+ * 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.
+ */
+
+clocks {
+ armpllclk: armpllclk@2620370 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,pll-clock";
+ clocks = <&refclkarm>;
+ clock-output-names = "arm-pll-clk";
+ reg = <0x02620370 4>;
+ reg-names = "control";
+ };
+
+ mainpllclk: mainpllclk@2310110 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,main-pll-clock";
+ clocks = <&refclksys>;
+ reg = <0x02620350 4>, <0x02310110 4>;
+ reg-names = "control", "multiplier";
+ fixed-postdiv = <2>;
+ };
+
+ papllclk: papllclk@2620358 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,pll-clock";
+ clocks = <&refclkpass>;
+ clock-output-names = "pa-pll-clk";
+ reg = <0x02620358 4>;
+ reg-names = "control";
+ };
+
+ ddr3apllclk: ddr3apllclk@2620360 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,pll-clock";
+ clocks = <&refclkddr3a>;
+ clock-output-names = "ddr-3a-pll-clk";
+ reg = <0x02620360 4>;
+ reg-names = "control";
+ };
+
+ ddr3bpllclk: ddr3bpllclk@2620368 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,pll-clock";
+ clocks = <&refclkddr3b>;
+ clock-output-names = "ddr-3b-pll-clk";
+ reg = <0x02620368 4>;
+ reg-names = "control";
+ };
+
+ clktsip: clktsip {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk16>;
+ clock-output-names = "tsip";
+ reg = <0x0235000c 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+
+ clksrio: clksrio {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1rstiso13>;
+ clock-output-names = "srio";
+ reg = <0x0235002c 0xb00>, <0x02350010 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <4>;
+ };
+
+ clkhyperlink0: clkhyperlink0 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk12>;
+ clock-output-names = "hyperlink-0";
+ reg = <0x02350030 0xb00>, <0x02350014 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <5>;
+ };
+
+ clkgem1: clkgem1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1>;
+ clock-output-names = "gem1";
+ reg = <0x02350040 0xb00>, <0x02350024 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <9>;
+ };
+
+ clkgem2: clkgem2 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1>;
+ clock-output-names = "gem2";
+ reg = <0x02350044 0xb00>, <0x02350028 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <10>;
+ };
+
+ clkgem3: clkgem3 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1>;
+ clock-output-names = "gem3";
+ reg = <0x02350048 0xb00>, <0x0235002c 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <11>;
+ };
+
+ clkgem4: clkgem4 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1>;
+ clock-output-names = "gem4";
+ reg = <0x0235004c 0xb00>, <0x02350030 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <12>;
+ };
+
+ clkgem5: clkgem5 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1>;
+ clock-output-names = "gem5";
+ reg = <0x02350050 0xb00>, <0x02350034 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <13>;
+ };
+
+ clkgem6: clkgem6 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1>;
+ clock-output-names = "gem6";
+ reg = <0x02350054 0xb00>, <0x02350038 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <14>;
+ };
+
+ clkgem7: clkgem7 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1>;
+ clock-output-names = "gem7";
+ reg = <0x02350058 0xb00>, <0x0235003c 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <15>;
+ };
+
+ clkddr31: clkddr31 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "ddr3-1";
+ reg = <0x02350060 0xb00>, <0x02350040 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <16>;
+ };
+
+ clktac: clktac {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "tac";
+ reg = <0x02350064 0xb00>, <0x02350044 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <17>;
+ };
+
+ clkrac01: clkrac01 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "rac-01";
+ reg = <0x02350068 0xb00>, <0x02350044 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <17>;
+ };
+
+ clkrac23: clkrac23 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "rac-23";
+ reg = <0x0235006c 0xb00>, <0x02350048 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <18>;
+ };
+
+ clkfftc0: clkfftc0 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "fftc-0";
+ reg = <0x02350070 0xb00>, <0x0235004c 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <19>;
+ };
+
+ clkfftc1: clkfftc1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "fftc-1";
+ reg = <0x02350074 0xb00>, <0x023504c0 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <19>;
+ };
+
+ clkfftc2: clkfftc2 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "fftc-2";
+ reg = <0x02350078 0xb00>, <0x02350050 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <20>;
+ };
+
+ clkfftc3: clkfftc3 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "fftc-3";
+ reg = <0x0235007c 0xb00>, <0x02350050 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <20>;
+ };
+
+ clkfftc4: clkfftc4 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "fftc-4";
+ reg = <0x02350080 0xb00>, <0x02350050 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <20>;
+ };
+
+ clkfftc5: clkfftc5 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "fftc-5";
+ reg = <0x02350084 0xb00>, <0x02350050 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <20>;
+ };
+
+ clkaif: clkaif {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "aif";
+ reg = <0x02350088 0xb00>, <0x02350054 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <21>;
+ };
+
+ clktcp3d0: clktcp3d0 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "tcp3d-0";
+ reg = <0x0235008c 0xb00>, <0x02350058 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <22>;
+ };
+
+ clktcp3d1: clktcp3d1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "tcp3d-1";
+ reg = <0x02350090 0xb00>, <0x02350058 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <22>;
+ };
+
+ clktcp3d2: clktcp3d2 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "tcp3d-2";
+ reg = <0x02350094 0xb00>, <0x0235005c 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <23>;
+ };
+
+ clktcp3d3: clktcp3d3 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "tcp3d-3";
+ reg = <0x02350098 0xb00>, <0x0235005c 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <23>;
+ };
+
+ clkvcp0: clkvcp0 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-0";
+ reg = <0x0235009c 0xb00>, <0x02350060 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <24>;
+ };
+
+ clkvcp1: clkvcp1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-1";
+ reg = <0x023500a0 0xb00>, <0x02350060 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <24>;
+ };
+
+ clkvcp2: clkvcp2 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-2";
+ reg = <0x023500a4 0xb00>, <0x02350060 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <24>;
+ };
+
+ clkvcp3: clkvcp3 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-3";
+ reg = <0x0235000a8 0xb00>, <0x02350060 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <24>;
+ };
+
+ clkvcp4: clkvcp4 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-4";
+ reg = <0x023500ac 0xb00>, <0x02350064 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <25>;
+ };
+
+ clkvcp5: clkvcp5 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-5";
+ reg = <0x023500b0 0xb00>, <0x02350064 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <25>;
+ };
+
+ clkvcp6: clkvcp6 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-6";
+ reg = <0x023500b4 0xb00>, <0x02350064 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <25>;
+ };
+
+ clkvcp7: clkvcp7 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-7";
+ reg = <0x023500b8 0xb00>, <0x02350064 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <25>;
+ };
+
+ clkbcp: clkbcp {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "bcp";
+ reg = <0x023500bc 0xb00>, <0x02350068 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <26>;
+ };
+
+ clkdxb: clkdxb {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "dxb";
+ reg = <0x023500c0 0xb00>, <0x0235006c 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <27>;
+ };
+
+ clkhyperlink1: clkhyperlink1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk12>;
+ clock-output-names = "hyperlink-1";
+ reg = <0x023500c4 0xb00>, <0x02350070 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <28>;
+ };
+
+ clkxge: clkxge {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "xge";
+ reg = <0x023500c8 0xb00>, <0x02350074 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <29>;
+ };
+};
diff --git a/arch/arm/boot/dts/k2hk-evm.dts b/arch/arm/boot/dts/k2hk-evm.dts
index 1d8ea6e..d8cc99a 100644
--- a/arch/arm/boot/dts/k2hk-evm.dts
+++ b/arch/arm/boot/dts/k2hk-evm.dts
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 Texas Instruments, Inc.
+ * Copyright 2013-2014 Texas Instruments, Inc.
*
* Keystone 2 Kepler/Hawking EVM device tree
*
@@ -10,9 +10,11 @@
/dts-v1/;
#include "keystone.dtsi"
+#include "k2hk.dtsi"
/ {
- compatible = "ti,keystone-evm";
+ compatible = "ti,k2hk-evm";
+ model = "Texas Instruments Keystone 2 Kepler/Hawking EVM";
soc {
clocks {
diff --git a/arch/arm/boot/dts/k2hk.dtsi b/arch/arm/boot/dts/k2hk.dtsi
new file mode 100644
index 0000000..c73899c
--- /dev/null
+++ b/arch/arm/boot/dts/k2hk.dtsi
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2013-2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 Kepler/Hawking soc specific device tree
+ *
+ * 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.
+ */
+
+/ {
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ interrupt-parent = <&gic>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <0>;
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <1>;
+ };
+
+ cpu@2 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <2>;
+ };
+
+ cpu@3 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <3>;
+ };
+ };
+
+ soc {
+ /include/ "k2hk-clocks.dtsi"
+ };
+};
diff --git a/arch/arm/boot/dts/keystone-clocks.dtsi b/arch/arm/boot/dts/keystone-clocks.dtsi
index a3d1f3d..93f82c7 100644
--- a/arch/arm/boot/dts/keystone-clocks.dtsi
+++ b/arch/arm/boot/dts/keystone-clocks.dtsi
@@ -13,51 +13,6 @@ clocks {
#size-cells = <1>;
ranges;
- mainpllclk: mainpllclk@2310110 {
- #clock-cells = <0>;
- compatible = "ti,keystone,main-pll-clock";
- clocks = <&refclksys>;
- reg = <0x02620350 4>, <0x02310110 4>;
- reg-names = "control", "multiplier";
- fixed-postdiv = <2>;
- };
-
- papllclk: papllclk@2620358 {
- #clock-cells = <0>;
- compatible = "ti,keystone,pll-clock";
- clocks = <&refclkpass>;
- clock-output-names = "pa-pll-clk";
- reg = <0x02620358 4>;
- reg-names = "control";
- };
-
- ddr3apllclk: ddr3apllclk@2620360 {
- #clock-cells = <0>;
- compatible = "ti,keystone,pll-clock";
- clocks = <&refclkddr3a>;
- clock-output-names = "ddr-3a-pll-clk";
- reg = <0x02620360 4>;
- reg-names = "control";
- };
-
- ddr3bpllclk: ddr3bpllclk@2620368 {
- #clock-cells = <0>;
- compatible = "ti,keystone,pll-clock";
- clocks = <&refclkddr3b>;
- clock-output-names = "ddr-3b-pll-clk";
- reg = <0x02620368 4>;
- reg-names = "control";
- };
-
- armpllclk: armpllclk@2620370 {
- #clock-cells = <0>;
- compatible = "ti,keystone,pll-clock";
- clocks = <&refclkarm>;
- clock-output-names = "arm-pll-clk";
- reg = <0x02620370 4>;
- reg-names = "control";
- };
-
mainmuxclk: mainmuxclk@2310108 {
#clock-cells = <0>;
compatible = "ti,keystone,pll-mux-clock";
@@ -297,26 +252,6 @@ clocks {
domain-id = <3>;
};
- clksrio: clksrio {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk1rstiso13>;
- clock-output-names = "srio";
- reg = <0x0235002c 0xb00>, <0x02350010 0x400>;
- reg-names = "control", "domain";
- domain-id = <4>;
- };
-
- clkhyperlink0: clkhyperlink0 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk12>;
- clock-output-names = "hyperlink-0";
- reg = <0x02350030 0xb00>, <0x02350014 0x400>;
- reg-names = "control", "domain";
- domain-id = <5>;
- };
-
clksr: clksr {
#clock-cells = <0>;
compatible = "ti,keystone,psc-clock";
@@ -337,76 +272,6 @@ clocks {
domain-id = <8>;
};
- clkgem1: clkgem1 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk1>;
- clock-output-names = "gem1";
- reg = <0x02350040 0xb00>, <0x02350024 0x400>;
- reg-names = "control", "domain";
- domain-id = <9>;
- };
-
- clkgem2: clkgem2 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk1>;
- clock-output-names = "gem2";
- reg = <0x02350044 0xb00>, <0x02350028 0x400>;
- reg-names = "control", "domain";
- domain-id = <10>;
- };
-
- clkgem3: clkgem3 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk1>;
- clock-output-names = "gem3";
- reg = <0x02350048 0xb00>, <0x0235002c 0x400>;
- reg-names = "control", "domain";
- domain-id = <11>;
- };
-
- clkgem4: clkgem4 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk1>;
- clock-output-names = "gem4";
- reg = <0x0235004c 0xb00>, <0x02350030 0x400>;
- reg-names = "control", "domain";
- domain-id = <12>;
- };
-
- clkgem5: clkgem5 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk1>;
- clock-output-names = "gem5";
- reg = <0x02350050 0xb00>, <0x02350034 0x400>;
- reg-names = "control", "domain";
- domain-id = <13>;
- };
-
- clkgem6: clkgem6 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk1>;
- clock-output-names = "gem6";
- reg = <0x02350054 0xb00>, <0x02350038 0x400>;
- reg-names = "control", "domain";
- domain-id = <14>;
- };
-
- clkgem7: clkgem7 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk1>;
- clock-output-names = "gem7";
- reg = <0x02350058 0xb00>, <0x0235003c 0x400>;
- reg-names = "control", "domain";
- domain-id = <15>;
- };
-
clkddr30: clkddr30 {
#clock-cells = <0>;
compatible = "ti,keystone,psc-clock";
@@ -417,276 +282,6 @@ clocks {
domain-id = <16>;
};
- clkddr31: clkddr31 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "ddr3-1";
- reg = <0x02350060 0xb00>, <0x02350040 0x400>;
- reg-names = "control", "domain";
- domain-id = <16>;
- };
-
- clktac: clktac {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "tac";
- reg = <0x02350064 0xb00>, <0x02350044 0x400>;
- reg-names = "control", "domain";
- domain-id = <17>;
- };
-
- clkrac01: clktac01 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "rac-01";
- reg = <0x02350068 0xb00>, <0x02350044 0x400>;
- reg-names = "control", "domain";
- domain-id = <17>;
- };
-
- clkrac23: clktac23 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "rac-23";
- reg = <0x0235006c 0xb00>, <0x02350048 0x400>;
- reg-names = "control", "domain";
- domain-id = <18>;
- };
-
- clkfftc0: clkfftc0 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "fftc-0";
- reg = <0x02350070 0xb00>, <0x0235004c 0x400>;
- reg-names = "control", "domain";
- domain-id = <19>;
- };
-
- clkfftc1: clkfftc1 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "fftc-1";
- reg = <0x02350074 0xb00>, <0x023504c0 0x400>;
- reg-names = "control", "domain";
- domain-id = <19>;
- };
-
- clkfftc2: clkfftc2 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "fftc-2";
- reg = <0x02350078 0xb00>, <0x02350050 0x400>;
- reg-names = "control", "domain";
- domain-id = <20>;
- };
-
- clkfftc3: clkfftc3 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "fftc-3";
- reg = <0x0235007c 0xb00>, <0x02350050 0x400>;
- reg-names = "control", "domain";
- domain-id = <20>;
- };
-
- clkfftc4: clkfftc4 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "fftc-4";
- reg = <0x02350080 0xb00>, <0x02350050 0x400>;
- reg-names = "control", "domain";
- domain-id = <20>;
- };
-
- clkfftc5: clkfftc5 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "fftc-5";
- reg = <0x02350084 0xb00>, <0x02350050 0x400>;
- reg-names = "control", "domain";
- domain-id = <20>;
- };
-
- clkaif: clkaif {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "aif";
- reg = <0x02350088 0xb00>, <0x02350054 0x400>;
- reg-names = "control", "domain";
- domain-id = <21>;
- };
-
- clktcp3d0: clktcp3d0 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "tcp3d-0";
- reg = <0x0235008c 0xb00>, <0x02350058 0x400>;
- reg-names = "control", "domain";
- domain-id = <22>;
- };
-
- clktcp3d1: clktcp3d1 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "tcp3d-1";
- reg = <0x02350090 0xb00>, <0x02350058 0x400>;
- reg-names = "control", "domain";
- domain-id = <22>;
- };
-
- clktcp3d2: clktcp3d2 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "tcp3d-2";
- reg = <0x02350094 0xb00>, <0x0235005c 0x400>;
- reg-names = "control", "domain";
- domain-id = <23>;
- };
-
- clktcp3d3: clktcp3d3 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "tcp3d-3";
- reg = <0x02350098 0xb00>, <0x0235005c 0x400>;
- reg-names = "control", "domain";
- domain-id = <23>;
- };
-
- clkvcp0: clkvcp0 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "vcp-0";
- reg = <0x0235009c 0xb00>, <0x02350060 0x400>;
- reg-names = "control", "domain";
- domain-id = <24>;
- };
-
- clkvcp1: clkvcp1 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "vcp-1";
- reg = <0x023500a0 0xb00>, <0x02350060 0x400>;
- reg-names = "control", "domain";
- domain-id = <24>;
- };
-
- clkvcp2: clkvcp2 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "vcp-2";
- reg = <0x023500a4 0xb00>, <0x02350060 0x400>;
- reg-names = "control", "domain";
- domain-id = <24>;
- };
-
- clkvcp3: clkvcp3 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "vcp-3";
- reg = <0x0235000a8 0xb00>, <0x02350060 0x400>;
- reg-names = "control", "domain";
- domain-id = <24>;
- };
-
- clkvcp4: clkvcp4 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "vcp-4";
- reg = <0x023500ac 0xb00>, <0x02350064 0x400>;
- reg-names = "control", "domain";
- domain-id = <25>;
- };
-
- clkvcp5: clkvcp5 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "vcp-5";
- reg = <0x023500b0 0xb00>, <0x02350064 0x400>;
- reg-names = "control", "domain";
- domain-id = <25>;
- };
-
- clkvcp6: clkvcp6 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "vcp-6";
- reg = <0x023500b4 0xb00>, <0x02350064 0x400>;
- reg-names = "control", "domain";
- domain-id = <25>;
- };
-
- clkvcp7: clkvcp7 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "vcp-7";
- reg = <0x023500b8 0xb00>, <0x02350064 0x400>;
- reg-names = "control", "domain";
- domain-id = <25>;
- };
-
- clkbcp: clkbcp {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "bcp";
- reg = <0x023500bc 0xb00>, <0x02350068 0x400>;
- reg-names = "control", "domain";
- domain-id = <26>;
- };
-
- clkdxb: clkdxb {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "dxb";
- reg = <0x023500c0 0xb00>, <0x0235006c 0x400>;
- reg-names = "control", "domain";
- domain-id = <27>;
- };
-
- clkhyperlink1: clkhyperlink1 {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk12>;
- clock-output-names = "hyperlink-1";
- reg = <0x023500c4 0xb00>, <0x02350070 0x400>;
- reg-names = "control", "domain";
- domain-id = <28>;
- };
-
- clkxge: clkxge {
- #clock-cells = <0>;
- compatible = "ti,keystone,psc-clock";
- clocks = <&chipclk13>;
- clock-output-names = "xge";
- reg = <0x023500c8 0xb00>, <0x02350074 0x400>;
- reg-names = "control", "domain";
- domain-id = <29>;
- };
-
clkwdtimer0: clkwdtimer0 {
#clock-cells = <0>;
compatible = "ti,keystone,psc-clock";
diff --git a/arch/arm/boot/dts/keystone.dtsi b/arch/arm/boot/dts/keystone.dtsi
index 4eceb46..1992351 100644
--- a/arch/arm/boot/dts/keystone.dtsi
+++ b/arch/arm/boot/dts/keystone.dtsi
@@ -25,37 +25,6 @@
reg = <0x00000000 0x80000000 0x00000000 0x40000000>;
};
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- interrupt-parent = <&gic>;
-
- cpu@0 {
- compatible = "arm,cortex-a15";
- device_type = "cpu";
- reg = <0>;
- };
-
- cpu@1 {
- compatible = "arm,cortex-a15";
- device_type = "cpu";
- reg = <1>;
- };
-
- cpu@2 {
- compatible = "arm,cortex-a15";
- device_type = "cpu";
- reg = <2>;
- };
-
- cpu@3 {
- compatible = "arm,cortex-a15";
- device_type = "cpu";
- reg = <3>;
- };
- };
-
gic: interrupt-controller {
compatible = "arm,cortex-a15-gic";
#interrupt-cells = <3>;
--
1.7.9.5
--
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 3/4] ARM: dts: keystone: add support for K2 Lamarr SoC and EVM
From: Santosh Shilimkar @ 2014-02-25 21:50 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Murali Karicheri,
Olof Johansson, Arnd Bergmann, Rob Herring, Kumar Gala,
Mark Rutland, Santosh Shilimkar
In-Reply-To: <1393365035-20083-1-git-send-email-santosh.shilimkar-l0cyMroinI0@public.gmane.org>
From: Murali Karicheri <m-karicheri2-l0cyMroinI0@public.gmane.org>
Keystone2 Lamarr (K2L) is a dual Cortex A15 core based SoC with
4 DSPs. It has standard peripherals such as i2c, spi, uart, timer,
pcie etc., similar to k2hk, but different set of wireless hardware.
This patch add support for k2 Lamarr SoC and EVM. This re-uses the
common keystone.dtsi to include common bindings across the various
k2 devices.
Cc: Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>
Cc: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
Cc: Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: Kumar Gala <galak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Cc: Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>
Signed-off-by: Murali Karicheri <m-karicheri2-l0cyMroinI0@public.gmane.org>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar-l0cyMroinI0@public.gmane.org>
---
arch/arm/boot/dts/k2l-clocks.dtsi | 267 +++++++++++++++++++++++++++++++++++++
arch/arm/boot/dts/k2l-evm.dts | 37 +++++
arch/arm/boot/dts/k2l.dtsi | 55 ++++++++
3 files changed, 359 insertions(+)
create mode 100644 arch/arm/boot/dts/k2l-clocks.dtsi
create mode 100644 arch/arm/boot/dts/k2l-evm.dts
create mode 100644 arch/arm/boot/dts/k2l.dtsi
diff --git a/arch/arm/boot/dts/k2l-clocks.dtsi b/arch/arm/boot/dts/k2l-clocks.dtsi
new file mode 100644
index 0000000..7764dc9
--- /dev/null
+++ b/arch/arm/boot/dts/k2l-clocks.dtsi
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2013-2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 lamarr SoC clock nodes
+ *
+ * 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.
+ */
+
+clocks {
+ armpllclk: armpllclk@2620370 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,pll-clock";
+ clocks = <&refclksys>;
+ clock-output-names = "arm-pll-clk";
+ reg = <0x02620370 4>;
+ reg-names = "control";
+ };
+
+ mainpllclk: mainpllclk@2310110 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,main-pll-clock";
+ clocks = <&refclksys>;
+ reg = <0x02620350 4>, <0x02310110 4>;
+ reg-names = "control", "multiplier";
+ fixed-postdiv = <2>;
+ };
+
+ papllclk: papllclk@2620358 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,pll-clock";
+ clocks = <&refclksys>;
+ clock-output-names = "pa-pll-clk";
+ reg = <0x02620358 4>;
+ reg-names = "control";
+ };
+
+ ddr3apllclk: ddr3apllclk@2620360 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,pll-clock";
+ clocks = <&refclksys>;
+ clock-output-names = "ddr-3a-pll-clk";
+ reg = <0x02620360 4>;
+ reg-names = "control";
+ };
+
+ clkdfeiqnsys: clkdfeiqnsys {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk12>;
+ clock-output-names = "dfe";
+ reg-names = "control", "domain";
+ reg = <0x02350004 0xb00>, <0x02350000 0x400>;
+ domain-id = <0>;
+ };
+
+ clkpcie1: clkpcie1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk12>;
+ clock-output-names = "pcie";
+ reg = <0x0235002c 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <4>;
+ };
+
+ clkgem1: clkgem1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1>;
+ clock-output-names = "gem1";
+ reg = <0x02350040 0xb00>, <0x02350024 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <9>;
+ };
+
+ clkgem2: clkgem2 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1>;
+ clock-output-names = "gem2";
+ reg = <0x02350044 0xb00>, <0x02350028 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <10>;
+ };
+
+ clkgem3: clkgem3 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk1>;
+ clock-output-names = "gem3";
+ reg = <0x02350048 0xb00>, <0x0235002c 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <11>;
+ };
+
+ clktac: clktac {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "tac";
+ reg = <0x02350064 0xb00>, <0x02350044 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <17>;
+ };
+
+ clkrac: clkrac {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "rac";
+ reg = <0x02350068 0xb00>, <0x02350044 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <17>;
+ };
+
+ clkdfepd0: clkdfepd0 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "dfe-pd0";
+ reg = <0x0235006c 0xb00>, <0x02350044 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <18>;
+ };
+
+ clkfftc0: clkfftc0 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "fftc-0";
+ reg = <0x02350070 0xb00>, <0x0235004c 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <19>;
+ };
+
+ clkosr: clkosr {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "osr";
+ reg = <0x02350088 0xb00>, <0x0235004c 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <21>;
+ };
+
+ clktcp3d0: clktcp3d0 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "tcp3d-0";
+ reg = <0x0235008c 0xb00>, <0x02350058 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <22>;
+ };
+
+ clktcp3d1: clktcp3d1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "tcp3d-1";
+ reg = <0x02350094 0xb00>, <0x02350058 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <23>;
+ };
+
+ clkvcp0: clkvcp0 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-0";
+ reg = <0x0235009c 0xb00>, <0x02350060 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <24>;
+ };
+
+ clkvcp1: clkvcp1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-1";
+ reg = <0x023500a0 0xb00>, <0x02350060 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <24>;
+ };
+
+ clkvcp2: clkvcp2 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-2";
+ reg = <0x023500a4 0xb00>, <0x02350060 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <24>;
+ };
+
+ clkvcp3: clkvcp3 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "vcp-3";
+ reg = <0x0235000a8 0xb00>, <0x02350060 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <24>;
+ };
+
+ clkbcp: clkbcp {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "bcp";
+ reg = <0x023500bc 0xb00>, <0x02350068 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <26>;
+ };
+
+ clkdfepd1: clkdfepd1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "dfe-pd1";
+ reg = <0x023500c0 0xb00>, <0x02350044 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <27>;
+ };
+
+ clkfftc1: clkfftc1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "fftc-1";
+ reg = <0x023500c4 0xb00>, <0x023504c0 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <28>;
+ };
+
+ clkiqnail: clkiqnail {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "iqn-ail";
+ reg = <0x023500c8 0xb00>, <0x0235004c 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <29>;
+ };
+
+ clkuart2: clkuart2 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&clkmodrst0>;
+ clock-output-names = "uart2";
+ reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+
+ clkuart3: clkuart3 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&clkmodrst0>;
+ clock-output-names = "uart3";
+ reg = <0x02350000 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/k2l-evm.dts b/arch/arm/boot/dts/k2l-evm.dts
new file mode 100644
index 0000000..ebf316a
--- /dev/null
+++ b/arch/arm/boot/dts/k2l-evm.dts
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 Lamarr EVM device tree
+ *
+ * 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.
+ */
+/dts-v1/;
+
+#include "keystone.dtsi"
+#include "k2l.dtsi"
+
+/ {
+ compatible = "ti,k2l-evm";
+ model = "Texas Instruments Keystone 2 Lamarr EVM";
+
+ soc {
+ clocks {
+ refclksys: refclksys {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <122880000>;
+ clock-output-names = "refclk-sys";
+ };
+ };
+ };
+};
+
+&usb_phy {
+ status = "okay";
+};
+
+&usb {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/k2l.dtsi b/arch/arm/boot/dts/k2l.dtsi
new file mode 100644
index 0000000..1f7f479
--- /dev/null
+++ b/arch/arm/boot/dts/k2l.dtsi
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 Lamarr SoC specific device tree
+ *
+ * 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.
+ */
+
+/ {
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ interrupt-parent = <&gic>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <0>;
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <1>;
+ };
+ };
+
+ soc {
+
+ /include/ "k2l-clocks.dtsi"
+
+ uart2: serial@02348400 {
+ compatible = "ns16550a";
+ current-speed = <115200>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ reg = <0x02348400 0x100>;
+ clocks = <&clkuart2>;
+ interrupts = <GIC_SPI 432 IRQ_TYPE_EDGE_RISING>;
+ };
+
+ uart3: serial@02348800 {
+ compatible = "ns16550a";
+ current-speed = <115200>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ reg = <0x02348800 0x100>;
+ clocks = <&clkuart3>;
+ interrupts = <GIC_SPI 435 IRQ_TYPE_EDGE_RISING>;
+ };
+ };
+};
--
1.7.9.5
--
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 4/4] ARM: dts: keystone: add support for k2 Edison SoC and EVM
From: Santosh Shilimkar @ 2014-02-25 21:50 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Murali Karicheri,
Santosh Shilimkar
In-Reply-To: <1393365035-20083-1-git-send-email-santosh.shilimkar-l0cyMroinI0@public.gmane.org>
From: Murali Karicheri <m-karicheri2-l0cyMroinI0@public.gmane.org>
Keystone2 Edison (K2E) is a Quad Cortex A15 based SoC with
1 DSP. It has standard peripherals such as i2c, spi, uart, timer,
pcie, etc similar to k2hk, but without wireless hardwares. This
patch add support for k2 Edison SoC and EVM. This re-uses the common
keystone.dtsi to include common bindings across the various k2
devices.
Signed-off-by: Murali Karicheri <m-karicheri2-l0cyMroinI0@public.gmane.org>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar-l0cyMroinI0@public.gmane.org>
---
arch/arm/boot/dts/k2e-clocks.dtsi | 78 ++++++++++++++++++++++++++++++++++++
arch/arm/boot/dts/k2e-evm.dts | 60 ++++++++++++++++++++++++++++
arch/arm/boot/dts/k2e.dtsi | 80 +++++++++++++++++++++++++++++++++++++
3 files changed, 218 insertions(+)
create mode 100644 arch/arm/boot/dts/k2e-clocks.dtsi
create mode 100644 arch/arm/boot/dts/k2e-evm.dts
create mode 100644 arch/arm/boot/dts/k2e.dtsi
diff --git a/arch/arm/boot/dts/k2e-clocks.dtsi b/arch/arm/boot/dts/k2e-clocks.dtsi
new file mode 100644
index 0000000..90774d6
--- /dev/null
+++ b/arch/arm/boot/dts/k2e-clocks.dtsi
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 Edison SoC specific device tree
+ *
+ * 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.
+ */
+
+clocks {
+ mainpllclk: mainpllclk@2310110 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,main-pll-clock";
+ clocks = <&refclksys>;
+ reg = <0x02620350 4>, <0x02310110 4>;
+ reg-names = "control", "multiplier";
+ fixed-postdiv = <2>;
+ };
+
+ papllclk: papllclk@2620358 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,pll-clock";
+ clocks = <&refclkpass>;
+ clock-output-names = "pa-pll-clk";
+ reg = <0x02620358 4>;
+ reg-names = "control";
+ };
+
+ ddr3apllclk: ddr3apllclk@2620360 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,pll-clock";
+ clocks = <&refclkddr3a>;
+ clock-output-names = "ddr-3a-pll-clk";
+ reg = <0x02620360 4>;
+ reg-names = "control";
+ };
+
+ clkusb1: clkusb1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk16>;
+ clock-output-names = "usb";
+ reg = <0x02350004 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <0>;
+ };
+
+ clkhyperlink0: clkhyperlink0 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk12>;
+ clock-output-names = "hyperlink-0";
+ reg = <0x02350030 0xb00>, <0x02350014 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <5>;
+ };
+
+ clkpcie1: clkpcie1 {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk12>;
+ clock-output-names = "pcie";
+ reg = <0x0235006c 0xb00>, <0x02350000 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <18>;
+ };
+
+ clkxge: clkxge {
+ #clock-cells = <0>;
+ compatible = "ti,keystone,psc-clock";
+ clocks = <&chipclk13>;
+ clock-output-names = "xge";
+ reg = <0x023500c8 0xb00>, <0x02350074 0x400>;
+ reg-names = "control", "domain";
+ domain-id = <29>;
+ };
+};
diff --git a/arch/arm/boot/dts/k2e-evm.dts b/arch/arm/boot/dts/k2e-evm.dts
new file mode 100644
index 0000000..bb8faeb
--- /dev/null
+++ b/arch/arm/boot/dts/k2e-evm.dts
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2013-2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 Edison EVM device tree
+ *
+ * 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.
+ */
+/dts-v1/;
+
+#include "keystone.dtsi"
+#include "k2e.dtsi"
+
+/ {
+ compatible = "ti,k2e-evm";
+ model = "Texas Instruments Keystone 2 Edison EVM";
+
+ soc {
+
+ clocks {
+ refclksys: refclksys {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <100000000>;
+ clock-output-names = "refclk-sys";
+ };
+
+ refclkpass: refclkpass {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <100000000>;
+ clock-output-names = "refclk-pass";
+ };
+
+ refclkddr3a: refclkddr3a {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <100000000>;
+ clock-output-names = "refclk-ddr3a";
+ };
+ };
+ };
+};
+
+&usb_phy {
+ status = "okay";
+};
+
+&usb {
+ status = "okay";
+};
+
+&usb1_phy {
+ status = "okay";
+};
+
+&usb1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/k2e.dtsi b/arch/arm/boot/dts/k2e.dtsi
new file mode 100644
index 0000000..03d0190
--- /dev/null
+++ b/arch/arm/boot/dts/k2e.dtsi
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2013-2014 Texas Instruments, Inc.
+ *
+ * Keystone 2 Edison soc device tree
+ *
+ * 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.
+ */
+
+/ {
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ interrupt-parent = <&gic>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <0>;
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <1>;
+ };
+
+ cpu@2 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <2>;
+ };
+
+ cpu@3 {
+ compatible = "arm,cortex-a15";
+ device_type = "cpu";
+ reg = <3>;
+ };
+ };
+
+ soc {
+ /include/ "k2e-clocks.dtsi"
+
+ usb: usb@2680000 {
+ interrupts = <GIC_SPI 152 IRQ_TYPE_EDGE_RISING>;
+ dwc3@2690000 {
+ interrupts = <GIC_SPI 152 IRQ_TYPE_EDGE_RISING>;
+ };
+ };
+
+ usb1_phy: usb_phy@2620750 {
+ compatible = "ti,keystone-usbphy";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x2620750 24>;
+ status = "disabled";
+ };
+
+ usb1: usb@25000000 {
+ compatible = "ti,keystone-dwc3";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x25000000 0x10000>;
+ clocks = <&clkusb1>;
+ clock-names = "usb";
+ interrupts = <GIC_SPI 414 IRQ_TYPE_EDGE_RISING>;
+ ranges;
+ status = "disabled";
+
+ dwc3@25010000 {
+ compatible = "synopsys,dwc3";
+ reg = <0x25010000 0x70000>;
+ interrupts = <GIC_SPI 414 IRQ_TYPE_EDGE_RISING>;
+ usb-phy = <&usb1_phy>, <&usb1_phy>;
+ };
+ };
+ };
+};
--
1.7.9.5
--
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: [PATCHv2 02/16] iommu/omap: omap_iommu_attach() should return ENODEV, not NULL
From: Suman Anna @ 2014-02-25 22:32 UTC (permalink / raw)
To: Laurent Pinchart
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Tony Lindgren,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-omap-u79uwXL29TY76Z2rM5mHXA, Florian Vaussard
In-Reply-To: <2290716.T9AJoGfoRd@avalon>
Hi Laurent,
On 02/25/2014 03:13 PM, Laurent Pinchart wrote:
> Hi Suman,
>
> Thank you for the patch.
>
> On Thursday 13 February 2014 12:15:33 Suman Anna wrote:
>> From: Florian Vaussard <florian.vaussard-p8DiymsW2f8@public.gmane.org>
>>
>> omap_iommu_attach() returns NULL or ERR_PTR in case of error, but
>> omap_iommu_attach_dev() only checks for IS_ERR. Thus a NULL return value (in
>> case driver_find_device fails) will cause the kernel to panic when
>> omap_iommu_attach_dev() dereferences the pointer.
>>
>> In such case, omap_iommu_attach() should return ENODEV, not NULL.
>>
>> Signed-off-by: Florian Vaussard <florian.vaussard-p8DiymsW2f8@public.gmane.org>
>> Acked-by: Suman Anna <s-anna-l0cyMroinI0@public.gmane.org>
>> ---
>> drivers/iommu/omap-iommu.c | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
>> index fff2ffd..6272c36 100644
>> --- a/drivers/iommu/omap-iommu.c
>> +++ b/drivers/iommu/omap-iommu.c
>> @@ -863,7 +863,7 @@ static int device_match_by_alias(struct device *dev,
>> void *data) **/
>> static struct omap_iommu *omap_iommu_attach(const char *name, u32 *iopgd)
>> {
>> - int err = -ENOMEM;
>> + int err = -ENODEV;
>> struct device *dev;
>> struct omap_iommu *obj;
>>
>> @@ -871,7 +871,7 @@ static struct omap_iommu *omap_iommu_attach(const char
>> *name, u32 *iopgd) (void *)name,
>> device_match_by_alias);
>> if (!dev)
>> - return NULL;
>> + return ERR_PTR(err);
>
> I would return ERR_PTR(-ENODEV) here, and remove the initialization at
> declaration of err above.
The initialization at the beginning is also serving one another exit
path (a check for try_module_get), where err is not being set. If the
initialization is removed, then the err has to be set explicitly at the
other place. Let me know if you still want this changed.
regards
Suman
>
>>
>> obj = to_iommu(dev);
>
^ permalink raw reply
* Re: [PATCH] ARM: tegra: add device tree for SHIELD
From: Stephen Warren @ 2014-02-25 22:38 UTC (permalink / raw)
To: Alexandre Courbot, Thierry Reding, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala, Russell King
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <530BFC58.6020003-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
On 02/24/2014 07:13 PM, Alexandre Courbot wrote:
> On 02/25/2014 03:53 AM, Stephen Warren wrote:
>> On 02/24/2014 03:26 AM, Alexandre Courbot wrote:
>>> Add a device tree for NVIDIA SHIELD. The set of enabled features is
>>> still minimal with no display option (although HDMI should be easy
>>> to get to work) and USB requiring external power.
>>> diff --git a/arch/arm/boot/dts/tegra114-roth.dts
>>> b/arch/arm/boot/dts/tegra114-roth.dts
>>
>>> + memory {
>>> + reg = <0x80000000 0x79600000>;
>>
>> It might be worth a comment here pointing out that the rest of RAM is
>> reserved for some carveouts/..., or at least that these values are set
>> this way in order to match what the bootloader usually passes to
>> downstream kernels in the command-line?
>
> Yes, absolutely right. On a more general note I feel like DTs could gain
> clarity if they had more comments (e.g. for pinmuxing which are a quite
> heavy block otherwise), do you have any objection to this? (I guess not,
> but so far the rule seems to be "no comment in DT" :P )
I have no objection in particular. Specifically for pinmux, the values
seem pretty obvious, so I'm not sure what extra the comment could
convey, but I'll take a look at any proposed patch:-)
>>> + /* Wifi */
>>> + sdhci@78000000 {
>>> + status = "okay";
>>> + bus-width = <4>;
>>> + broken-cd;
>>> + keep-power-in-suspend;
>>> + cap-sdio-irq;
>>
>> Is non-removable better than broken-cd, or are they entirely unrelated?
>
> They are unrelated actually. With non-removable the driver expects the
> device to always be there since boot, and does not check for the card to
> be removed/added after boot. broken-cd indicates there is no CD line and
> the device should be polled regularly.
It doesn't sound like that's what we want either; we should know exactly
when the device is added/removed, based on when the relevant
clocks/supplies/... are turned on/off.
> For the Wifi chip, non-removable would be the correct setting
> hardware-wise, but there is a trap: the chip has its reset line asserted
> at boot-time, and you need to set GPIO 229 to de-assert it. Only after
> that will the device be detected on the SDIO bus. Since it lacks a CD
> line, it must be polled, hence the broken-cd property.
How does that GPIO get manipulated right now? I assume you must be
manually configuring it via sysfs after boot or something? If so,
perhaps it's best to just leave out the WiFi node until it works
automatically.
> This also raises another, redundant problem with DT bindings: AFAIK we
> currently have no way to let the system know the device will only appear
> after a given GPIO is set. It would also be nice to be able to give some
> parameters to the Wifi driver through the DT (like the OOB interrupt).
> Right now the Wifi chip is brought up by exporting the GPIO and writing
> to it from user-space, and the OOB interrupt is not used.
There was a thread on this topic on LAKML recently. I didn't really
follow it, so I don't know if there was a useful resolution. I think it
was "mmc: add support for power-on sequencing through DT", although
there may have been other related threads. It was possibly tangentially
related to power-sequences-in-DT...
...
> I'm not sure about cap-sdio-irq, it doesn't seem to make a difference
> for SHIELD Wifi.
I'd tend to leave it out then.
^ permalink raw reply
* Re: [PATCHv2 07/16] iommu/omap: allow enable/disable even without pdata
From: Suman Anna @ 2014-02-25 22:41 UTC (permalink / raw)
To: Laurent Pinchart
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Tony Lindgren,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-omap-u79uwXL29TY76Z2rM5mHXA, Florian Vaussard
In-Reply-To: <5986613.CineS9pX88@avalon>
Hi Laurent,
On 02/25/2014 03:15 PM, Laurent Pinchart wrote:
> Hi Suman,
>
> Thank you for the patch.
>
> On Thursday 13 February 2014 12:15:38 Suman Anna wrote:
>> From: Florian Vaussard <florian.vaussard-p8DiymsW2f8@public.gmane.org>
>>
>> When booting with a devicetree, no platform data is provided.
>> Do not prematurely exit iommu_enable() and iommu_disable() in
>> such a case.
>>
>> Note: As OMAP do not yet has a proper reset controller driver,
>> IOMMUs requiring a reset signal should use pdata-quirks as a
>> transitional solution.
>>
>> Signed-off-by: Florian Vaussard <florian.vaussard-p8DiymsW2f8@public.gmane.org>
>
> This looks good to me, but you should move this patch before 04/16, otherwise
> you'll break bisection.
OK, I see the point w.r.t the OMAP3 ISP node. I will move it to before
03/16 (the DT bindings patch), it shouldn't make any difference.
regards
Suman
>
> Acked-by: Laurent Pinchart <laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>
>
>> ---
>> drivers/iommu/omap-iommu.c | 10 ++--------
>> 1 file changed, 2 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
>> index f6afe8f..7672eb4 100644
>> --- a/drivers/iommu/omap-iommu.c
>> +++ b/drivers/iommu/omap-iommu.c
>> @@ -149,13 +149,10 @@ static int iommu_enable(struct omap_iommu *obj)
>> struct platform_device *pdev = to_platform_device(obj->dev);
>> struct iommu_platform_data *pdata = pdev->dev.platform_data;
>>
>> - if (!pdata)
>> - return -EINVAL;
>> -
>> if (!arch_iommu)
>> return -ENODEV;
>>
>> - if (pdata->deassert_reset) {
>> + if (pdata && pdata->deassert_reset) {
>> err = pdata->deassert_reset(pdev, pdata->reset_name);
>> if (err) {
>> dev_err(obj->dev, "deassert_reset failed: %d\n", err);
>> @@ -175,14 +172,11 @@ static void iommu_disable(struct omap_iommu *obj)
>> struct platform_device *pdev = to_platform_device(obj->dev);
>> struct iommu_platform_data *pdata = pdev->dev.platform_data;
>>
>> - if (!pdata)
>> - return;
>> -
>> arch_iommu->disable(obj);
>>
>> pm_runtime_put_sync(obj->dev);
>>
>> - if (pdata->assert_reset)
>> + if (pdata && pdata->assert_reset)
>> pdata->assert_reset(pdev, pdata->reset_name);
>> }
>
^ permalink raw reply
* Re: [RFC] dt: bindings: add bindings for Broadcom bcm43xx sdio devices
From: Stephen Warren @ 2014-02-25 22:51 UTC (permalink / raw)
To: Arend van Spriel, Rob Herring
Cc: devicetree, linux-kernel, Chen-Yu Tsai, Tomasz Figa
In-Reply-To: <1392059868-8782-1-git-send-email-arend@broadcom.com>
On 02/10/2014 12:17 PM, Arend van Spriel wrote:
> The Broadcom bcm43xx sdio devices are fullmac devices that may be
> integrated in ARM platforms. Currently, the brcmfmac driver for
> these devices support use of platform data. This patch specifies
> the bindings that allow this platform data to be expressed in the
> devicetree.
> diff --git a/Documentation/devicetree/bindings/staging/net/wireless/brcm,bcm43xx-fmac.txt b/Documentation/devicetree/bindings/staging/net/wireless/brcm,bcm43xx-fmac.txt
> + - compatible : Should be "brcm,bcm43xx-fmac".
> + - wlan-supply : phandle for fixed regulator used to control power for
> + the device/module.
Ignoring the fact that perhaps this should just be a GPIO instead and
assuming it actually make sense for this to be a regulator:
Why "fixed regulator" not just "the regulator". There shouldn't be any
requirement for the power supply to the device to be fixed; the driver
should (a) set the voltage (which will be a no-op for a fixed regulator
already providing that voltage), then (b) enable the regulator. That
would allow a PMIC with programmable voltage to be feeding the device.
Now, if this property was really intended to control some enable GPIO on
the device, as others have said, this shouldn't be a regulator property
but rather a GPIO property. However, there is definitely some power
supply fed to the device, so you definitely need /some/ supply property
here.
Aren't there other enable GPIOs required? These should be specified in DT.
Doesn't the WiFi chip/module require a (32KHz?) clock? If so, that needs
to be represented in DT. Preferably write the binding to require
clock-names (name-based lookup) rather than just clocks (index-based
lookup).
> +Optional properties:
> + - drive-strength : drive strength used for SDIO pins on device (default = 6mA).
As mentioned elsewhere, since that's a binding-specific property, rename
it brcm,drive-strength.
> + - interrupt-parent : the phandle for the interrupt controller to which the
> + device interrupt (HOST_WAKE) is connected.
That's such a common property, individual bindings don't typically
mention it.
> + - interrupts : interrupt specifier encoded according the interrupt controller
> + specified by interrupt-parent property.
The description of the property should say which interrupt (name and/or
description) it's describing, even if there's only 1.
> +mmc3: mmc@01c20000 {
> + pinctrl-0 = <&mmc3_pins>;
> + pinctrl-1 = <&wifi_host_wake>;
> + vmmc-supply = <&mmc3_supply>;
> + bus-width = <4>;
None of that is really relevant to this binding, and may vary from SDIO
controller to SDIO controller, so may end up being wrong.
I'm not sure whether it makes sense to show the example inside some
arbitrary SDIO controller node. Perhaps /just/ put the WiFi node in the
example? The text above should be enough to describe that the node
should be inside an SDIO controller.
> + bcm4335: bcm4335@0 {
> + compatible = "brcm,bcm43xx-fmac";
> + wlan-supply = <&wlan-reg>;
> + drive-strength = <4>;
> + interrupt-parent = <&gpx2>;
> + interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
> + interrupt-names = "HOST_WAKE";
interrupt-names wasn't documented in the list of properties above.
Entries in *-names properties are usually lower-case.
^ permalink raw reply
* [PATCH v12] gpio: add a driver for the Synopsys DesignWare APB GPIO block
From: Alan Tull @ 2014-02-25 23:01 UTC (permalink / raw)
To: Linus Walleij
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-gpio-u79uwXL29TY76Z2rM5mHXA,
linux-doc-u79uwXL29TY76Z2rM5mHXA, Jamie Iles,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Rob Herring,
Grant Likely, Mark Rutland, Steffen Trumtrar,
Sebastian Hesselbarth, delicious quinoa, Heiko Stuebner,
Alan Tull, Dinh Nguyen, Yves Vandervennet
From: Jamie Iles <jamie-wmLquQDDieKakBO8gow8eQ@public.gmane.org>
The Synopsys DesignWare block is used in some ARM devices (picoxcell)
and can be configured to provide multiple banks of GPIO pins.
Signed-off-by: Jamie Iles <jamie-wmLquQDDieKakBO8gow8eQ@public.gmane.org>
Signed-off-by: Alan Tull <atull-EIB2kfCEclfQT0dZR+AlfA@public.gmane.org>
Reviewed-by: Sebastian Hesselbarth <sebastian.hesselbarth-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
v12: - Add irq_startup/shutdown
- do irq_create_mapping() in probe, irq_find_mapping() in to_irq()
- Adjust mappings to show support for 1 gpio per port.
- gpio-cells = <1>
v11: - Use NULL when checking existence of 'interrupts' property
- Bindings descriptions cleanup
v10: - in documentation nr-gpio -> nr-gpios
v9: - cleanup in dt bindings doc
- use of_get_child_count()
v8: - remove socfpga.dtsi changes
- minor cleanup in devicetree documentation
v7: - use irq_generic_chip
- support one irq per gpio line or one irq for many
- s/bank/port/ and other cleanup
v6: - (atull) squash the set of patches
- use linear irq domain
- build fixes. Original driver was reviewed on v3.2.
- Fix setting irq edge type for 'rising' and 'both'.
- Support as a loadable module.
- Use bgpio_chip's spinlock during register access.
- Clean up register names to match spec
- s/bank/port/ because register names use the word 'port'
- s/nr-gpio/nr-gpios/
- don't get/put the of_node
- remove signoffs/acked-by's because of changes
- other cleanup
v5: - handle sparse bank population correctly
v3: - depend on rather than select IRQ_DOMAIN
- split IRQ support into a separate patch
v2: - use Rob Herring's irqdomain in generic irq chip patches
- use reg property to indicate bank index
- support irqs on both edges based on LinusW's u300 driver
---
.../devicetree/bindings/gpio/snps-dwapb-gpio.txt | 57 +++
drivers/gpio/Kconfig | 9 +
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-dwapb.c | 438 ++++++++++++++++++++
4 files changed, 505 insertions(+)
create mode 100644 Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
create mode 100644 drivers/gpio/gpio-dwapb.c
diff --git a/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt b/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
new file mode 100644
index 0000000..0934950
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
@@ -0,0 +1,57 @@
+* Synopsys DesignWare APB GPIO controller
+
+Required properties:
+- compatible : Should contain "snps,dw-apb-gpio"
+- reg : Address and length of the register set for the device.
+- #address-cells : should be 1 (for addressing port subnodes).
+- #size-cells : should be 0 (port subnodes).
+
+The GPIO controller has a configurable number of ports, each of which are
+represented as child nodes with the following properties:
+
+Required properties:
+- compatible : "snps,dw-apb-gpio-port"
+- gpio-controller : Marks the device node as a gpio controller.
+- #gpio-cells : Should be 1. It is the pin number.
+- reg : The integer port index of the port, a single cell.
+
+Optional properties:
+- interrupt-controller : The first port may be configured to be an interrupt
+controller.
+- #interrupt-cells : Specifies the number of cells needed to encode an
+ interrupt. Shall be set to 2. The first cell defines the interrupt number,
+ the second encodes the triger flags encoded as described in
+ Documentation/devicetree/bindings/interrupts.txt
+- interrupt-parent : The parent interrupt controller.
+- interrupts : The interrupt to the parent controller raised when GPIOs
+ generate the interrupts.
+- snps,nr-gpios : The number of pins in the port, a single cell.
+
+Example:
+
+gpio: gpio@20000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x20000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ porta: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <1>;
+ snps,nr-gpios = <8>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&vic1>;
+ interrupts = <0>;
+ };
+
+ portb: gpio-controller@1 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <1>;
+ snps,nr-gpios = <8>;
+ reg = <1>;
+ };
+};
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 903f24d..9979017 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -128,6 +128,15 @@ config GPIO_GENERIC_PLATFORM
help
Say yes here to support basic platform_device memory-mapped GPIO controllers.
+config GPIO_DWAPB
+ tristate "Synopsys DesignWare APB GPIO driver"
+ select GPIO_GENERIC
+ select GENERIC_IRQ_CHIP
+ depends on OF_GPIO && IRQ_DOMAIN
+ help
+ Say Y or M here to build support for the Synopsys DesignWare APB
+ GPIO block.
+
config GPIO_IT8761E
tristate "IT8761E GPIO support"
depends on X86 # unconditional access to IO space.
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 5d50179..2d09f04 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o
obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o
obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o
obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o
+obj-$(CONFIG_GPIO_DWAPB) += gpio-dwapb.o
obj-$(CONFIG_GPIO_EM) += gpio-em.o
obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o
obj-$(CONFIG_GPIO_F7188X) += gpio-f7188x.o
diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c
new file mode 100644
index 0000000..2797fbb
--- /dev/null
+++ b/drivers/gpio/gpio-dwapb.c
@@ -0,0 +1,438 @@
+/*
+ * Copyright (c) 2011 Jamie Iles
+ *
+ * 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.
+ *
+ * All enquiries to support-QECmZ7LgVXZWk0Htik3J/w@public.gmane.org
+ */
+#include <linux/basic_mmio_gpio.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+
+#define GPIO_SWPORTA_DR 0x00
+#define GPIO_SWPORTA_DDR 0x04
+#define GPIO_SWPORTB_DR 0x0c
+#define GPIO_SWPORTB_DDR 0x10
+#define GPIO_SWPORTC_DR 0x18
+#define GPIO_SWPORTC_DDR 0x1c
+#define GPIO_SWPORTD_DR 0x24
+#define GPIO_SWPORTD_DDR 0x28
+#define GPIO_INTEN 0x30
+#define GPIO_INTMASK 0x34
+#define GPIO_INTTYPE_LEVEL 0x38
+#define GPIO_INT_POLARITY 0x3c
+#define GPIO_INTSTATUS 0x40
+#define GPIO_PORTA_EOI 0x4c
+#define GPIO_EXT_PORTA 0x50
+#define GPIO_EXT_PORTB 0x54
+#define GPIO_EXT_PORTC 0x58
+#define GPIO_EXT_PORTD 0x5c
+
+#define DWAPB_MAX_PORTS 4
+#define GPIO_EXT_PORT_SIZE (GPIO_EXT_PORTB - GPIO_EXT_PORTA)
+#define GPIO_SWPORT_DR_SIZE (GPIO_SWPORTB_DR - GPIO_SWPORTA_DR)
+#define GPIO_SWPORT_DDR_SIZE (GPIO_SWPORTB_DDR - GPIO_SWPORTA_DDR)
+
+struct dwapb_gpio;
+
+struct dwapb_gpio_port {
+ struct bgpio_chip bgc;
+ bool is_registered;
+ struct dwapb_gpio *gpio;
+};
+
+struct dwapb_gpio {
+ struct device *dev;
+ void __iomem *regs;
+ struct dwapb_gpio_port *ports;
+ unsigned int nr_ports;
+ struct irq_domain *domain;
+};
+
+static int dwapb_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
+{
+ struct bgpio_chip *bgc = to_bgpio_chip(gc);
+ struct dwapb_gpio_port *port = container_of(bgc, struct
+ dwapb_gpio_port, bgc);
+ struct dwapb_gpio *gpio = port->gpio;
+
+ return irq_find_mapping(gpio->domain, offset);
+}
+
+static void dwapb_toggle_trigger(struct dwapb_gpio *gpio, unsigned int offs)
+{
+ u32 v = readl(gpio->regs + GPIO_INT_POLARITY);
+
+ if (gpio_get_value(gpio->ports[0].bgc.gc.base + offs))
+ v &= ~BIT(offs);
+ else
+ v |= BIT(offs);
+
+ writel(v, gpio->regs + GPIO_INT_POLARITY);
+}
+
+static void dwapb_irq_handler(u32 irq, struct irq_desc *desc)
+{
+ struct dwapb_gpio *gpio = irq_get_handler_data(irq);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ u32 irq_status = readl_relaxed(gpio->regs + GPIO_INTSTATUS);
+
+ while (irq_status) {
+ int hwirq = fls(irq_status) - 1;
+ int gpio_irq = irq_find_mapping(gpio->domain, hwirq);
+
+ generic_handle_irq(gpio_irq);
+ irq_status &= ~BIT(hwirq);
+
+ if ((irq_get_trigger_type(gpio_irq) & IRQ_TYPE_SENSE_MASK)
+ == IRQ_TYPE_EDGE_BOTH)
+ dwapb_toggle_trigger(gpio, hwirq);
+ }
+
+ if (chip->irq_eoi)
+ chip->irq_eoi(irq_desc_get_irq_data(desc));
+}
+
+static void dwapb_irq_enable(struct irq_data *d)
+{
+ struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d);
+ struct dwapb_gpio *gpio = igc->private;
+ struct bgpio_chip *bgc = &gpio->ports[0].bgc;
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&bgc->lock, flags);
+ val = readl(gpio->regs + GPIO_INTEN);
+ val |= BIT(d->hwirq);
+ writel(val, gpio->regs + GPIO_INTEN);
+ spin_unlock_irqrestore(&bgc->lock, flags);
+}
+
+static void dwapb_irq_disable(struct irq_data *d)
+{
+ struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d);
+ struct dwapb_gpio *gpio = igc->private;
+ struct bgpio_chip *bgc = &gpio->ports[0].bgc;
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&bgc->lock, flags);
+ val = readl(gpio->regs + GPIO_INTEN);
+ val &= ~BIT(d->hwirq);
+ writel(val, gpio->regs + GPIO_INTEN);
+ spin_unlock_irqrestore(&bgc->lock, flags);
+}
+
+static unsigned int dwapb_irq_startup(struct irq_data *d)
+{
+ struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d);
+ struct dwapb_gpio *gpio = igc->private;
+ struct bgpio_chip *bgc = &gpio->ports[0].bgc;
+
+ if (gpio_lock_as_irq(&bgc->gc, irqd_to_hwirq(d)))
+ dev_err(gpio->dev, "unable to lock HW IRQ %lu for IRQ\n",
+ irqd_to_hwirq(d));
+ dwapb_irq_enable(d);
+ return 0;
+}
+
+static void dwapb_irq_shutdown(struct irq_data *d)
+{
+ struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d);
+ struct dwapb_gpio *gpio = igc->private;
+ struct bgpio_chip *bgc = &gpio->ports[0].bgc;
+
+ dwapb_irq_disable(d);
+ gpio_unlock_as_irq(&bgc->gc, irqd_to_hwirq(d));
+}
+
+static int dwapb_irq_set_type(struct irq_data *d, u32 type)
+{
+ struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d);
+ struct dwapb_gpio *gpio = igc->private;
+ struct bgpio_chip *bgc = &gpio->ports[0].bgc;
+ int bit = d->hwirq;
+ unsigned long level, polarity, flags;
+
+ if (type & ~(IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
+ IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
+ return -EINVAL;
+
+ spin_lock_irqsave(&bgc->lock, flags);
+ level = readl(gpio->regs + GPIO_INTTYPE_LEVEL);
+ polarity = readl(gpio->regs + GPIO_INT_POLARITY);
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_BOTH:
+ level |= BIT(bit);
+ dwapb_toggle_trigger(gpio, bit);
+ break;
+ case IRQ_TYPE_EDGE_RISING:
+ level |= BIT(bit);
+ polarity |= BIT(bit);
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ level |= BIT(bit);
+ polarity &= ~BIT(bit);
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ level &= ~BIT(bit);
+ polarity |= BIT(bit);
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ level &= ~BIT(bit);
+ polarity &= ~BIT(bit);
+ break;
+ }
+
+ writel(level, gpio->regs + GPIO_INTTYPE_LEVEL);
+ writel(polarity, gpio->regs + GPIO_INT_POLARITY);
+ spin_unlock_irqrestore(&bgc->lock, flags);
+
+ return 0;
+}
+
+static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
+ struct dwapb_gpio_port *port)
+{
+ struct gpio_chip *gc = &port->bgc.gc;
+ struct device_node *node = gc->of_node;
+ struct irq_chip_generic *irq_gc;
+ unsigned int hwirq, ngpio = gc->ngpio;
+ struct irq_chip_type *ct;
+ int err, irq;
+
+ irq = irq_of_parse_and_map(node, 0);
+ if (!irq) {
+ dev_warn(gpio->dev, "no irq for bank %s\n",
+ port->bgc.gc.of_node->full_name);
+ return;
+ }
+
+ gpio->domain = irq_domain_add_linear(node, ngpio,
+ &irq_generic_chip_ops, gpio);
+ if (!gpio->domain)
+ return;
+
+ err = irq_alloc_domain_generic_chips(gpio->domain, ngpio, 1,
+ "gpio-dwapb", handle_level_irq,
+ IRQ_NOREQUEST, 0,
+ IRQ_GC_INIT_NESTED_LOCK);
+ if (err) {
+ dev_info(gpio->dev, "irq_alloc_domain_generic_chips failed\n");
+ irq_domain_remove(gpio->domain);
+ gpio->domain = NULL;
+ return;
+ }
+
+ irq_gc = irq_get_domain_generic_chip(gpio->domain, 0);
+ if (!irq_gc) {
+ irq_domain_remove(gpio->domain);
+ gpio->domain = NULL;
+ return;
+ }
+
+ irq_gc->reg_base = gpio->regs;
+ irq_gc->private = gpio;
+
+ ct = irq_gc->chip_types;
+ ct->chip.irq_ack = irq_gc_ack_set_bit;
+ ct->chip.irq_mask = irq_gc_mask_set_bit;
+ ct->chip.irq_unmask = irq_gc_mask_clr_bit;
+ ct->chip.irq_set_type = dwapb_irq_set_type;
+ ct->chip.irq_enable = dwapb_irq_enable;
+ ct->chip.irq_disable = dwapb_irq_disable;
+ ct->chip.irq_startup = dwapb_irq_startup;
+ ct->chip.irq_shutdown = dwapb_irq_shutdown;
+ ct->regs.ack = GPIO_PORTA_EOI;
+ ct->regs.mask = GPIO_INTMASK;
+
+ irq_setup_generic_chip(irq_gc, IRQ_MSK(port->bgc.gc.ngpio),
+ IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0);
+
+ irq_set_chained_handler(irq, dwapb_irq_handler);
+ irq_set_handler_data(irq, gpio);
+
+ for (hwirq = 0 ; hwirq < ngpio ; hwirq++)
+ irq_create_mapping(gpio->domain, hwirq);
+
+ port->bgc.gc.to_irq = dwapb_gpio_to_irq;
+}
+
+static void dwapb_irq_teardown(struct dwapb_gpio *gpio)
+{
+ struct dwapb_gpio_port *port = &gpio->ports[0];
+ struct gpio_chip *gc = &port->bgc.gc;
+ unsigned int ngpio = gc->ngpio;
+ irq_hw_number_t hwirq;
+
+ if (!gpio->domain)
+ return;
+
+ for (hwirq = 0 ; hwirq < ngpio ; hwirq++)
+ irq_dispose_mapping(irq_find_mapping(gpio->domain, hwirq));
+
+ irq_domain_remove(gpio->domain);
+ gpio->domain = NULL;
+}
+
+static int dwapb_gpio_add_port(struct dwapb_gpio *gpio,
+ struct device_node *port_np,
+ unsigned int offs)
+{
+ struct dwapb_gpio_port *port;
+ u32 port_idx, ngpio;
+ void __iomem *dat, *set, *dirout;
+ int err;
+
+ if (of_property_read_u32(port_np, "reg", &port_idx) ||
+ port_idx >= DWAPB_MAX_PORTS) {
+ dev_err(gpio->dev, "missing/invalid port index for %s\n",
+ port_np->full_name);
+ return -EINVAL;
+ }
+
+ port = &gpio->ports[offs];
+ port->gpio = gpio;
+
+ if (of_property_read_u32(port_np, "snps,nr-gpios", &ngpio)) {
+ dev_info(gpio->dev, "failed to get number of gpios for %s\n",
+ port_np->full_name);
+ ngpio = 32;
+ }
+
+ dat = gpio->regs + GPIO_EXT_PORTA + (port_idx * GPIO_EXT_PORT_SIZE);
+ set = gpio->regs + GPIO_SWPORTA_DR + (port_idx * GPIO_SWPORT_DR_SIZE);
+ dirout = gpio->regs + GPIO_SWPORTA_DDR +
+ (port_idx * GPIO_SWPORT_DDR_SIZE);
+
+ err = bgpio_init(&port->bgc, gpio->dev, 4, dat, set, NULL, dirout,
+ NULL, false);
+ if (err) {
+ dev_err(gpio->dev, "failed to init gpio chip for %s\n",
+ port_np->full_name);
+ return err;
+ }
+
+ port->bgc.gc.ngpio = ngpio;
+ port->bgc.gc.of_node = port_np;
+
+ /*
+ * Only port A can provide interrupts in all configurations of the IP.
+ */
+ if (port_idx == 0 &&
+ of_property_read_bool(port_np, "interrupt-controller"))
+ dwapb_configure_irqs(gpio, port);
+
+ err = gpiochip_add(&port->bgc.gc);
+ if (err)
+ dev_err(gpio->dev, "failed to register gpiochip for %s\n",
+ port_np->full_name);
+ else
+ port->is_registered = true;
+
+ return err;
+}
+
+static void dwapb_gpio_unregister(struct dwapb_gpio *gpio)
+{
+ unsigned int m;
+
+ for (m = 0; m < gpio->nr_ports; ++m)
+ if (gpio->ports[m].is_registered)
+ WARN_ON(gpiochip_remove(&gpio->ports[m].bgc.gc));
+}
+
+static int dwapb_gpio_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct dwapb_gpio *gpio;
+ struct device_node *np;
+ int err;
+ unsigned int offs = 0;
+
+ gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
+ if (!gpio)
+ return -ENOMEM;
+ gpio->dev = &pdev->dev;
+
+ gpio->nr_ports = of_get_child_count(pdev->dev.of_node);
+ if (!gpio->nr_ports) {
+ err = -EINVAL;
+ goto out_err;
+ }
+ gpio->ports = devm_kzalloc(&pdev->dev, gpio->nr_ports *
+ sizeof(*gpio->ports), GFP_KERNEL);
+ if (!gpio->ports) {
+ err = -ENOMEM;
+ goto out_err;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ gpio->regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(gpio->regs)) {
+ err = PTR_ERR(gpio->regs);
+ goto out_err;
+ }
+
+ for_each_child_of_node(pdev->dev.of_node, np) {
+ err = dwapb_gpio_add_port(gpio, np, offs++);
+ if (err)
+ goto out_unregister;
+ }
+ platform_set_drvdata(pdev, gpio);
+
+ return 0;
+
+out_unregister:
+ dwapb_gpio_unregister(gpio);
+ dwapb_irq_teardown(gpio);
+
+out_err:
+ return err;
+}
+
+static int dwapb_gpio_remove(struct platform_device *pdev)
+{
+ struct dwapb_gpio *gpio = platform_get_drvdata(pdev);
+
+ dwapb_gpio_unregister(gpio);
+ dwapb_irq_teardown(gpio);
+
+ return 0;
+}
+
+static const struct of_device_id dwapb_of_match[] = {
+ { .compatible = "snps,dw-apb-gpio" },
+ { /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dwapb_of_match);
+
+static struct platform_driver dwapb_gpio_driver = {
+ .driver = {
+ .name = "gpio-dwapb",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(dwapb_of_match),
+ },
+ .probe = dwapb_gpio_probe,
+ .remove = dwapb_gpio_remove,
+};
+
+module_platform_driver(dwapb_gpio_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jamie Iles");
+MODULE_DESCRIPTION("Synopsys DesignWare APB GPIO driver");
--
1.7.9.5
--
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: [PATCHv2 03/16] Documentation: dt: add OMAP iommu bindings
From: Suman Anna @ 2014-02-25 23:02 UTC (permalink / raw)
To: Laurent Pinchart
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Tony Lindgren,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-omap-u79uwXL29TY76Z2rM5mHXA, Florian Vaussard
In-Reply-To: <13151454.2tbkC7YZsi@avalon>
Hi Laurent,
On 02/25/2014 03:26 PM, Laurent Pinchart wrote:
> Hi Suman,
>
> Thank you for the patch.
>
> On Thursday 13 February 2014 12:15:34 Suman Anna wrote:
>> From: Florian Vaussard <florian.vaussard-p8DiymsW2f8@public.gmane.org>
>>
>> This patch adds the iommu bindings for all OMAP2+ SoCs. Apart from
>> the standard bindings used by OMAP peripherals, this patch uses a
>> 'dma-window' (already used by Tegra SMMU) and adds two OMAP custom
>> bindings - 'ti,#tlb-entries' and 'ti,iommu-bus-err-back'.
>>
>> Signed-off-by: Florian Vaussard <florian.vaussard-p8DiymsW2f8@public.gmane.org>
>> [s-anna-l0cyMroinI0@public.gmane.org: split bindings document, add dra7 and bus error back]
>> Signed-off-by: Suman Anna <s-anna-l0cyMroinI0@public.gmane.org>
>> ---
>> .../devicetree/bindings/iommu/ti,omap-iommu.txt | 28 +++++++++++++++++++
>> 1 file changed, 28 insertions(+)
>> create mode 100644
>> Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt
>>
>> diff --git a/Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt
>> b/Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt new file mode
>> 100644
>> index 0000000..116492d
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt
>> @@ -0,0 +1,28 @@
>> +OMAP2+ IOMMU
>> +
>> +Required properties:
>> +- compatible : Should be one of,
>> + "ti,omap2-iommu" for OMAP2/OMAP3 IOMMU instances
>> + "ti,omap4-iommu" for OMAP4/OMAP5 IOMMU instances
>> + "ti,dra7-iommu" for DRA7xx IOMMU instances
>> +- ti,hwmods : Name of the hwmod associated with the IOMMU instance
>> +- reg : Address space for the configuration registers
>> +- interrupts : Interrupt specifier for the IOMMU instance
>> +- dma-window : IOVA start address and length
>
> Isn't the dma window more of a system configuration property than a hardware
> property ? How do you expect it to be set?
We are setting it based on the addressable range for the MMU. We are
reusing the existing defined property and it allows us to get rid of the
IOVA start and end addresses defined in the pre-DT OMAP iommu platform data.
>
>> +Optional properties:
>> +- ti,#tlb-entries : Number of entries in the translation look-aside buffer.
>> + Should be either 8 or 32 (default: 32)
>> +- ti,iommu-bus-err-back : Indicates the IOMMU instance supports throwing
>> + back a bus error response on MMU faults.
>
> Do these features vary per IOMMU instance or per IOMMU model ? In the latter
> case they could be inferred from the compatible string by the driver without
> requiring them to be explicit in DT (whether you want to do so is left to you
> though).
Well, these are fixed features given an IOMMU instance, like the OMAP3
ISP is the only one that has 8 TLB entries, all the remaining ones have
32, and the IPU iommu instances are the only ones that support the bus
error response back. I have no preference to any particular way, and
sure the driver can infer these easily based on unique compatible
strings per subsystem per SoC. I just happened to go with defining
compatible strings per SoC, with the optional properties differentiating
the fixed behavior between different IOMMU instances on that SoC. This
is where I was looking for some inputs/guidance from the DT bindings
maintainers on what is the preferred method.
regards
Suman
>
>> +Example:
>> + /* OMAP3 ISP MMU */
>> + mmu_isp: mmu@480bd400 {
>> + compatible = "ti,omap2-iommu";
>> + reg = <0x480bd400 0x80>;
>> + interrupts = <24>;
>> + ti,hwmods = "mmu_isp";
>> + ti,#tlb-entries = <8>;
>> + dma-window = <0 0xfffff000>;
>> + };
>
^ permalink raw reply
* Re: [PATCH 00/10] pinctrl: mvebu: remove hard-coded addresses from Dove pinctrl
From: Jason Cooper @ 2014-02-26 0:09 UTC (permalink / raw)
To: Linus Walleij
Cc: Mark Rutland, Andrew Lunn, Russell King, Pawel Moll, Ian Campbell,
linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Rob Herring,
Rob Landley, Kumar Gala, Gregory Clement,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
Sebastian Hesselbarth
In-Reply-To: <CACRpkdZ+YGTyDj6i8c198MdRtz3GY-YBmVO9LysPCcmT4EC0cg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Linus,
On Tue, Feb 25, 2014 at 10:36:54AM +0100, Linus Walleij wrote:
> On Mon, Feb 24, 2014 at 7:10 PM, Jason Cooper <jason-NLaQJdtUoK4Be96aLqz0jA@public.gmane.org> wrote:
>
> > Sebastian, Linus,
> >
> > I've now created mvebu/pinctrl-dove for this series. It's based on
> > v3.14-rc1, and depends on mvebu/pinctrl (which depends on
> > mvebu/pinctrl-3xx).
> >
> > I've kept this series in a separate branch in case we encounter an
> > unforeseen problem with something in here. Then this branch can be
> > dropped, and /pinctrl-3xx and /pinctrl will still make it in.
> >
> > So, all patches except 3 and 4 are in mvebu/pinctrl-dove. 3 and 4 are
> > in mvebu/dt.
>
> OK so what should I be pulling in first now?
Sebastian has now re-organized the branches as I asked, and I confirmed
that the final result is the exact same as mine (diff is null).
Usually when I submit pull requests to arm-soc, they like to see the
branches. That way if there is an error in one of them, they just drop
the one branch and the others remain.
Would you like them the same way? If so, I'll send the pulls to you
tomorrow. Otherwise, I'll wait a few more days to let things shake out
and then send you one request with the branches merged.
thx,
Jason.
--
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 v2 00/12] clk: bcm281xx: updates for 3.15
From: Alex Elder @ 2014-02-26 0:15 UTC (permalink / raw)
To: mturquette-QSEj5FYQhm4dnm+yROfE0A, mporter-QSEj5FYQhm4dnm+yROfE0A,
bcm-xK7y4jjYLqYh9ZMKESR00Q, galak-sgV2jX0FEOL9JmXXK+q4OQ,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg, mark.rutland-5wv7dgnIgG8,
pawel.moll-5wv7dgnIgG8, robh+dt-DgEjT+Ai2ygdnm+yROfE0A
Cc: bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
This series includes updates for the bcm281xx clock code for 3.15.
I had held off posting this until the code on which this is based
was queued for 3.14, and it now has been:
https://github.com/broadcom/mach-bcm/
Branch armsoc/for-3.15/drivers
clk: bcm281xx: don't disable unused peripheral clocks
clk: bcm281xx: add initial clock framework support
followed by:
(same repository)
Branch armsoc/for-3.15/dt
ARM: dts: bcm281xx: define real clocks
The patches in this series are available here:
http://git.linaro.org/landing-teams/working/broadcom/kernel.git
Branch review/bcm-clk-next-v2
I've grouped them, and offer a little explanation of each of the
groups below.
Note: The final (DT) patch *must* be committed last.
The first version of this series had a patch from the middle of the
series that shouldn't have been there, and it has been removed in
this version (that patch affected mach-bcm, not clk). I also split
the final patch into two, with the second one isolating the change
to a device tree file.
-Alex
Alex Elder (12):
clk: bcm281xx: warn if ccu_wait_bit() fails
clk: bcm281xx: use init_data.name for clock name
clk: bcm281xx: change some symbol names
Three small code improvements.
clk: bcm281xx: initialize CCU structures statically
clk: bcm281xx: define CCU clock data statically
Rearrange the way CCUs and the clocks they provide are
defined, so that they're defined statically to the extent
possible rather than allocating and initializing things at
runtime.
clk: bcm281xx: add clock policy support
clk: bcm281xx: add clock hysteresis support
clk: bcm281xx: add an initialized flag
clk: bcm281xx: implement prerequisite clocks
clk: bcm281xx: add bus clock support
clk: bcm281xx: define a bus clock
Add a few new features, ultimately for the purpose of adding
support for another type of Kona clock. Currently only
peripheral clocks are supported; this adds the ability to
define and control bus clocks. In addition, support is
added for clocks to identify a prerequisite clock; a clock
won't be initialized until after its prerequisite has been.
ARM: dts: add bus clock bsc3_apb for bcm281xx
Add the new bus clock to the device tree.
arch/arm/boot/dts/bcm11351.dtsi | 3 +-
drivers/clk/bcm/clk-bcm281xx.c | 254 ++++++++++++--------------
drivers/clk/bcm/clk-kona-setup.c | 331 +++++++++++++++++++++++++++-------
drivers/clk/bcm/clk-kona.c | 331 ++++++++++++++++++++++++++++++++--
drivers/clk/bcm/clk-kona.h | 189 ++++++++++++++++---
include/dt-bindings/clock/bcm281xx.h | 3 +-
6 files changed, 872 insertions(+), 239 deletions(-)
--
1.7.9.5
--
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 v2 01/12] clk: bcm281xx: warn if ccu_wait_bit() fails
From: Alex Elder @ 2014-02-26 0:15 UTC (permalink / raw)
To: mturquette, mporter, bcm, galak, ijc+devicetree, mark.rutland,
pawel.moll, robh+dt
Cc: devicetree, bcm-kernel-feedback-list, linux-kernel,
linux-arm-kernel
In-Reply-To: <1393373752-30875-1-git-send-email-elder@linaro.org>
Don't let a failure of ccu_wait_bit() go unnoticed.
Signed-off-by: Alex Elder <elder@linaro.org>
---
drivers/clk/bcm/clk-kona.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/clk/bcm/clk-kona.c b/drivers/clk/bcm/clk-kona.c
index e3d339e..c01d810 100644
--- a/drivers/clk/bcm/clk-kona.c
+++ b/drivers/clk/bcm/clk-kona.c
@@ -207,6 +207,9 @@ __ccu_wait_bit(struct ccu_data *ccu, u32 reg_offset, u32 bit, bool want)
return true;
udelay(1);
}
+ pr_warn("%s: %s/0x%04x bit %u was never %s\n", __func__,
+ ccu->name, reg_offset, bit, want ? "set" : "clear");
+
return false;
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 02/12] clk: bcm281xx: use init_data.name for clock name
From: Alex Elder @ 2014-02-26 0:15 UTC (permalink / raw)
To: mturquette, mporter, bcm, galak, ijc+devicetree, mark.rutland,
pawel.moll, robh+dt
Cc: bcm-kernel-feedback-list, linux-arm-kernel, devicetree,
linux-kernel
In-Reply-To: <1393373752-30875-1-git-send-email-elder@linaro.org>
Use the init_data.name field to hold the name of a Kona clock rather
than duplicating it.
Signed-off-by: Alex Elder <elder@linaro.org>
---
drivers/clk/bcm/clk-kona-setup.c | 6 +++---
drivers/clk/bcm/clk-kona.c | 17 ++++++++++-------
drivers/clk/bcm/clk-kona.h | 3 +--
3 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/drivers/clk/bcm/clk-kona-setup.c b/drivers/clk/bcm/clk-kona-setup.c
index c7607fe..eed84f5 100644
--- a/drivers/clk/bcm/clk-kona-setup.c
+++ b/drivers/clk/bcm/clk-kona-setup.c
@@ -64,7 +64,7 @@ static bool peri_clk_data_offsets_valid(struct kona_clk *bcm_clk)
BUG_ON(bcm_clk->type != bcm_clk_peri);
peri = bcm_clk->peri;
- name = bcm_clk->name;
+ name = bcm_clk->init_data.name;
range = bcm_clk->ccu->range;
limit = range - sizeof(u32);
@@ -329,7 +329,7 @@ peri_clk_data_valid(struct kona_clk *bcm_clk)
return false;
peri = bcm_clk->peri;
- name = bcm_clk->name;
+ name = bcm_clk->init_data.name;
gate = &peri->gate;
if (gate_exists(gate) && !gate_valid(gate, "gate", name))
return false;
@@ -630,7 +630,7 @@ struct clk *kona_clk_setup(struct ccu_data *ccu, const char *name,
return NULL;
}
bcm_clk->ccu = ccu;
- bcm_clk->name = name;
+ bcm_clk->init_data.name = name;
init_data = &bcm_clk->init_data;
init_data->name = name;
diff --git a/drivers/clk/bcm/clk-kona.c b/drivers/clk/bcm/clk-kona.c
index c01d810..488ed1f 100644
--- a/drivers/clk/bcm/clk-kona.c
+++ b/drivers/clk/bcm/clk-kona.c
@@ -807,7 +807,7 @@ static int kona_peri_clk_enable(struct clk_hw *hw)
struct kona_clk *bcm_clk = to_kona_clk(hw);
struct bcm_clk_gate *gate = &bcm_clk->peri->gate;
- return clk_gate(bcm_clk->ccu, bcm_clk->name, gate, true);
+ return clk_gate(bcm_clk->ccu, bcm_clk->init_data.name, gate, true);
}
static void kona_peri_clk_disable(struct clk_hw *hw)
@@ -815,7 +815,7 @@ static void kona_peri_clk_disable(struct clk_hw *hw)
struct kona_clk *bcm_clk = to_kona_clk(hw);
struct bcm_clk_gate *gate = &bcm_clk->peri->gate;
- (void)clk_gate(bcm_clk->ccu, bcm_clk->name, gate, false);
+ (void)clk_gate(bcm_clk->ccu, bcm_clk->init_data.name, gate, false);
}
static int kona_peri_clk_is_enabled(struct clk_hw *hw)
@@ -873,12 +873,13 @@ static int kona_peri_clk_set_parent(struct clk_hw *hw, u8 index)
ret = selector_write(bcm_clk->ccu, &data->gate, sel, trig, index);
if (ret == -ENXIO) {
- pr_err("%s: gating failure for %s\n", __func__, bcm_clk->name);
+ pr_err("%s: gating failure for %s\n", __func__,
+ bcm_clk->init_data.name);
ret = -EIO; /* Don't proliferate weird errors */
} else if (ret == -EIO) {
pr_err("%s: %strigger failed for %s\n", __func__,
trig == &data->pre_trig ? "pre-" : "",
- bcm_clk->name);
+ bcm_clk->init_data.name);
}
return ret;
@@ -937,10 +938,12 @@ static int kona_peri_clk_set_rate(struct clk_hw *hw, unsigned long rate,
ret = divider_write(bcm_clk->ccu, &data->gate, &data->div,
&data->trig, scaled_div);
if (ret == -ENXIO) {
- pr_err("%s: gating failure for %s\n", __func__, bcm_clk->name);
+ pr_err("%s: gating failure for %s\n", __func__,
+ bcm_clk->init_data.name);
ret = -EIO; /* Don't proliferate weird errors */
} else if (ret == -EIO) {
- pr_err("%s: trigger failed for %s\n", __func__, bcm_clk->name);
+ pr_err("%s: trigger failed for %s\n", __func__,
+ bcm_clk->init_data.name);
}
return ret;
@@ -962,7 +965,7 @@ static bool __peri_clk_init(struct kona_clk *bcm_clk)
{
struct ccu_data *ccu = bcm_clk->ccu;
struct peri_clk_data *peri = bcm_clk->peri;
- const char *name = bcm_clk->name;
+ const char *name = bcm_clk->init_data.name;
struct bcm_clk_trig *trig;
BUG_ON(bcm_clk->type != bcm_clk_peri);
diff --git a/drivers/clk/bcm/clk-kona.h b/drivers/clk/bcm/clk-kona.h
index 5e139ad..96fd0bc 100644
--- a/drivers/clk/bcm/clk-kona.h
+++ b/drivers/clk/bcm/clk-kona.h
@@ -373,8 +373,7 @@ struct peri_clk_data {
struct kona_clk {
struct clk_hw hw;
- struct clk_init_data init_data;
- const char *name; /* name of this clock */
+ struct clk_init_data init_data; /* includes name of this clock */
struct ccu_data *ccu; /* ccu this clock is associated with */
enum bcm_clk_type type;
union {
--
1.7.9.5
^ 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