* [PATCH] ARM: imx: stop adjusting ar8031 phy tx delay
From: André Draszik @ 2019-08-09 3:12 UTC (permalink / raw)
To: linux-kernel
Cc: Kate Stewart, André Draszik, Sascha Hauer, Russell King,
NXP Linux Team, Pengutronix Kernel Team, Greg Kroah-Hartman,
Shawn Guo, Thomas Gleixner, Leonard Crestez, Fabio Estevam,
linux-arm-kernel
Recent changes to the Atheros at803x driver cause
the approach taken here to stop working because
commit 6d4cd041f0af
("net: phy: at803x: disable delay only for RGMII mode")
and commit cd28d1d6e52e
("net: phy: at803x: Disable phy delay for RGMII mode")
fix the AR8031 driver to configure the phy's (RX/TX)
delays as per the 'phy-mode' in the device tree.
In particular, the phy tx (and rx) delays are updated
again as per the 'phy-mode' *after* the code in here
runs.
Things worked before above commits, because the AR8031
comes out of reset with RX delay enabled, and the
at803x driver didn't touch the delay configuration at
all when "rgmii" mode was selected.
It appears the code in here tries to make device
trees work that incorrectly specify "rgmii", but
that can't work any more and it is imperative since
above commits to have the phy-mode configured
correctly in the device tree.
I suspect there are a few imx7d based boards using
the ar8031 phy and phy-mode = "rgmii", but given I
don't know which ones exactly, I am not in a
position to update the respective device trees.
Hence this patch is simply removing the superfluous
code from the imx7d initialisation. An alternative
could be to add a warning instead, but that would
penalize all boards that have been updated already.
Signed-off-by: André Draszik <git@andred.net>
CC: Russell King <linux@armlinux.org.uk>
CC: Shawn Guo <shawnguo@kernel.org>
CC: Sascha Hauer <s.hauer@pengutronix.de>
CC: Pengutronix Kernel Team <kernel@pengutronix.de>
CC: Fabio Estevam <festevam@gmail.com>
CC: NXP Linux Team <linux-imx@nxp.com>
CC: Kate Stewart <kstewart@linuxfoundation.org>
CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
CC: Thomas Gleixner <tglx@linutronix.de>
CC: Leonard Crestez <leonard.crestez@nxp.com>
CC: linux-arm-kernel@lists.infradead.org
---
arch/arm/mach-imx/mach-imx7d.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/arch/arm/mach-imx/mach-imx7d.c b/arch/arm/mach-imx/mach-imx7d.c
index 95713450591a..ebb27592a9f7 100644
--- a/arch/arm/mach-imx/mach-imx7d.c
+++ b/arch/arm/mach-imx/mach-imx7d.c
@@ -30,12 +30,6 @@ static int ar8031_phy_fixup(struct phy_device *dev)
val &= ~(0x1 << 8);
phy_write(dev, 0xe, val);
- /* introduce tx clock delay */
- phy_write(dev, 0x1d, 0x5);
- val = phy_read(dev, 0x1e);
- val |= 0x0100;
- phy_write(dev, 0x1e, val);
-
return 0;
}
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH] ARM: dts: imx7d: cl-som-imx7: make ethernet work again
From: André Draszik @ 2019-08-09 3:12 UTC (permalink / raw)
To: linux-kernel
Cc: Mark Rutland, devicetree, Fabio Estevam, linux-arm-kernel,
André Draszik, Sascha Hauer, Rob Herring, Igor Grinberg,
Pengutronix Kernel Team, Shawn Guo, Ilya Ledvich, NXP Linux Team
Recent changes to the atheros at803x driver caused
ethernet to stop working on this board.
In particular commit 6d4cd041f0af
("net: phy: at803x: disable delay only for RGMII mode")
and commit cd28d1d6e52e
("net: phy: at803x: Disable phy delay for RGMII mode")
fix the AR8031 driver to configure the phy's (RX/TX)
delays as per the 'phy-mode' in the device tree.
This now prevents ethernet from working on this board.
It used to work before those commits, because the
AR8031 comes out of reset with RX delay enabled, and
the at803x driver didn't touch the delay configuration
at all when "rgmii" mode was selected, and because
arch/arm/mach-imx/mach-imx7d.c:ar8031_phy_fixup()
unconditionally enables TX delay.
Since above commits ar8031_phy_fixup() also has no
effect anymore, and the end-result is that all delays
are disabled in the phy, no ethernet.
Update the device tree to restore functionality.
Signed-off-by: André Draszik <git@andred.net>
CC: Ilya Ledvich <ilya@compulab.co.il>
CC: Igor Grinberg <grinberg@compulab.co.il>
CC: Rob Herring <robh+dt@kernel.org>
CC: Mark Rutland <mark.rutland@arm.com>
CC: Shawn Guo <shawnguo@kernel.org>
CC: Sascha Hauer <s.hauer@pengutronix.de>
CC: Pengutronix Kernel Team <kernel@pengutronix.de>
CC: Fabio Estevam <festevam@gmail.com>
CC: NXP Linux Team <linux-imx@nxp.com>
CC: devicetree@vger.kernel.org
CC: linux-arm-kernel@lists.infradead.org
---
arch/arm/boot/dts/imx7d-cl-som-imx7.dts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/imx7d-cl-som-imx7.dts b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
index e61567437d73..62d5e9a4a781 100644
--- a/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
+++ b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
@@ -44,7 +44,7 @@
<&clks IMX7D_ENET1_TIME_ROOT_CLK>;
assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
assigned-clock-rates = <0>, <100000000>;
- phy-mode = "rgmii";
+ phy-mode = "rgmii-id";
phy-handle = <ðphy0>;
fsl,magic-packet;
status = "okay";
@@ -70,7 +70,7 @@
<&clks IMX7D_ENET2_TIME_ROOT_CLK>;
assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
assigned-clock-rates = <0>, <100000000>;
- phy-mode = "rgmii";
+ phy-mode = "rgmii-id";
phy-handle = <ðphy1>;
fsl,magic-packet;
status = "okay";
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH 1/2 v2] tracing/arm64: Have max stack tracer handle the case of return address after data
From: Steven Rostedt @ 2019-08-09 2:24 UTC (permalink / raw)
To: Jiping Ma
Cc: catalin.marinas, will.deacon, linux-kernel, mingo, Joel Fernandes,
Will Deacon, linux-arm-kernel
In-Reply-To: <21530ce5-3847-c669-2a64-7c59ffb45f35@windriver.com>
On Fri, 9 Aug 2019 10:17:19 +0800
Jiping Ma <Jiping.Ma2@windriver.com> wrote:
> On 2019年08月09日 01:24, Steven Rostedt wrote:
> > On Thu, 8 Aug 2019 18:11:53 +0100
> > Will Deacon <will@kernel.org> wrote:
> >
> >>> We could make it more descriptive of what it will do and not the reason
> >>> for why it is done...
> >>>
> >>>
> >>> ARCH_FTRACE_SHIFT_STACK_TRACER
> >> Acked-by: Will Deacon <will@kernel.org>
> > Thanks Will!
> >
> > Here's the official patch.
> >
> > From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
> >
> > Most archs (well at least x86) store the function call return address on the
> > stack before storing the local variables for the function. The max stack
> > tracer depends on this in its algorithm to display the stack size of each
> > function it finds in the back trace.
> >
> > Some archs (arm64), may store the return address (from its link register)
> > just before calling a nested function. There's no reason to save the link
> > register on leaf functions, as it wont be updated. This breaks the algorithm
> > of the max stack tracer.
> >
> > Add a new define ARCH_RET_ADDR_AFTER_LOCAL_VARS that an architecture may set
>
> ARCH_FTRACE_SHIFT_STACK_TRACER is used in the code.
Ah, I did a s/x/y/ to the diff of the patch, but not the change log.
Thanks for pointing that out. I also need to update the comment in 2/2.
-- Steve
>
> Jiping
>
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFC PATCH 09/11] devfreq: exynos-bus: Add interconnect functionality to exynos-bus
From: Chanwoo Choi @ 2019-08-09 2:17 UTC (permalink / raw)
To: Artur Świgoń, devicetree, linux-arm-kernel,
linux-samsung-soc, linux-kernel, linux-pm, dri-devel
Cc: sw0312.kim, krzk, inki.dae, myungjoo.ham, georgi.djakov,
m.szyprowski
In-Reply-To: <7171e3c56b0dca8a81058e77dd76bd1e684e7778.camel@partner.samsung.com>
Hi,
We need to discuss how to change or do refactoring on v2.
Actually, I don't know the your opinion and how to do it on v2.
You have to reply the answer and then after finished the discussion,
I recommend that you would rework and resend the v2 patches.
On 19. 8. 8. 오후 10:18, Artur Świgoń wrote:
> Hi,
>
> Thank you for your remarks. I will take them into account while preparing RFCv2.
>
> On Mon, 2019-07-29 at 10:52 +0900, Chanwoo Choi wrote:
>> Hi,
>>
>> On 19. 7. 23. 오후 9:20, Artur Świgoń wrote:
>>> This patch adds interconnect functionality to the exynos-bus devfreq
>>> driver.
>>>
>>> The SoC topology is a graph (or, more specifically, a tree) and most of its
>>> edges are taken from the devfreq parent-child hierarchy (cf.
>>> Documentation/devicetree/bindings/devfreq/exynos-bus.txt). The previous
>>> patch adds missing edges to the DT (under the name 'parent'). Due to
>>> unspecified relative probing order, -EPROBE_DEFER may be propagated to
>>> guarantee that a child is probed before its parent.
>>>
>>> Each bus is now an interconnect provider and an interconnect node as well
>>> (cf. Documentation/interconnect/interconnect.rst), i.e. every bus registers
>>> itself as a node. Node IDs are not hardcoded but rather assigned at
>>> runtime, in probing order (subject to the above-mentioned exception
>>> regarding relative order). This approach allows for using this driver with
>>> various Exynos SoCs.
>>>
>>> The devfreq target() callback provided by exynos-bus now selects either the
>>> frequency calculated by the devfreq governor or the frequency requested via
>>> the interconnect API for the given node, whichever is higher.
>>
>> Basically, I agree to support the QoS requirement between devices.
>> But, I think that need to consider the multiple cases.
>>
>>
>> 1. When changing the devfreq governor by user,
>> For example of the connection between bus_dmc/leftbus/display on patch8,
>> there are possible multiple cases with various devfreq governor
>> which is changed on the runtime by user through sysfs interface.
>>
>> If users changes the devfreq governor as following:
>> Before,
>> - bus_dmc (simple_ondemand, available frequency 100/200/300/400 MHz)
>> --> bus_leftbus(simple_ondemand, available frequency 100/200/300/400 MHz)
>> ----> bus_display(passive)
>>
>> After changed governor of bus_dmc,
>> if the min_freq by interconnect requirement is 400Mhz,
>> - bus_dmc (powersave) : min_freq and max_freq and cur_freq is 100MHz
>> --> bus_leftbus(simple_ondemand) : cur_freq is 400Mhz
>> ----> bus_display(passive)
>>
>> The final frequency is 400MHz of bus_dmc
>> even if the min_freq/max_freq/cur_freq is 100MHz.
>> It cannot show the correct min_freq/max_freq through
>> devfreq sysfs interface.
>>
>>
>> 2. When disabling the some frequency by devfreq-thermal throttling,
>> This patch checks the min_freq of interconnect requirement
>> in the exynos_bus_target() and exynos_bus_passive_target().
>> Also, it cannot show the correct min_freq/max_freq through
>> devfreq sysfs interface.
>>
>> For example of bus_dmc bus,
>> - The available frequencies are 100MHz, 200MHz, 300MHz, 400MHz
>> - Disable 400MHz by devfreq-thermal throttling
>> - min_freq is 100MHz
>> - max_freq is 300MHz
>> - min_freq of interconnect is 400MHz
>>
>> In result, the final frequency is 400MHz by exynos_bus_target()
>> There are no problem for working. But, the user cannot know
>> reason why cur_freq is 400MHz even if max_freq is 300MHz.
>>
>> Basically, update_devfreq() considers the all constraints
>> of min_freq/max_freq to decide the proper target frequency.
>>
>>
>> 3.
>> I think that the exynos_bus_passive_target() is used for devfreq device
>> using 'passive' governor. The frequency already depends on the parent device.
>>
>> If already the parent devfreq device like bus_leftbus consider
>> the minimum frequency of QoS requirement like interconnect,
>> it is not necessary. The next frequency of devfreq device
>> with 'passive' governor, it will apply the QoS requirement
>> without any additional code.
>>
>>>
>>> Please note that it is not an error when CONFIG_INTERCONNECT is 'n', in
>>> which case all interconnect API functions are no-op.
>>>
>>> Signed-off-by: Artur Świgoń <a.swigon@partner.samsung.com>
>>> ---
>>> drivers/devfreq/exynos-bus.c | 145 +++++++++++++++++++++++++++++++++++
>>> 1 file changed, 145 insertions(+)
>>>
>>> diff --git a/drivers/devfreq/exynos-bus.c b/drivers/devfreq/exynos-bus.c
>>> index 412511ca7703..12fb7c84ae50 100644
>>> --- a/drivers/devfreq/exynos-bus.c
>>> +++ b/drivers/devfreq/exynos-bus.c
>>> @@ -14,6 +14,7 @@
>>> #include <linux/devfreq-event.h>
>>> #include <linux/device.h>
>>> #include <linux/export.h>
>>> +#include <linux/interconnect-provider.h>
>>> #include <linux/module.h>
>>> #include <linux/of.h>
>>> #include <linux/pm_opp.h>
>>> @@ -23,6 +24,8 @@
>>> #define DEFAULT_SATURATION_RATIO 40
>>> #define DEFAULT_VOLTAGE_TOLERANCE 2
>>>
>>> +#define icc_units_to_hz(x) ((x) * 1000UL / 8)
>>> +
>>> struct exynos_bus {
>>> struct device *dev;
>>>
>>> @@ -31,12 +34,17 @@ struct exynos_bus {
>>> unsigned int edev_count;
>>> struct mutex lock;
>>>
>>> + unsigned long min_freq;
>>> unsigned long curr_freq;
>>>
>>> struct regulator *regulator;
>>> struct clk *clk;
>>> unsigned int voltage_tolerance;
>>> unsigned int ratio;
>>> +
>>> + /* One provider per bus, one node per provider */
>>> + struct icc_provider provider;
>>> + struct icc_node *node;
>>> };
>>>
>>> /*
>>> @@ -61,6 +69,13 @@ exynos_bus_ops_edev(enable_edev);
>>> exynos_bus_ops_edev(disable_edev);
>>> exynos_bus_ops_edev(set_event);
>>>
>>> +static int exynos_bus_next_id(void)
>>> +{
>>> + static int exynos_bus_node_id;
>>> +
>>> + return exynos_bus_node_id++;
>>> +}
>>> +
>>> static int exynos_bus_get_event(struct exynos_bus *bus,
>>> struct devfreq_event_data *edata)
>>> {
>>> @@ -98,6 +113,8 @@ static int exynos_bus_target(struct device *dev, unsigned
>>> long *freq, u32 flags)
>>> unsigned long old_freq, new_freq, new_volt, tol;
>>> int ret = 0;
>>>
>>> + *freq = max(*freq, bus->min_freq);
>>> +
>>> /* Get new opp-bus instance according to new bus clock */
>>> new_opp = devfreq_recommended_opp(dev, freq, flags);
>>> if (IS_ERR(new_opp)) {
>>> @@ -208,6 +225,8 @@ static int exynos_bus_passive_target(struct device *dev,
>>> unsigned long *freq,
>>> unsigned long old_freq, new_freq;
>>> int ret = 0;
>>>
>>> + *freq = max(*freq, bus->min_freq);
>>> +
>>> /* Get new opp-bus instance according to new bus clock */
>>> new_opp = devfreq_recommended_opp(dev, freq, flags);
>>> if (IS_ERR(new_opp)) {
>>> @@ -251,6 +270,35 @@ static void exynos_bus_passive_exit(struct device *dev)
>>> clk_disable_unprepare(bus->clk);
>>> }
>>>
>>> +static int exynos_bus_icc_set(struct icc_node *src, struct icc_node *dst)
>>> +{
>>> + struct exynos_bus *src_bus = src->data, *dst_bus = dst->data;
>>> +
>>> + src_bus->min_freq = icc_units_to_hz(src->peak_bw);
>>> + dst_bus->min_freq = icc_units_to_hz(dst->peak_bw);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static int exynos_bus_icc_aggregate(struct icc_node *node, u32 avg_bw,
>>> + u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
>>> +{
>>> + *agg_peak = *agg_avg = peak_bw;
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static struct icc_node *exynos_bus_icc_xlate(struct of_phandle_args *spec,
>>> + void *data)
>>> +{
>>> + struct exynos_bus *bus = data;
>>> +
>>> + if (spec->np != bus->dev->of_node)
>>> + return ERR_PTR(-EINVAL);
>>> +
>>> + return bus->node;
>>> +}
>>> +
>>> static int exynos_bus_parent_parse_of(struct device_node *np,
>>> struct exynos_bus *bus)
>>> {
>>> @@ -469,6 +517,95 @@ static int exynos_bus_profile_init_passive(struct
>>> exynos_bus *bus,
>>> return ret;
>>> }
>>>
>>> +static int exynos_bus_icc_connect(struct exynos_bus *bus)
>>> +{
>>> + struct device_node *np = bus->dev->of_node;
>>> + struct devfreq *parent_devfreq;
>>> + struct icc_node *parent_node = NULL;
>>> + struct of_phandle_args args;
>>> + int ret = 0;
>>> +
>>> + parent_devfreq = devfreq_get_devfreq_by_phandle(bus->dev, 0);
>>> + if (!IS_ERR(parent_devfreq)) {
>>> + struct exynos_bus *parent_bus;
>>> +
>>> + parent_bus = dev_get_drvdata(parent_devfreq->dev.parent);
>>> + parent_node = parent_bus->node;
>>> + } else {
>>> + /* Look for parent in DT */
>>> + int num = of_count_phandle_with_args(np, "parent",
>>> + "#interconnect-cells");
>>> + if (num != 1)
>>> + goto out;
>>> +
>>> + ret = of_parse_phandle_with_args(np, "parent",
>>> + "#interconnect-cells",
>>> + 0, &args);
>>> + if (ret < 0)
>>> + goto out;
>>> +
>>> + of_node_put(args.np);
>>> +
>>> + parent_node = of_icc_get_from_provider(&args);
>>> + if (IS_ERR(parent_node)) {
>>> + /* May be -EPROBE_DEFER */
>>> + ret = PTR_ERR(parent_node);
>>> + goto out;
>>> + }
>>> + }
>>> +
>>> + ret = icc_link_create(bus->node, parent_node->id);
>>> +
>>> +out:
>>> + return ret;
>>> +}
>>> +
>>> +static int exynos_bus_icc_init(struct exynos_bus *bus)
>>> +{
>>> + struct device *dev = bus->dev;
>>> + struct icc_provider *provider = &bus->provider;
>>> + struct icc_node *node;
>>> + int id, ret;
>>> +
>>> + /* Initialize the interconnect provider */
>>> + provider->set = exynos_bus_icc_set;
>>> + provider->aggregate = exynos_bus_icc_aggregate;
>>> + provider->xlate = exynos_bus_icc_xlate;
>>> + provider->dev = dev;
>>> + provider->data = bus;
>>> +
>>> + ret = icc_provider_add(provider);
>>> + if (ret < 0)
>>> + goto out;
>>> +
>>> + id = exynos_bus_next_id();
>>> + node = icc_node_create(id);
>>> + if (IS_ERR(node)) {
>>> + ret = PTR_ERR(node);
>>> + goto err_node;
>>> + }
>>> +
>>> + bus->node = node;
>>> + node->name = dev->of_node->name;
>>> + node->data = bus;
>>> + icc_node_add(node, provider);
>>> +
>>> + ret = exynos_bus_icc_connect(bus);
>>> + if (ret < 0)
>>> + goto err_connect;
>>> +
>>> +out:
>>> + return ret;
>>> +
>>> +err_connect:
>>> + icc_node_del(node);
>>> + icc_node_destroy(id);
>>> +err_node:
>>> + icc_provider_del(provider);
>>> +
>>> + return ret;
>>> +}
>>> +
>>> static int exynos_bus_probe(struct platform_device *pdev)
>>> {
>>> struct device *dev = &pdev->dev;
>>> @@ -517,6 +654,14 @@ static int exynos_bus_probe(struct platform_device
>>> *pdev)
>>> goto err;
>>> }
>>>
>>> + /*
>>> + * Initialize interconnect provider. A return value of -ENOTSUPP means
>>> + * that CONFIG_INTERCONNECT is disabled.
>>> + */
>>> + ret = exynos_bus_icc_init(bus);
>>> + if (ret < 0 && ret != -ENOTSUPP)
>>> + goto err;
>>> +
>>> max_state = bus->devfreq->profile->max_state;
>>> min_freq = (bus->devfreq->profile->freq_table[0] / 1000);
>>> max_freq = (bus->devfreq->profile->freq_table[max_state - 1] / 1000);
>>>
>>
>>
--
Best Regards,
Chanwoo Choi
Samsung Electronics
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3 38/41] powerpc: convert put_page() to put_user_page*()
From: John Hubbard @ 2019-08-09 1:26 UTC (permalink / raw)
To: Michael Ellerman, Andrew Morton
Cc: linux-fbdev, Jan Kara, kvm, Benjamin Herrenschmidt, Dave Hansen,
Dave Chinner, dri-devel, linux-mm, sparclinux, Ira Weiny,
ceph-devel, devel, rds-devel, linux-rdma, x86, amd-gfx,
Christoph Hellwig, Christoph Hellwig, Jason Gunthorpe, xen-devel,
devel, linux-media, intel-gfx, linux-block,
Jérôme Glisse, linux-rpi-kernel, Dan Williams,
linux-arm-kernel, linux-nfs, netdev, LKML, linux-xfs,
linux-crypto, linux-fsdevel, linuxppc-dev
In-Reply-To: <87k1botdpx.fsf@concordia.ellerman.id.au>
On 8/7/19 10:42 PM, Michael Ellerman wrote:
> Hi John,
>
> john.hubbard@gmail.com writes:
>> diff --git a/arch/powerpc/mm/book3s64/iommu_api.c b/arch/powerpc/mm/book3s64/iommu_api.c
>> index b056cae3388b..e126193ba295 100644
>> --- a/arch/powerpc/mm/book3s64/iommu_api.c
>> +++ b/arch/powerpc/mm/book3s64/iommu_api.c
>> @@ -203,6 +202,7 @@ static void mm_iommu_unpin(struct mm_iommu_table_group_mem_t *mem)
>> {
>> long i;
>> struct page *page = NULL;
>> + bool dirty = false;
>
> I don't think you need that initialisation do you?
>
Nope, it can go. Fixed locally, thanks.
Did you get a chance to look at enough of the other bits to feel comfortable
with the patch, overall?
thanks,
--
John Hubbard
NVIDIA
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] mtd: spi-nor: aspeed-smc: Add of_node_put()
From: Andrew Jeffery @ 2019-08-09 0:38 UTC (permalink / raw)
To: Nishka Dasgupta, marek.vasut, tudor.ambarus, dwmw2,
computersforpeace, miquel.raynal, richard, vigneshr, Joel Stanley,
linux-mtd, linux-arm-kernel, linux-aspeed
In-Reply-To: <20190808075104.15928-1-nishkadg.linux@gmail.com>
On Thu, 8 Aug 2019, at 17:21, Nishka Dasgupta wrote:
> Each iteration of for_each_available_child_of_node puts the previous
> node, but in the case of a break from the middle of the loop, there is
> no put, thus causing a memory leak. Upon termination of the loop
> (whether by break or a natural exit), either ret will have a non-zero
> value or child will be NULL. Hence add an of_node_put() that will
> execute only when ret has a non-zero value, as calling of_node_put() on
> a possible NULL value does not cause any further issues.
> Issue found with Coccinelle.
>
> Signed-off-by: Nishka Dasgupta <nishkadg.linux@gmail.com>
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 0/6] arm64: g12a: add support for DVFS
From: Kevin Hilman @ 2019-08-08 23:56 UTC (permalink / raw)
To: Neil Armstrong
Cc: linux-amlogic, linux-kernel, linux-arm-kernel, Neil Armstrong
In-Reply-To: <7hwofrh1md.fsf@baylibre.com>
Kevin Hilman <khilman@baylibre.com> writes:
> Neil Armstrong <narmstrong@baylibre.com> writes:
>
>> The G12A & G12B SoCs has kernel controllable CPU clocks and PWMs for
>> voltage regulators.
>>
>> This patchsets moves the meson-g12a.dtsi to meson-g12-common.dtsi to simplify
>> handling the G12A & G12B differences in the meson-g12a.dtsi & meson-g12b.dtsi
>> files, like the OPPs and CPU nodes.
>>
>> Then G12A & G12B OPP tables are added, followed by the CPU voltages regulators
>> in each boards DT.
>>
>> It was voluntary chosen to enabled DVFS (CPU regulator and CPU clocks) only
>> in boards, to make sure only tested boards has DVFS enabled.
>>
>> This patchset :
>> - moves the G12A DT to a common g12a-common dtsi
>> - adds the G12A and G12B OPPs
>> - enables DVFS on all supported boards
>>
>> Dependencies:
>> - None
>
> Not quite. The last patch to enable DVFS on odroid-n2 has a build-time
> dependency on the clock series that adds the CPUB clock.
>
> I'll apply the rest of the series to v5.4/dt64 until there's a stable
> clock tag I can use for the clocks.
In order to test this, I noticed another dependency needed for the PWM
regulators to work:
https://lore.kernel.org/linux-amlogic/20190729125838.6498-1-narmstrong@baylibre.com/
With that and the clock deps, it's working well on my odroid-n2.
Tested-by: Kevin Hilman <khilman@baylibre.com>
Thanks,
Kevin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 13/22] input: omap: void using mach/*.h headers
From: Sebastian Reichel @ 2019-08-08 23:39 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Arnd Bergmann, Bartlomiej Zolnierkiewicz, Tony Lindgren,
Greg Kroah-Hartman, Linus Walleij, Aaro Koskinen,
Linux Kernel Mailing List, Tomi Valkeinen,
open list:HID CORE LAYER, linux-omap, Linux ARM
In-Reply-To: <20190808221950.GG178933@dtor-ws>
[-- Attachment #1.1: Type: text/plain, Size: 1631 bytes --]
Hi,
On Thu, Aug 08, 2019 at 03:19:50PM -0700, Dmitry Torokhov wrote:
> On Thu, Aug 08, 2019 at 11:46:45PM +0200, Arnd Bergmann wrote:
> > On Thu, Aug 8, 2019 at 11:43 PM Dmitry Torokhov wrote:
> > > On Thu, Aug 08, 2019 at 11:22:22PM +0200, Arnd Bergmann wrote:
> > > > By using the new linux/soc/ti/omap1-io.h header instead,
> > > > compile-testing can be enabled, and a CONFIG_ARCH_MULTIPLATFORM
> > > > conversion of omap1 may eventually be possible.
> > > >
> > > > The warning in the header file gets removed in order to
> > > > allow CONFIG_COMPILE_TEST.
> > >
> > > Given that we want to migrate people off this driver everywhere but
> > > OMAP1 I wonder why we would want to improve compile coverage of it.
> >
> > Mainly for consistency: I'm converting all omap1 drivers in this series to
> > not rely on mach/* headers and to let them be compiled standalone.
> > The other drivers don't have a replacement, so I could treat this different
> > from the rest and skip the Kconfig and platform_data changes if you
> > prefer.
>
> Yes, because at least with the version you posted we are losing the
> #warning telling people to move to matrix_keypad. We could do:
>
> #ifndef CONFIG_COMPILE_TEST
> #warning ...
> #endif
>
> if you really want to allow compiling standalone for testing.
FWIW the driver depends on ARCH_OMAP1 and the warning is
only printed for !ARCH_OMAP1. In other words: The warning
is never printed at the moment. All OMAP2+ boards moved to
matrix-keypad long time ago and the driver does not support
OMAP2+ anymore since f799a3d8fe170 from 2012.
-- Sebastian
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [linux-sunxi] [PATCH 0/3] Add basic support for RTC on Allwinner H6 SoC
From: Alexandre Belloni @ 2019-08-08 23:39 UTC (permalink / raw)
To: Chen-Yu Tsai, Mark Rutland, Alessandro Zummo, devicetree,
Maxime Ripard, linux-kernel, linux-sunxi, Rob Herring,
linux-arm-kernel, linux-rtc
In-Reply-To: <20190808121237.g6twq2nh3sayu3vx@core.my.home>
On 08/08/2019 14:12:37+0200, Ondřej Jirman wrote:
> On Wed, Aug 07, 2019 at 12:55:02PM +0200, Alexandre Belloni wrote:
> > Hi,
> >
> > On 06/08/2019 20:30:45+0200, Ondřej Jirman wrote:
> > > Maybe whether XO or DCXO is used also matters if you want to do some fine
> > > tunning of DCXO (control register has pletny of options), but that's probably
> > > better done in u-boot. And there's still no need to read HOSC source from DT.
> > > The driver can just check compatible, and if it is H6 and OSC_CLK_SRC_SEL is 1,
> > > it can do it's DCXO tunning, or whatever. But neither OS nor bootloader will
> > > be using this info to gate/disable the osciallator.
> > >
> >
> > It is actually useful to be able to tweak the crystal tuning at
> > runtime to be able to reduce clock drift and compare with a reliable
> > source (e.g. NTP).
>
> I don't think there's a Linux kernel API that you can use to achieve that, so
> that's a rather theoretical concern at the moment.
>
There is /sys/class/rtc/rtcX/offset which is even properly documented.
The reason I asked is that some RTCs have both analog (changing the
oscillator capacitance) and digital (changing the RTC counter) so I'm
wondering whether this interface should be extended.
> Also there are multiple clocks, that can drive the RTC, and you usually don't
> drive it from 24MHz DCXO oscillator. The reason is that you'd have to deal with
> the fact that the clock for RTC then becomes 24000000/750 (750 is fixed
> divider), which is 32000.
>
> So if you want to get 32768Hz for RTC by tuning the DCXO, it would have to have
> 24 576 000 Hz. And even if you could achieve that (doubtful), it would throw off
> timings in the rest of the system (say UART, USB, CPU, display ctl) in a major way.
>
> I guess you can try tuning 24MHz oscillator so that it's closer to the
> real-world 24MHz via NTP reference for other reasons. But it would be
> complicated, and require precise interaction with other components, like using
> HW timers sourced from 24MHz HOSC clock, because you can't use CPU's timers,
> because of inaccuracies introduced during DVFS, for example.
>
> regards,
> o.
>
> > I'm curious, what kind of options does this RTC have?
> >
> > --
> > Alexandre Belloni, Bootlin
> > Embedded Linux and Kernel engineering
> > https://bootlin.com
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v19 00/15] arm64: untag user pointers passed to the kernel
From: Kees Cook @ 2019-08-08 23:09 UTC (permalink / raw)
To: Andrew Morton
Cc: Mark Rutland, kvm, Christian Koenig, Szabolcs Nagy,
Catalin Marinas, Will Deacon, dri-devel, Kostya Serebryany,
Khalid Aziz, Lee Smith, open list:KERNEL SELFTEST FRAMEWORK,
Vincenzo Frascino, Will Deacon, Jacob Bramley, Leon Romanovsky,
linux-rdma, amd-gfx, Christoph Hellwig, Jason Gunthorpe,
Dmitry Vyukov, Dave Martin, Evgeniy Stepanov, linux-media,
Ruben Ayrapetyan, Andrey Konovalov, Kevin Brodsky,
Alex Williamson, Mauro Carvalho Chehab, Linux ARM,
Linux Memory Management List, Greg Kroah-Hartman, Felix Kuehling,
LKML, Jens Wiklander, Ramana Radhakrishnan, Alexander Deucher,
enh, Robin Murphy, Yishai Hadas, Luc Van Oostenryck
In-Reply-To: <20190808153300.09d3eb80772515f0ea062833@linux-foundation.org>
On Thu, Aug 08, 2019 at 03:33:00PM -0700, Andrew Morton wrote:
> On Thu, 8 Aug 2019 14:12:19 -0700 Kees Cook <keescook@chromium.org> wrote:
>
> > > The ones that are left are the mm ones: 4, 5, 6, 7 and 8.
> > >
> > > Andrew, could you take a look and give your Acked-by or pick them up directly?
> >
> > Given the subsystem Acks, it seems like 3-10 and 12 could all just go
> > via Andrew? I hope he agrees. :)
>
> I'll grab everything that has not yet appeared in linux-next. If more
> of these patches appear in linux-next I'll drop those as well.
>
> The review discussion against " [PATCH v19 02/15] arm64: Introduce
> prctl() options to control the tagged user addresses ABI" has petered
> out inconclusively. prctl() vs arch_prctl().
I've always disliked arch_prctl() existing at all. Given that tagging is
likely to be a multi-architectural feature, it seems like the controls
should live in prctl() to me.
--
Kees Cook
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v19 00/15] arm64: untag user pointers passed to the kernel
From: Andrew Morton @ 2019-08-08 22:33 UTC (permalink / raw)
To: Kees Cook
Cc: Mark Rutland, kvm, Christian Koenig, Szabolcs Nagy,
Catalin Marinas, Will Deacon, dri-devel, Kostya Serebryany,
Khalid Aziz, Lee Smith, open list:KERNEL SELFTEST FRAMEWORK,
Vincenzo Frascino, Will Deacon, Jacob Bramley, Leon Romanovsky,
linux-rdma, amd-gfx, Christoph Hellwig, Jason Gunthorpe,
Dmitry Vyukov, Dave Martin, Evgeniy Stepanov, linux-media,
Ruben Ayrapetyan, Andrey Konovalov, Kevin Brodsky,
Alex Williamson, Mauro Carvalho Chehab, Linux ARM,
Linux Memory Management List, Greg Kroah-Hartman, Felix Kuehling,
LKML, Jens Wiklander, Ramana Radhakrishnan, Alexander Deucher,
enh, Robin Murphy, Yishai Hadas, Luc Van Oostenryck
In-Reply-To: <201908081410.C16D2BD@keescook>
On Thu, 8 Aug 2019 14:12:19 -0700 Kees Cook <keescook@chromium.org> wrote:
> > The ones that are left are the mm ones: 4, 5, 6, 7 and 8.
> >
> > Andrew, could you take a look and give your Acked-by or pick them up directly?
>
> Given the subsystem Acks, it seems like 3-10 and 12 could all just go
> via Andrew? I hope he agrees. :)
I'll grab everything that has not yet appeared in linux-next. If more
of these patches appear in linux-next I'll drop those as well.
The review discussion against " [PATCH v19 02/15] arm64: Introduce
prctl() options to control the tagged user addresses ABI" has petered
out inconclusively. prctl() vs arch_prctl().
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [Tee-dev] [RFC v2 2/6] tee: enable support to register kernel memory
From: Stuart Yoder @ 2019-08-08 22:26 UTC (permalink / raw)
To: Sumit Garg, keyrings, linux-integrity, linux-security-module
Cc: corbet, daniel.thompson, ard.biesheuvel, jejb, linux-doc,
linux-kernel, zohar, tee-dev, jarkko.sakkinen, dhowells, casey,
linux-arm-kernel, serge
In-Reply-To: <1564489420-677-3-git-send-email-sumit.garg@linaro.org>
On 7/30/19 7:23 AM, Sumit Garg wrote:
> @@ -264,7 +266,17 @@ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr,
> goto err;
> }
>
> - rc = get_user_pages_fast(start, num_pages, FOLL_WRITE, shm->pages);
> + if (flags & TEE_SHM_USER_MAPPED) {
> + rc = get_user_pages_fast(start, num_pages, FOLL_WRITE,
> + shm->pages);
> + } else {
> + const struct kvec kiov = {
> + .iov_base = (void *)start,
> + .iov_len = PAGE_SIZE
> + };
> +
> + rc = get_kernel_pages(&kiov, num_pages, 0, shm->pages);
Passing a single kvec struct is temporary I assume? Because as currently
written this will only work with num_pages==1.
Stuart
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v4 1/2] ACPI/PPTT: Add support for ACPI 6.3 thread flag
From: Robert Richter @ 2019-08-08 22:25 UTC (permalink / raw)
To: Jeremy Linton
Cc: lorenzo.pieralisi@arm.com, rric@kernel.org,
catalin.marinas@arm.com, rjw@rjwysocki.net,
linux-acpi@vger.kernel.org, sudeep.holla@arm.com, will@kernel.org,
linux-arm-kernel@lists.infradead.org, lenb@kernel.org
In-Reply-To: <20190808204007.30110-2-jeremy.linton@arm.com>
On 08.08.19 15:40:06, Jeremy Linton wrote:
> ACPI 6.3 adds a flag to the CPU node to indicate whether
> the given PE is a thread. Add a function to return that
> information for a given linux logical CPU.
>
> Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
> Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
> ---
> drivers/acpi/pptt.c | 53 +++++++++++++++++++++++++++++++++++++++++++-
> include/linux/acpi.h | 5 +++++
> 2 files changed, 57 insertions(+), 1 deletion(-)
Reviewed-by: Robert Richter <rrichter@marvell.com>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 07/22] ARM: omap1: move perseus spi pinconf to board file
From: Mark Brown @ 2019-08-08 22:24 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Aaro Koskinen, Tony Lindgren, Greg Kroah-Hartman, Linus Walleij,
Bartlomiej Zolnierkiewicz, linux-kernel, linux-spi,
Tomi Valkeinen, linux-omap, linux-arm-kernel, Boris Brezillon
In-Reply-To: <20190808212234.2213262-8-arnd@arndb.de>
[-- Attachment #1.1: Type: text/plain, Size: 339 bytes --]
On Thu, Aug 08, 2019 at 11:22:16PM +0200, Arnd Bergmann wrote:
> The driver has always had a FIXME about this, and it seems
> like this trivial code move avoids a mach header inclusion,
> so just do it.
This appears to be part of a series but I've no cover letter or anything
else from it. What's the story for dependencies and merging?
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v4 2/2] arm64: topology: Use PPTT to determine if PE is a thread
From: Robert Richter @ 2019-08-08 22:23 UTC (permalink / raw)
To: Jeremy Linton
Cc: lorenzo.pieralisi@arm.com, rric@kernel.org,
catalin.marinas@arm.com, rjw@rjwysocki.net,
linux-acpi@vger.kernel.org, sudeep.holla@arm.com, will@kernel.org,
linux-arm-kernel@lists.infradead.org, lenb@kernel.org
In-Reply-To: <20190808204007.30110-3-jeremy.linton@arm.com>
On 08.08.19 15:40:07, Jeremy Linton wrote:
> ACPI 6.3 adds a thread flag to represent if a CPU/PE is
> actually a thread. Given that the MPIDR_MT bit may not
> represent this information consistently on homogeneous machines
> we should prefer the PPTT flag if its available.
>
> Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
> Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
> ---
> arch/arm64/kernel/topology.c | 19 +++++++++++++++----
> 1 file changed, 15 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
> index 0825c4a856e3..bad9c42ea825 100644
> --- a/arch/arm64/kernel/topology.c
> +++ b/arch/arm64/kernel/topology.c
> @@ -340,17 +340,28 @@ void remove_cpu_topology(unsigned int cpu)
> }
>
> #ifdef CONFIG_ACPI
> +static int __init acpi_cpu_is_threaded(int cpu)
> +{
> + int is_threaded = acpi_pptt_cpu_is_thread(cpu);
> +
> + /*
> + * if the PPTT doesn't have thread information, assume a homogeneous
> + * machine and return the current CPU's thread state.
> + */
> + if (is_threaded < 0)
> + is_threaded = read_cpuid_mpidr() & MPIDR_MT_BITMASK;
Since this is no longer bool now, better have a !!(...) or (...) != 0
here.
> +
> + return is_threaded;
> +}
> +
> /*
> * Propagate the topology information of the processor_topology_node tree to the
> * cpu_topology array.
> */
> static int __init parse_acpi_topology(void)
> {
> - bool is_threaded;
> int cpu, topology_id;
>
> - is_threaded = read_cpuid_mpidr() & MPIDR_MT_BITMASK;
> -
> for_each_possible_cpu(cpu) {
> int i, cache_id;
>
> @@ -358,7 +369,7 @@ static int __init parse_acpi_topology(void)
> if (topology_id < 0)
> return topology_id;
>
> - if (is_threaded) {
> + if (acpi_cpu_is_threaded(cpu)) {
> cpu_topology[cpu].thread_id = topology_id;
> topology_id = find_acpi_cpu_topology(cpu, 1);
> cpu_topology[cpu].core_id = topology_id;
Looks otherwise ok.
Reviewed-by: Robert Richter <rrichter@marvell.com>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 13/22] input: omap: void using mach/*.h headers
From: Dmitry Torokhov @ 2019-08-08 22:19 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Aaro Koskinen, Tony Lindgren, Greg Kroah-Hartman, Linus Walleij,
Bartlomiej Zolnierkiewicz, Linux Kernel Mailing List,
Tomi Valkeinen, open list:HID CORE LAYER, linux-omap, Linux ARM
In-Reply-To: <CAK8P3a2TOcjxwCBGkZAhMAf9HuTL=FAB1e0=FAg+oHB0U1nJ0A@mail.gmail.com>
On Thu, Aug 08, 2019 at 11:46:45PM +0200, Arnd Bergmann wrote:
> On Thu, Aug 8, 2019 at 11:43 PM Dmitry Torokhov
> <dmitry.torokhov@gmail.com> wrote:
> >
> > Hi Arnd,
> >
> > On Thu, Aug 08, 2019 at 11:22:22PM +0200, Arnd Bergmann wrote:
> > > By using the new linux/soc/ti/omap1-io.h header instead,
> > > compile-testing can be enabled, and a CONFIG_ARCH_MULTIPLATFORM
> > > conversion of omap1 may eventually be possible.
> > >
> > > The warning in the header file gets removed in order to
> > > allow CONFIG_COMPILE_TEST.
> >
> > Given that we want to migrate people off this driver everywhere but
> > OMAP1 I wonder why we would want to improve compile coverage of it.
>
> Mainly for consistency: I'm converting all omap1 drivers in this series to
> not rely on mach/* headers and to let them be compiled standalone.
> The other drivers don't have a replacement, so I could treat this different
> from the rest and skip the Kconfig and platform_data changes if you
> prefer.
Yes, because at least with the version you posted we are losing the
#warning telling people to move to matrix_keypad. We could do:
#ifndef CONFIG_COMPILE_TEST
#warning ...
#endif
if you really want to allow compiling standalone for testing.
Thanks.
--
Dmitry
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] arm64/cache: silence -Woverride-init warnings
From: Qian Cai @ 2019-08-08 22:18 UTC (permalink / raw)
To: Mark Rutland
Cc: Catalin Marinas, Will Deacon, Linux List Kernel Mailing,
linux-arm-kernel, clang-built-linux
In-Reply-To: <20190808103808.GC46901@lakrids.cambridge.arm.com>
> On Aug 8, 2019, at 6:38 AM, Mark Rutland <mark.rutland@arm.com> wrote:
>
> On Wed, Aug 07, 2019 at 11:29:16PM -0400, Qian Cai wrote:
>> The commit 155433cb365e ("arm64: cache: Remove support for ASID-tagged
>> VIVT I-caches") introduced some compiation warnings from GCC (and
>> Clang) with -Winitializer-overrides),
>>
>> arch/arm64/kernel/cpuinfo.c:38:26: warning: initialized field
>> overwritten [-Woverride-init]
>> [ICACHE_POLICY_VIPT] = "VIPT",
>> ^~~~~~
>> arch/arm64/kernel/cpuinfo.c:38:26: note: (near initialization for
>> 'icache_policy_str[2]')
>> arch/arm64/kernel/cpuinfo.c:39:26: warning: initialized field
>> overwritten [-Woverride-init]
>> [ICACHE_POLICY_PIPT] = "PIPT",
>> ^~~~~~
>> arch/arm64/kernel/cpuinfo.c:39:26: note: (near initialization for
>> 'icache_policy_str[3]')
>> arch/arm64/kernel/cpuinfo.c:40:27: warning: initialized field
>> overwritten [-Woverride-init]
>> [ICACHE_POLICY_VPIPT] = "VPIPT",
>> ^~~~~~~
>> arch/arm64/kernel/cpuinfo.c:40:27: note: (near initialization for
>> 'icache_policy_str[0]')
>>
>> because it initializes icache_policy_str[0 ... 3] twice. Since
>> arm64 developers are keen to keep the style of initializing a static
>> array with a non-zero pattern first, just disable those warnings for
>> both GCC and Clang of this file.
>>
>> Fixes: 155433cb365e ("arm64: cache: Remove support for ASID-tagged VIVT I-caches")
>> Signed-off-by: Qian Cai <cai@lca.pw>
>
> This is _not_ a fix, and should not require backporting to stable trees.
From my experience, the stable AI will pick up whatever they want to backport
not matter if there Is a “Fixes” tag or not unless it is one of those subsystems like
Networking that exclusively manually flag for. backporting by the maintainer.
>
> What about all the other instances that we have in mainline?
I have not had a chance to review all instances yet. It is not unusually to fix one
warning at a time, and then go on fixing some more if time permit.
>
> I really don't think that we need to go down this road; we're just going
> to end up adding this to every file that happens to include a header
> using this scheme…
How about disable them this way in a top level like arch/arm64/Makefile or
arch/arm64/kernel/Makefile? Therefore, there is no need to add this to
every file, but with a drawback that it could miss a few real issues there
in the future which probably not many people are checking for them of
the arm64 subsystem nowadays.
>
> Please just turn this off by default for clang.
As mentioned before, it is very valuable to run “make W=1” given it found
many real developer mistakes which will enable “-Woverride-init” for both
compilers. Even “-Woverride-init” itself is useful find real issues as in,
ae5e033d65a (“mfd: rk808: Fix RK818_IRQ_DISCHG_ILIM initializer”)
32df34d875bb (“[media] rc: img-ir: jvc: Remove unused no-leader timings”)
Especially, to find redundant initializations in large structures. e.g.,
e6ea0b917875 (“[media] dvb_frontend: Don't declare values twice at a table”)
It is important to keep the noise-level as low as possible by keeping the
amount of false positives under control to be truly benefit from those
valuable compiler warnings.
>
> If we want to enable this, we need a mechanism to permit overridable
> assignments as we use range initializers for.
I am not sure that it is worth filling a RFE for compilers of that feature.
I feel like the range initializers just another way to initialize an array, and
it is just easier to make mistakes with unintended double-initializations.
The compiler developers probably recommend to enforce more of
“-Woverride-init” for the range initializers rather than permitting it.
>
> Thanks,
> Mark.
>
>> ---
>> arch/arm64/kernel/Makefile | 3 +++
>> 1 file changed, 3 insertions(+)
>>
>> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
>> index 478491f07b4f..397ed5f7be1e 100644
>> --- a/arch/arm64/kernel/Makefile
>> +++ b/arch/arm64/kernel/Makefile
>> @@ -11,6 +11,9 @@ CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE)
>> CFLAGS_REMOVE_insn.o = $(CC_FLAGS_FTRACE)
>> CFLAGS_REMOVE_return_address.o = $(CC_FLAGS_FTRACE)
>>
>> +CFLAGS_cpuinfo.o += $(call cc-disable-warning, override-init)
>> +CFLAGS_cpuinfo.o += $(call cc-disable-warning, initializer-overrides)
>> +
>> # Object file lists.
>> obj-y := debug-monitors.o entry.o irq.o fpsimd.o \
>> entry-fpsimd.o process.o ptrace.o setup.o signal.o \
>> --
>> 2.20.1 (Apple Git-117)
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] phy: Change the configuration interface param to void* to make it more general
From: kbuild test robot @ 2019-08-08 22:01 UTC (permalink / raw)
To: Zeng Tao
Cc: Sakari Ailus, Maxime Ripard, linux-kernel, kishon,
Paul Kocialkowski, Chen-Yu Tsai, kbuild-all, prime.zeng,
linux-arm-kernel
In-Reply-To: <1562868255-31467-1-git-send-email-prime.zeng@hisilicon.com>
Hi Zeng,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on linus/master]
[cannot apply to v5.3-rc3 next-20190808]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Zeng-Tao/phy-Change-the-configuration-interface-param-to-void-to-make-it-more-general/20190713-213420
reproduce:
# apt-get install sparse
# sparse version: v0.6.1-rc1-7-g2b96cd8-dirty
make ARCH=x86_64 allmodconfig
make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
sparse warnings: (new ones prefixed by >>)
include/linux/sched.h:609:43: sparse: sparse: bad integer constant expression
include/linux/sched.h:609:73: sparse: sparse: invalid named zero-width bitfield `value'
include/linux/sched.h:610:43: sparse: sparse: bad integer constant expression
include/linux/sched.h:610:67: sparse: sparse: invalid named zero-width bitfield `bucket_id'
>> drivers/gpu/drm/bridge/cdns-dsi.c:609:73: sparse: sparse: using member 'mipi_dphy' in incomplete union phy_configure_opts
drivers/gpu/drm/bridge/cdns-dsi.c:784:73: sparse: sparse: using member 'mipi_dphy' in incomplete union phy_configure_opts
--
include/linux/sched.h:609:43: sparse: sparse: bad integer constant expression
include/linux/sched.h:609:73: sparse: sparse: invalid named zero-width bitfield `value'
include/linux/sched.h:610:43: sparse: sparse: bad integer constant expression
include/linux/sched.h:610:67: sparse: sparse: invalid named zero-width bitfield `bucket_id'
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:165:22: sparse: sparse: using member 'hs_clk_rate' in incomplete struct phy_configure_opts_mipi_dphy
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:169:30: sparse: sparse: using member 'hs_clk_rate' in incomplete struct phy_configure_opts_mipi_dphy
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:173:17: sparse: sparse: using member 'hs_clk_rate' in incomplete struct phy_configure_opts_mipi_dphy
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:200:17: sparse: sparse: using member 'hs_clk_rate' in incomplete struct phy_configure_opts_mipi_dphy
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:206:9: sparse: sparse: using member 'hs_clk_rate' in incomplete struct phy_configure_opts_mipi_dphy
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:211:9: sparse: sparse: using member 'lp_clk_rate' in incomplete struct phy_configure_opts_mipi_dphy
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:216:9: sparse: sparse: using member 'lp_clk_rate' in incomplete struct phy_configure_opts_mipi_dphy
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:220:26: sparse: sparse: using member 'hs_prepare' in incomplete struct phy_configure_opts_mipi_dphy
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:221:17: sparse: sparse: using member 'hs_prepare' in incomplete struct phy_configure_opts_mipi_dphy
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:227:22: sparse: sparse: using member 'hs_prepare' in incomplete struct phy_configure_opts_mipi_dphy
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:230:37: sparse: sparse: using member 'hs_prepare' in incomplete struct phy_configure_opts_mipi_dphy
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:237:26: sparse: sparse: using member 'clk_prepare' in incomplete struct phy_configure_opts_mipi_dphy
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:238:17: sparse: sparse: using member 'clk_prepare' in incomplete struct phy_configure_opts_mipi_dphy
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:244:43: sparse: sparse: using member 'clk_prepare' in incomplete struct phy_configure_opts_mipi_dphy
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:247:30: sparse: sparse: using member 'hs_clk_rate' in incomplete struct phy_configure_opts_mipi_dphy
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:251:29: sparse: sparse: using member 'hs_clk_rate' in incomplete struct phy_configure_opts_mipi_dphy
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:255:30: sparse: sparse: using member 'hs_clk_rate' in incomplete struct phy_configure_opts_mipi_dphy
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:264:22: sparse: sparse: using member 'hs_clk_rate' in incomplete struct phy_configure_opts_mipi_dphy
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:266:27: sparse: sparse: using member 'hs_clk_rate' in incomplete struct phy_configure_opts_mipi_dphy
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:268:27: sparse: sparse: using member 'hs_clk_rate' in incomplete struct phy_configure_opts_mipi_dphy
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:270:27: sparse: sparse: using member 'hs_clk_rate' in incomplete struct phy_configure_opts_mipi_dphy
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:272:27: sparse: sparse: using member 'hs_clk_rate' in incomplete struct phy_configure_opts_mipi_dphy
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:274:27: sparse: sparse: using member 'hs_clk_rate' in incomplete struct phy_configure_opts_mipi_dphy
>> drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:326:53: sparse: sparse: using member 'mipi_dphy' in incomplete union phy_configure_opts
drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:356:54: sparse: sparse: using member 'mipi_dphy' in incomplete union phy_configure_opts
vim +/mipi_dphy +609 drivers/gpu/drm/bridge/cdns-dsi.c
4dad3e7f12f702 Maxime Ripard 2019-01-21 602
4dad3e7f12f702 Maxime Ripard 2019-01-21 603 static int cdns_dsi_check_conf(struct cdns_dsi *dsi,
4dad3e7f12f702 Maxime Ripard 2019-01-21 604 const struct drm_display_mode *mode,
4dad3e7f12f702 Maxime Ripard 2019-01-21 605 struct cdns_dsi_cfg *dsi_cfg,
4dad3e7f12f702 Maxime Ripard 2019-01-21 606 bool mode_valid_check)
4dad3e7f12f702 Maxime Ripard 2019-01-21 607 {
4dad3e7f12f702 Maxime Ripard 2019-01-21 608 struct cdns_dsi_output *output = &dsi->output;
fced5a364dee9d Maxime Ripard 2019-01-21 @609 struct phy_configure_opts_mipi_dphy *phy_cfg = &output->phy_opts.mipi_dphy;
4dad3e7f12f702 Maxime Ripard 2019-01-21 610 unsigned long dsi_hss_hsa_hse_hbp;
4dad3e7f12f702 Maxime Ripard 2019-01-21 611 unsigned int nlanes = output->dev->lanes;
4dad3e7f12f702 Maxime Ripard 2019-01-21 612 int ret;
4dad3e7f12f702 Maxime Ripard 2019-01-21 613
4dad3e7f12f702 Maxime Ripard 2019-01-21 614 ret = cdns_dsi_mode2cfg(dsi, mode, dsi_cfg, mode_valid_check);
4dad3e7f12f702 Maxime Ripard 2019-01-21 615 if (ret)
4dad3e7f12f702 Maxime Ripard 2019-01-21 616 return ret;
4dad3e7f12f702 Maxime Ripard 2019-01-21 617
fced5a364dee9d Maxime Ripard 2019-01-21 618 phy_mipi_dphy_get_default_config(mode->crtc_clock * 1000,
fced5a364dee9d Maxime Ripard 2019-01-21 619 mipi_dsi_pixel_format_to_bpp(output->dev->format),
fced5a364dee9d Maxime Ripard 2019-01-21 620 nlanes, phy_cfg);
fced5a364dee9d Maxime Ripard 2019-01-21 621
fced5a364dee9d Maxime Ripard 2019-01-21 622 ret = cdns_dsi_adjust_phy_config(dsi, dsi_cfg, phy_cfg, mode, mode_valid_check);
fced5a364dee9d Maxime Ripard 2019-01-21 623 if (ret)
fced5a364dee9d Maxime Ripard 2019-01-21 624 return ret;
fced5a364dee9d Maxime Ripard 2019-01-21 625
fced5a364dee9d Maxime Ripard 2019-01-21 626 ret = phy_validate(dsi->dphy, PHY_MODE_MIPI_DPHY, 0, &output->phy_opts);
4dad3e7f12f702 Maxime Ripard 2019-01-21 627 if (ret)
4dad3e7f12f702 Maxime Ripard 2019-01-21 628 return ret;
4dad3e7f12f702 Maxime Ripard 2019-01-21 629
4dad3e7f12f702 Maxime Ripard 2019-01-21 630 dsi_hss_hsa_hse_hbp = dsi_cfg->hbp + DSI_HBP_FRAME_OVERHEAD;
4dad3e7f12f702 Maxime Ripard 2019-01-21 631 if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
4dad3e7f12f702 Maxime Ripard 2019-01-21 632 dsi_hss_hsa_hse_hbp += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD;
e19233955d9e9a Boris Brezillon 2018-04-21 633
e19233955d9e9a Boris Brezillon 2018-04-21 634 /*
e19233955d9e9a Boris Brezillon 2018-04-21 635 * Make sure DPI(HFP) > DSI(HSS+HSA+HSE+HBP) to guarantee that the FIFO
e19233955d9e9a Boris Brezillon 2018-04-21 636 * is empty before we start a receiving a new line on the DPI
e19233955d9e9a Boris Brezillon 2018-04-21 637 * interface.
e19233955d9e9a Boris Brezillon 2018-04-21 638 */
fced5a364dee9d Maxime Ripard 2019-01-21 639 if ((u64)phy_cfg->hs_clk_rate *
4dad3e7f12f702 Maxime Ripard 2019-01-21 640 mode_to_dpi_hfp(mode, mode_valid_check) * nlanes <
e19233955d9e9a Boris Brezillon 2018-04-21 641 (u64)dsi_hss_hsa_hse_hbp *
e19233955d9e9a Boris Brezillon 2018-04-21 642 (mode_valid_check ? mode->clock : mode->crtc_clock) * 1000)
e19233955d9e9a Boris Brezillon 2018-04-21 643 return -EINVAL;
e19233955d9e9a Boris Brezillon 2018-04-21 644
e19233955d9e9a Boris Brezillon 2018-04-21 645 return 0;
e19233955d9e9a Boris Brezillon 2018-04-21 646 }
e19233955d9e9a Boris Brezillon 2018-04-21 647
:::::: The code at line 609 was first introduced by commit
:::::: fced5a364dee9d3a3ed1e3290ea3b83984b78007 drm/bridge: cdns: Convert to phy framework
:::::: TO: Maxime Ripard <maxime.ripard@bootlin.com>
:::::: CC: Maxime Ripard <maxime.ripard@bootlin.com>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v8 09/14] media: rkisp1: add rockchip isp1 core driver
From: Helen Koike @ 2019-08-08 21:59 UTC (permalink / raw)
To: Sakari Ailus
Cc: devicetree, eddie.cai.linux, kernel, heiko, jacob2.chen,
jeffy.chen, zyc, linux-kernel, tfiga, linux-rockchip, Allon Huang,
Jacob Chen, hans.verkuil, laurent.pinchart, zhengsq, mchehab,
ezequiel, linux-arm-kernel, linux-media
In-Reply-To: <20190807152727.GN21370@paasikivi.fi.intel.com>
Hi Sakari,
Thanks for your review, just some comments/questions below:
On 8/7/19 12:27 PM, Sakari Ailus wrote:
> Hi Helen,
>
> On Tue, Jul 30, 2019 at 03:42:51PM -0300, Helen Koike wrote:
>> From: Jacob Chen <jacob2.chen@rock-chips.com>
>>
>> Add the core driver for rockchip isp1.
>>
>> Signed-off-by: Jacob Chen <jacob2.chen@rock-chips.com>
>> Signed-off-by: Shunqian Zheng <zhengsq@rock-chips.com>
>> Signed-off-by: Yichong Zhong <zyc@rock-chips.com>
>> Signed-off-by: Jacob Chen <cc@rock-chips.com>
>> Signed-off-by: Eddie Cai <eddie.cai.linux@gmail.com>
>> Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
>> Signed-off-by: Allon Huang <allon.huang@rock-chips.com>
>> Signed-off-by: Tomasz Figa <tfiga@chromium.org>
>> [fixed compilation and run time errors regarding new v4l2 async API]
>> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
>> [Add missing module device table]
>> Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
>> [update for upstream]
>> Signed-off-by: Helen Koike <helen.koike@collabora.com>
>>
>> ---
>>
>> Changes in v8: None
>> Changes in v7:
>> - VIDEO_ROCKCHIP_ISP1 selects VIDEOBUF2_VMALLOC
>> - add PHY_ROCKCHIP_DPHY as a dependency for VIDEO_ROCKCHIP_ISP1
>> - Fix compilation and runtime errors due to bitrotting
>> The code has bit-rotten since March 2018, fix compilation errors.
>> The new V4L2 async notifier API requires notifiers to be initialized by
>> a call to v4l2_async_notifier_init() before being used, do so.
>> - Add missing module device table
>> - use clk_bulk framework
>> - add missing notifiers cleanups
>> - s/strlcpy/strscpy
>> - normalize bus_info name
>> - fix s_stream error path, stream_cnt wans't being decremented properly
>> - use devm_platform_ioremap_resource() helper
>> - s/deice/device
>> - redesign: remove mipi/csi subdevice, sensors connect directly to the
>> isp subdevice in the media topology now.
>> - remove "saved_state" member from rkisp1_stream struct
>> - Reverse the order of MIs
>> - Simplify MI interrupt handling
>> Rather than adding unnecessary indirection, just use stream index to
>> handle MI interrupt enable/disable/clear, since the stream index matches
>> the order of bits now, thanks to previous patch. While at it, remove
>> some dead code.
>> - code styling and checkpatch fixes
>>
>> drivers/media/platform/Kconfig | 12 +
>> drivers/media/platform/Makefile | 1 +
>> drivers/media/platform/rockchip/isp1/Makefile | 7 +
>> drivers/media/platform/rockchip/isp1/common.h | 101 +++
>> drivers/media/platform/rockchip/isp1/dev.c | 675 ++++++++++++++++++
>> drivers/media/platform/rockchip/isp1/dev.h | 97 +++
>> 6 files changed, 893 insertions(+)
>> create mode 100644 drivers/media/platform/rockchip/isp1/Makefile
>> create mode 100644 drivers/media/platform/rockchip/isp1/common.h
>> create mode 100644 drivers/media/platform/rockchip/isp1/dev.c
>> create mode 100644 drivers/media/platform/rockchip/isp1/dev.h
>>
>> diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
>> index 89555f9a813f..e0e98937c565 100644
>> --- a/drivers/media/platform/Kconfig
>> +++ b/drivers/media/platform/Kconfig
>> @@ -106,6 +106,18 @@ config VIDEO_QCOM_CAMSS
>> select VIDEOBUF2_DMA_SG
>> select V4L2_FWNODE
>>
>> +config VIDEO_ROCKCHIP_ISP1
>> + tristate "Rockchip Image Signal Processing v1 Unit driver"
>> + depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
>> + depends on ARCH_ROCKCHIP || COMPILE_TEST
>> + select VIDEOBUF2_DMA_CONTIG
>> + select VIDEOBUF2_VMALLOC
>> + select V4L2_FWNODE
>> + select PHY_ROCKCHIP_DPHY
>> + default n
>> + ---help---
>> + Support for ISP1 on the rockchip SoC.
>> +
>> config VIDEO_S3C_CAMIF
>> tristate "Samsung S3C24XX/S3C64XX SoC Camera Interface driver"
>> depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
>> diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
>> index 7cbbd925124c..f9fcf8e7c513 100644
>> --- a/drivers/media/platform/Makefile
>> +++ b/drivers/media/platform/Makefile
>> @@ -69,6 +69,7 @@ obj-$(CONFIG_VIDEO_RENESAS_FDP1) += rcar_fdp1.o
>> obj-$(CONFIG_VIDEO_RENESAS_JPU) += rcar_jpu.o
>> obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1/
>>
>> +obj-$(CONFIG_VIDEO_ROCKCHIP_ISP1) += rockchip/isp1/
>> obj-$(CONFIG_VIDEO_ROCKCHIP_RGA) += rockchip/rga/
>>
>> obj-y += omap/
>> diff --git a/drivers/media/platform/rockchip/isp1/Makefile b/drivers/media/platform/rockchip/isp1/Makefile
>> new file mode 100644
>> index 000000000000..72706e80fc8b
>> --- /dev/null
>> +++ b/drivers/media/platform/rockchip/isp1/Makefile
>> @@ -0,0 +1,7 @@
>> +obj-$(CONFIG_VIDEO_ROCKCHIP_ISP1) += rockchip-isp1.o
>> +rockchip-isp1-objs += rkisp1.o \
>> + dev.o \
>> + regs.o \
>> + isp_stats.o \
>> + isp_params.o \
>> + capture.o
>> diff --git a/drivers/media/platform/rockchip/isp1/common.h b/drivers/media/platform/rockchip/isp1/common.h
>> new file mode 100644
>> index 000000000000..606ce2793546
>> --- /dev/null
>> +++ b/drivers/media/platform/rockchip/isp1/common.h
>> @@ -0,0 +1,101 @@
>> +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
>> +/*
>> + * Rockchip isp1 driver
>> + *
>> + * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
>> + */
>> +
>> +#ifndef _RKISP1_COMMON_H
>> +#define _RKISP1_COMMON_H
>> +
>> +#include <linux/mutex.h>
>> +#include <media/media-device.h>
>> +#include <media/media-entity.h>
>> +#include <media/v4l2-ctrls.h>
>> +#include <media/v4l2-device.h>
>> +#include <media/videobuf2-v4l2.h>
>> +
>> +#define RKISP1_DEFAULT_WIDTH 800
>> +#define RKISP1_DEFAULT_HEIGHT 600
>> +
>> +#define RKISP1_MAX_STREAM 2
>> +#define RKISP1_STREAM_MP 0
>> +#define RKISP1_STREAM_SP 1
>> +
>> +#define RKISP1_PLANE_Y 0
>> +#define RKISP1_PLANE_CB 1
>> +#define RKISP1_PLANE_CR 2
>> +
>> +enum rkisp1_sd_type {
>> + RKISP1_SD_SENSOR,
>> + RKISP1_SD_PHY_CSI,
>> + RKISP1_SD_VCM,
>> + RKISP1_SD_FLASH,
>> + RKISP1_SD_MAX,
>> +};
>
> I wonder if this is a leftover from the driver development time. Same goes
> for the subdevs field in struct rkisp1_device.
It is a left over, I'm removing them for the next version, thanks.
>
>> +
>> +/* One structure per video node */
>> +struct rkisp1_vdev_node {
>> + struct vb2_queue buf_queue;
>> + /* vfd lock */
>> + struct mutex vlock;
>> + struct video_device vdev;
>> + struct media_pad pad;
>> +};
>> +
>> +enum rkisp1_fmt_pix_type {
>> + FMT_YUV,
>> + FMT_RGB,
>> + FMT_BAYER,
>> + FMT_JPEG,
>> + FMT_MAX
>> +};
>> +
>> +enum rkisp1_fmt_raw_pat_type {
>> + RAW_RGGB = 0,
>> + RAW_GRBG,
>> + RAW_GBRG,
>> + RAW_BGGR,
>> +};
>> +
>> +struct rkisp1_buffer {
>> + struct vb2_v4l2_buffer vb;
>> + struct list_head queue;
>> + union {
>> + u32 buff_addr[VIDEO_MAX_PLANES];
>> + void *vaddr[VIDEO_MAX_PLANES];
>> + };
>> +};
>> +
>> +struct rkisp1_dummy_buffer {
>> + void *vaddr;
>> + dma_addr_t dma_addr;
>> + u32 size;
>> +};
>> +
>> +extern int rkisp1_debug;
>> +
>> +static inline
>> +struct rkisp1_vdev_node *vdev_to_node(struct video_device *vdev)
>> +{
>> + return container_of(vdev, struct rkisp1_vdev_node, vdev);
>> +}
>> +
>> +static inline struct rkisp1_vdev_node *queue_to_node(struct vb2_queue *q)
>> +{
>> + return container_of(q, struct rkisp1_vdev_node, buf_queue);
>> +}
>> +
>> +static inline struct rkisp1_buffer *to_rkisp1_buffer(struct vb2_v4l2_buffer *vb)
>> +{
>> + return container_of(vb, struct rkisp1_buffer, vb);
>> +}
>> +
>> +static inline struct vb2_queue *to_vb2_queue(struct file *file)
>> +{
>> + struct rkisp1_vdev_node *vnode = video_drvdata(file);
>> +
>> + return &vnode->buf_queue;
>> +}
>> +
>> +#endif /* _RKISP1_COMMON_H */
>> diff --git a/drivers/media/platform/rockchip/isp1/dev.c b/drivers/media/platform/rockchip/isp1/dev.c
>> new file mode 100644
>> index 000000000000..2b4a67e1a3b5
>> --- /dev/null
>> +++ b/drivers/media/platform/rockchip/isp1/dev.c
>> @@ -0,0 +1,675 @@
>> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>> +/*
>> + * Rockchip isp1 driver
>> + *
>> + * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/of_graph.h>
>> +#include <linux/of_platform.h>
>> +#include <linux/pm_runtime.h>
>> +#include <linux/pinctrl/consumer.h>
>> +#include <linux/phy/phy.h>
>> +#include <linux/phy/phy-mipi-dphy.h>
>> +
>> +#include "common.h"
>> +#include "regs.h"
>> +
>> +struct isp_match_data {
>> + const char * const *clks;
>> + int size;
>
> unsigned int
ack
>
>> +};
>> +
>> +struct sensor_async_subdev {
>> + struct v4l2_async_subdev asd;
>> + struct v4l2_mbus_config mbus;
>> + unsigned int lanes;
>> +};
>> +
>> +int rkisp1_debug;
>> +module_param_named(debug, rkisp1_debug, int, 0644);
>> +MODULE_PARM_DESC(debug, "Debug level (0-1)");
>
> Have you thought of using dynamic debug instead?
right, this is being used in v4l2_dbg(), which I can replace by dev_dbg()
that is already covered by dynamic debug iirc.
Should I also replace v4l2_err() by dev_err() (I always get confused by
which log function I should use).
>
>> +
>> +/**************************** pipeline operations******************************/
>> +
>> +static int __isp_pipeline_prepare(struct rkisp1_pipeline *p,
>> + struct media_entity *me)
>> +{
>> + struct rkisp1_device *dev = container_of(p, struct rkisp1_device, pipe);
>> + struct v4l2_subdev *sd;
>> + unsigned int i;
>> +
>> + p->num_subdevs = 0;
>> + memset(p->subdevs, 0, sizeof(p->subdevs));
>> +
>> + while (1) {
>> + struct media_pad *pad = NULL;
>> +
>> + /* Find remote source pad */
>> + for (i = 0; i < me->num_pads; i++) {
>> + struct media_pad *spad = &me->pads[i];
>> +
>> + if (!(spad->flags & MEDIA_PAD_FL_SINK))
>> + continue;
>> + pad = media_entity_remote_pad(spad);
>> + if (pad)
>> + break;
>> + }
>> +
>> + if (!pad)
>> + break;
>> +
>> + sd = media_entity_to_v4l2_subdev(pad->entity);
>> + if (sd != &dev->isp_sdev.sd)
>> + p->subdevs[p->num_subdevs++] = sd;
>
> How do you make sure you don't overrun the array?
Because the maximum path the topology can have is:
sensor->rkisp->capture
>
> Instead, I'd avoid maintaining the array in the first place --- the same
> information is available from the MC framework data structures --- see e.g.
> the omap3isp driver.
If I understand correctly, omap3isp navigates through the topology in the same way,
but it just don't save in an array, but I reuse this information in other places,
mostly for power up/down (see below why I don't use v4l2_pipeline_pm_use())
>
>> +
>> + me = &sd->entity;
>> + if (me->num_pads == 1)
>> + break;
>> + }
>> + return 0;
>> +}
>> +
>> +static int __subdev_set_power(struct v4l2_subdev *sd, int on)
>> +{
>> + int ret;
>> +
>> + if (!sd)
>> + return -ENXIO;
>> +
>> + ret = v4l2_subdev_call(sd, core, s_power, on);
>> +
>> + return ret != -ENOIOCTLCMD ? ret : 0;
>> +}
>> +
>> +static int __isp_pipeline_s_power(struct rkisp1_pipeline *p, bool on)
>
> Could you instead use v4l2_pipeline_pm_use()?
Unless I misunderstood this (which is very likely), v4l2_pipeline_pm_use() calls pipeline_pm_power(),
that applies power change to all entities in a pipeline, but if I have two sensors
connected to the ISP, one with link enabled and the other with a disabled link,
I don't want to power both sensors on, just the one participating in that stream. And
if I call v4l2_pipeline_pm_use() it will power on both, which is not what I want.
Does it make sense?
>
>> +{
>> + struct rkisp1_device *dev = container_of(p, struct rkisp1_device, pipe);
>> + int i, ret;
>> +
>> + if (on) {
>> + __subdev_set_power(&dev->isp_sdev.sd, true);
>> +
>> + for (i = p->num_subdevs - 1; i >= 0; --i) {
>> + ret = __subdev_set_power(p->subdevs[i], true);
>> + if (ret < 0 && ret != -ENXIO)
>> + goto err_power_off;
>> + }
>> + } else {
>> + for (i = 0; i < p->num_subdevs; ++i)
>> + __subdev_set_power(p->subdevs[i], false);
>> +
>> + __subdev_set_power(&dev->isp_sdev.sd, false);
>> + }
>> +
>> + return 0;
>> +
>> +err_power_off:
>> + for (++i; i < p->num_subdevs; ++i)
>> + __subdev_set_power(p->subdevs[i], false);
>> + __subdev_set_power(&dev->isp_sdev.sd, true);
>> + return ret;
>> +}
>> +
>> +static int rkisp1_pipeline_open(struct rkisp1_pipeline *p,
>> + struct media_entity *me,
>> + bool prepare)
>> +{
>> + int ret;
>> +
>> + if (WARN_ON(!p || !me))
>> + return -EINVAL;
>> + if (atomic_inc_return(&p->power_cnt) > 1)
>> + return 0;
>> +
>> + /* go through media graphic and get subdevs */
>> + if (prepare)
>> + __isp_pipeline_prepare(p, me);
>> +
>> + if (!p->num_subdevs)
>> + return -EINVAL;
>> +
>> + ret = __isp_pipeline_s_power(p, 1);
>> + if (ret < 0)
>> + return ret;
>> +
>> + return 0;
>> +}
>> +
>> +static int rkisp1_pipeline_close(struct rkisp1_pipeline *p)
>> +{
>> + int ret;
>> +
>> + if (atomic_dec_return(&p->power_cnt) > 0)
>> + return 0;
>> + ret = __isp_pipeline_s_power(p, 0);
>> +
>> + return ret == -ENXIO ? 0 : ret;
>> +}
>> +
>> +/*
>> + * stream-on order: isp_subdev, mipi dphy, sensor
>> + * stream-off order: mipi dphy, sensor, isp_subdev
>> + */
>> +static int rkisp1_pipeline_set_stream(struct rkisp1_pipeline *p, bool on)
>> +{
>> + struct rkisp1_device *dev = container_of(p, struct rkisp1_device, pipe);
>> + int i, ret;
>> +
>> + if ((on && atomic_inc_return(&p->stream_cnt) > 1) ||
>> + (!on && atomic_dec_return(&p->stream_cnt) > 0))
>> + return 0;
>> +
>> + if (on) {
>> + ret = v4l2_subdev_call(&dev->isp_sdev.sd, video, s_stream,
>> + true);
>> + if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
>> + v4l2_err(&dev->v4l2_dev,
>> + "s_stream failed on subdevice %s (%d)\n",
>> + dev->isp_sdev.sd.name,
>> + ret);
>> + atomic_dec(&p->stream_cnt);
>> + return ret;
>> + }
>> + }
>> +
>> + /* phy -> sensor */
>> + for (i = 0; i < p->num_subdevs; ++i) {
>> + ret = v4l2_subdev_call(p->subdevs[i], video, s_stream, on);
>> + if (on && ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
>> + goto err_stream_off;
>
> You should stop after the first external sub-device.
>
> It seems even the omap3isp driver doesn't do that. It's not easy to spot
> such issues indeed.
I'm not sure I understand, what do you call an external sub-device? Is the sensor
an external subdevice?
>
>> + }
>> +
>> + if (!on)
>> + v4l2_subdev_call(&dev->isp_sdev.sd, video, s_stream, false);
>> +
>> + return 0;
>> +
>> +err_stream_off:
>> + for (--i; i >= 0; --i)
>> + v4l2_subdev_call(p->subdevs[i], video, s_stream, false);
>> + v4l2_subdev_call(&dev->isp_sdev.sd, video, s_stream, false);
>> + atomic_dec(&p->stream_cnt);
>> + return ret;
>> +}
>> +
>> +/***************************** media controller *******************************/
>> +/* See http://opensource.rock-chips.com/wiki_Rockchip-isp1 for Topology */
>
> The host appears to be down, or there's a routing problem. Unless this is
> fixed, having such a URL here doesn't do much good. :-I
This is a left over, sorry about that.
I can access the URL now. I'll try to get some of the docs and move to the kernel docs.
>
>> +
>> +static int rkisp1_create_links(struct rkisp1_device *dev)
>> +{
>> + struct media_entity *source, *sink;
>> + struct rkisp1_sensor *sensor;
>> + unsigned int flags, pad;
>> + int ret;
>> +
>> + /* sensor links(or mipi-phy) */
>> + list_for_each_entry(sensor, &dev->sensors, list) {
>> + for (pad = 0; pad < sensor->sd->entity.num_pads; pad++)
>> + if (sensor->sd->entity.pads[pad].flags &
>> + MEDIA_PAD_FL_SOURCE)
>> + break;
>
> Could you use media_entity_get_fwnode_pad() instead?
Yes, I didn't know about it actually, thanks for that, looks cleaner (I'll send in
the next version).
>
>> +
>> + if (pad == sensor->sd->entity.num_pads) {
>> + dev_err(dev->dev,
>> + "failed to find src pad for %s\n",
>> + sensor->sd->name);
>> +
>> + return -ENXIO;
>> + }
>> +
>> + ret = media_create_pad_link(
>> + &sensor->sd->entity, pad,
>> + &dev->isp_sdev.sd.entity,
>> + RKISP1_ISP_PAD_SINK,
>> + list_is_first(&sensor->list, &dev->sensors) ?
>> + MEDIA_LNK_FL_ENABLED : 0);
>> + if (ret) {
>> + dev_err(dev->dev,
>> + "failed to create link for %s\n",
>> + sensor->sd->name);
>> + return ret;
>> + }
>> + }
>> +
>> + /* params links */
>> + source = &dev->params_vdev.vnode.vdev.entity;
>> + sink = &dev->isp_sdev.sd.entity;
>> + flags = MEDIA_LNK_FL_ENABLED;
>> + ret = media_create_pad_link(source, 0, sink,
>> + RKISP1_ISP_PAD_SINK_PARAMS, flags);
>> + if (ret < 0)
>> + return ret;
>> +
>> + /* create isp internal links */
>> + /* SP links */
>> + source = &dev->isp_sdev.sd.entity;
>> + sink = &dev->stream[RKISP1_STREAM_SP].vnode.vdev.entity;
>> + ret = media_create_pad_link(source, RKISP1_ISP_PAD_SOURCE_PATH,
>> + sink, 0, flags);
>> + if (ret < 0)
>> + return ret;
>> +
>> + /* MP links */
>> + source = &dev->isp_sdev.sd.entity;
>> + sink = &dev->stream[RKISP1_STREAM_MP].vnode.vdev.entity;
>> + ret = media_create_pad_link(source, RKISP1_ISP_PAD_SOURCE_PATH,
>> + sink, 0, flags);
>> + if (ret < 0)
>> + return ret;
>> +
>> + /* 3A stats links */
>> + source = &dev->isp_sdev.sd.entity;
>> + sink = &dev->stats_vdev.vnode.vdev.entity;
>> + return media_create_pad_link(source, RKISP1_ISP_PAD_SOURCE_STATS,
>> + sink, 0, flags);
>
> Indentation. Same for the calls to the same function above.
ack
>
>> +}
>> +
>> +static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
>> + struct v4l2_subdev *sd,
>> + struct v4l2_async_subdev *asd)
>> +{
>> + struct rkisp1_device *isp_dev = container_of(notifier,
>> + struct rkisp1_device,
>> + notifier);
>> + struct sensor_async_subdev *s_asd = container_of(asd,
>> + struct sensor_async_subdev, asd);
>> + struct rkisp1_sensor *sensor;
>> +
>> + sensor = devm_kzalloc(isp_dev->dev, sizeof(*sensor), GFP_KERNEL);
>> + if (!sensor)
>> + return -ENOMEM;
>> +
>> + sensor->lanes = s_asd->lanes;
>> + sensor->mbus = s_asd->mbus;
>> + sensor->sd = sd;
>> + sensor->dphy = devm_phy_get(isp_dev->dev, "dphy");
>> + if (IS_ERR(sensor->dphy)) {
>> + if (PTR_ERR(sensor->dphy) != -EPROBE_DEFER)
>> + dev_err(isp_dev->dev, "Couldn't get the MIPI D-PHY\n");
>> + return PTR_ERR(sensor->dphy);
>> + }
>> + phy_init(sensor->dphy);
>> +
>> + list_add(&sensor->list, &isp_dev->sensors);
>
> In general, maintaining the information on the external subdevs on your own
> adds complexity to the driver. You can get the information when you need it
> from the data structures maintained by MC (see e.g. the omap3isp driver for
> examples).
>
>> +
>> + return 0;
>> +}
>> +
>> +static struct rkisp1_sensor *sd_to_sensor(struct rkisp1_device *dev,
>> + struct v4l2_subdev *sd)
>> +{
>> + struct rkisp1_sensor *sensor;
>> +
>> + list_for_each_entry(sensor, &dev->sensors, list)
>> + if (sensor->sd == sd)
>> + return sensor;
>> +
>> + return NULL;
>> +}
>> +
>> +static void subdev_notifier_unbind(struct v4l2_async_notifier *notifier,
>> + struct v4l2_subdev *sd,
>> + struct v4l2_async_subdev *asd)
>> +{
>> + struct rkisp1_device *isp_dev = container_of(notifier,
>> + struct rkisp1_device,
>> + notifier);
>> + struct rkisp1_sensor *sensor = sd_to_sensor(isp_dev, sd);
>> +
>> + /* TODO: check if a lock is required here */
>> + list_del(&sensor->list);
>> +
>> + phy_exit(sensor->dphy);
>> +}
>> +
>> +static int subdev_notifier_complete(struct v4l2_async_notifier *notifier)
>> +{
>> + struct rkisp1_device *dev = container_of(notifier, struct rkisp1_device,
>> + notifier);
>> + int ret;
>> +
>> + mutex_lock(&dev->media_dev.graph_mutex);
>> + ret = rkisp1_create_links(dev);
>> + if (ret < 0)
>> + goto unlock;
>> + ret = v4l2_device_register_subdev_nodes(&dev->v4l2_dev);
>> + if (ret < 0)
>> + goto unlock;
>> +
>> + v4l2_info(&dev->v4l2_dev, "Async subdev notifier completed\n");
>> +
>> +unlock:
>> + mutex_unlock(&dev->media_dev.graph_mutex);
>> + return ret;
>> +}
>> +
>> +static int rkisp1_fwnode_parse(struct device *dev,
>> + struct v4l2_fwnode_endpoint *vep,
>> + struct v4l2_async_subdev *asd)
>> +{
>> + struct sensor_async_subdev *s_asd =
>> + container_of(asd, struct sensor_async_subdev, asd);
>> +
>> + if (vep->bus_type != V4L2_MBUS_CSI2_DPHY) {
>> + dev_err(dev, "Only CSI2 bus type is currently supported\n");
>> + return -EINVAL;
>> + }
>> +
>> + if (vep->base.port != 0) {
>> + dev_err(dev, "The ISP has only port 0\n");
>> + return -EINVAL;
>> + }
>> +
>> + s_asd->mbus.type = vep->bus_type;
>> + s_asd->mbus.flags = vep->bus.mipi_csi2.flags;
>> + s_asd->lanes = vep->bus.mipi_csi2.num_data_lanes;
>> +
>> + switch (vep->bus.mipi_csi2.num_data_lanes) {
>> + case 1:
>> + s_asd->mbus.flags |= V4L2_MBUS_CSI2_1_LANE;
>> + break;
>> + case 2:
>> + s_asd->mbus.flags |= V4L2_MBUS_CSI2_2_LANE;
>> + break;
>> + case 3:
>> + s_asd->mbus.flags |= V4L2_MBUS_CSI2_3_LANE;
>> + break;
>> + case 4:
>> + s_asd->mbus.flags |= V4L2_MBUS_CSI2_4_LANE;
>> + break;
>> + default:
>> + return -EINVAL;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static const struct v4l2_async_notifier_operations subdev_notifier_ops = {
>> + .bound = subdev_notifier_bound,
>> + .unbind = subdev_notifier_unbind,
>> + .complete = subdev_notifier_complete,
>> +};
>> +
>> +static int isp_subdev_notifier(struct rkisp1_device *isp_dev)
>> +{
>> + struct v4l2_async_notifier *ntf = &isp_dev->notifier;
>> + struct device *dev = isp_dev->dev;
>> + int ret;
>> +
>> + v4l2_async_notifier_init(ntf);
>> +
>> + ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(
>> + dev, ntf, sizeof(struct sensor_async_subdev), 0,
>> + rkisp1_fwnode_parse);
>> + if (ret < 0)
>> + return ret;
>> +
>> + if (list_empty(&ntf->asd_list))
>> + return -ENODEV; /* no endpoint */
>> +
>> + ntf->ops = &subdev_notifier_ops;
>> +
>> + return v4l2_async_notifier_register(&isp_dev->v4l2_dev, ntf);
>> +}
>> +
>> +/***************************** platform device *******************************/
>> +
>> +static int rkisp1_register_platform_subdevs(struct rkisp1_device *dev)
>> +{
>> + int ret;
>> +
>> + ret = rkisp1_register_isp_subdev(dev, &dev->v4l2_dev);
>> + if (ret < 0)
>> + return ret;
>> +
>> + ret = rkisp1_register_stream_vdevs(dev);
>> + if (ret < 0)
>> + goto err_unreg_isp_subdev;
>> +
>> + ret = rkisp1_register_stats_vdev(&dev->stats_vdev, &dev->v4l2_dev, dev);
>> + if (ret < 0)
>> + goto err_unreg_stream_vdev;
>> +
>> + ret = rkisp1_register_params_vdev(&dev->params_vdev, &dev->v4l2_dev,
>> + dev);
>> + if (ret < 0)
>> + goto err_unreg_stats_vdev;
>> +
>> + ret = isp_subdev_notifier(dev);
>> + if (ret < 0) {
>> + v4l2_err(&dev->v4l2_dev,
>> + "Failed to register subdev notifier(%d)\n", ret);
>> + goto err_unreg_params_vdev;
>> + }
>> +
>> + return 0;
>> +err_unreg_params_vdev:
>> + rkisp1_unregister_params_vdev(&dev->params_vdev);
>> +err_unreg_stats_vdev:
>> + rkisp1_unregister_stats_vdev(&dev->stats_vdev);
>> +err_unreg_stream_vdev:
>> + rkisp1_unregister_stream_vdevs(dev);
>> +err_unreg_isp_subdev:
>> + rkisp1_unregister_isp_subdev(dev);
>> + return ret;
>> +}
>> +
>> +static const char * const rk3399_isp_clks[] = {
>> + "clk_isp",
>> + "aclk_isp",
>> + "hclk_isp",
>> + "aclk_isp_wrap",
>> + "hclk_isp_wrap",
>> +};
>> +
>> +static const char * const rk3288_isp_clks[] = {
>> + "clk_isp",
>> + "aclk_isp",
>> + "hclk_isp",
>> + "pclk_isp_in",
>> + "sclk_isp_jpe",
>> +};
>> +
>> +static const struct isp_match_data rk3288_isp_clk_data = {
>> + .clks = rk3288_isp_clks,
>> + .size = ARRAY_SIZE(rk3288_isp_clks),
>> +};
>> +
>> +static const struct isp_match_data rk3399_isp_clk_data = {
>> + .clks = rk3399_isp_clks,
>> + .size = ARRAY_SIZE(rk3399_isp_clks),
>> +};
>> +
>> +static const struct of_device_id rkisp1_plat_of_match[] = {
>> + {
>> + .compatible = "rockchip,rk3288-cif-isp",
>> + .data = &rk3288_isp_clk_data,
>> + }, {
>> + .compatible = "rockchip,rk3399-cif-isp",
>> + .data = &rk3399_isp_clk_data,
>> + },
>> + {},
>> +};
>> +MODULE_DEVICE_TABLE(of, rkisp1_plat_of_match);
>> +
>> +static irqreturn_t rkisp1_irq_handler(int irq, void *ctx)
>> +{
>> + struct device *dev = ctx;
>> + struct rkisp1_device *rkisp1_dev = dev_get_drvdata(dev);
>> + unsigned int mis_val;
>> +
>> + mis_val = readl(rkisp1_dev->base_addr + CIF_ISP_MIS);
>> + if (mis_val)
>> + rkisp1_isp_isr(mis_val, rkisp1_dev);
>> +
>> + mis_val = readl(rkisp1_dev->base_addr + CIF_MIPI_MIS);
>> + if (mis_val)
>> + rkisp1_mipi_isr(mis_val, rkisp1_dev);
>> +
>> + mis_val = readl(rkisp1_dev->base_addr + CIF_MI_MIS);
>> + if (mis_val)
>> + rkisp1_mi_isr(mis_val, rkisp1_dev);
>> +
>> + return IRQ_HANDLED;
>> +}
>> +
>> +static int rkisp1_plat_probe(struct platform_device *pdev)
>> +{
>> + struct device_node *node = pdev->dev.of_node;
>> + const struct isp_match_data *clk_data;
>> + const struct of_device_id *match;
>> + struct device *dev = &pdev->dev;
>> + struct rkisp1_device *isp_dev;
>> + struct v4l2_device *v4l2_dev;
>> + unsigned int i;
>> + int ret, irq;
>> +
>> + match = of_match_node(rkisp1_plat_of_match, node);
>> + isp_dev = devm_kzalloc(dev, sizeof(*isp_dev), GFP_KERNEL);
>> + if (!isp_dev)
>> + return -ENOMEM;
>> +
>> + INIT_LIST_HEAD(&isp_dev->sensors);
>> +
>> + dev_set_drvdata(dev, isp_dev);
>> + isp_dev->dev = dev;
>> +
>> + isp_dev->base_addr = devm_platform_ioremap_resource(pdev, 0);
>> + if (IS_ERR(isp_dev->base_addr))
>> + return PTR_ERR(isp_dev->base_addr);
>> +
>> + irq = platform_get_irq(pdev, 0);
>> + if (irq < 0)
>> + return irq;
>> +
>> + ret = devm_request_irq(dev, irq, rkisp1_irq_handler, IRQF_SHARED,
>> + dev_driver_string(dev), dev);
>> + if (ret < 0) {
>> + dev_err(dev, "request irq failed: %d\n", ret);
>> + return ret;
>> + }
>> +
>> + isp_dev->irq = irq;
>> + clk_data = match->data;
>> +
>> + for (i = 0; i < clk_data->size; i++)
>> + isp_dev->clks[i].id = clk_data->clks[i];
>> + ret = devm_clk_bulk_get(dev, clk_data->size, isp_dev->clks);
>> + if (ret)
>> + return ret;
>> + isp_dev->clk_size = clk_data->size;
>> +
>> + atomic_set(&isp_dev->pipe.power_cnt, 0);
>> + atomic_set(&isp_dev->pipe.stream_cnt, 0);
>> + isp_dev->pipe.open = rkisp1_pipeline_open;
>> + isp_dev->pipe.close = rkisp1_pipeline_close;
>> + isp_dev->pipe.set_stream = rkisp1_pipeline_set_stream;
>> +
>> + rkisp1_stream_init(isp_dev, RKISP1_STREAM_SP);
>> + rkisp1_stream_init(isp_dev, RKISP1_STREAM_MP);
>> +
>> + strscpy(isp_dev->media_dev.model, "rkisp1",
>> + sizeof(isp_dev->media_dev.model));
>> + isp_dev->media_dev.dev = &pdev->dev;
>> + strscpy(isp_dev->media_dev.bus_info,
>> + "platform: " DRIVER_NAME, sizeof(isp_dev->media_dev.bus_info));
>> + media_device_init(&isp_dev->media_dev);
>> +
>> + v4l2_dev = &isp_dev->v4l2_dev;
>> + v4l2_dev->mdev = &isp_dev->media_dev;
>> + strscpy(v4l2_dev->name, "rkisp1", sizeof(v4l2_dev->name));
>> + v4l2_ctrl_handler_init(&isp_dev->ctrl_handler, 5);
>> + v4l2_dev->ctrl_handler = &isp_dev->ctrl_handler;
>> +
>> + ret = v4l2_device_register(isp_dev->dev, &isp_dev->v4l2_dev);
>> + if (ret < 0)
>
> Once you've initialised the control handler, you'll need to free it in case
> of an error. I.e. add one more label for that purpose near the end.
control handler is not required, I'll remove it for the next version.
>
>> + return ret;
>> +
>> + ret = media_device_register(&isp_dev->media_dev);
>> + if (ret < 0) {
>> + v4l2_err(v4l2_dev, "Failed to register media device: %d\n",
>> + ret);
>> + goto err_unreg_v4l2_dev;
>> + }
>> +
>> + /* create & register platefom subdev (from of_node) */
>> + ret = rkisp1_register_platform_subdevs(isp_dev);
>> + if (ret < 0)
>> + goto err_unreg_media_dev;
>> +
>> + pm_runtime_enable(&pdev->dev);
>> +
>> + return 0;
>> +
>> +err_unreg_media_dev:
>> + media_device_unregister(&isp_dev->media_dev);
>> +err_unreg_v4l2_dev:
>> + v4l2_device_unregister(&isp_dev->v4l2_dev);
>> + return ret;
>> +}
>> +
>> +static int rkisp1_plat_remove(struct platform_device *pdev)
>> +{
>> + struct rkisp1_device *isp_dev = platform_get_drvdata(pdev);
>> +
>> + pm_runtime_disable(&pdev->dev);
>> + media_device_unregister(&isp_dev->media_dev);
>> + v4l2_async_notifier_unregister(&isp_dev->notifier);
>> + v4l2_async_notifier_cleanup(&isp_dev->notifier);
>> + v4l2_device_unregister(&isp_dev->v4l2_dev);
>> + rkisp1_unregister_params_vdev(&isp_dev->params_vdev);
>> + rkisp1_unregister_stats_vdev(&isp_dev->stats_vdev);
>> + rkisp1_unregister_stream_vdevs(isp_dev);
>> + rkisp1_unregister_isp_subdev(isp_dev);
>> +
>> + return 0;
>> +}
>> +
>> +static int __maybe_unused rkisp1_runtime_suspend(struct device *dev)
>> +{
>> + struct rkisp1_device *isp_dev = dev_get_drvdata(dev);
>> +
>> + clk_bulk_disable_unprepare(isp_dev->clk_size, isp_dev->clks);
>> + return pinctrl_pm_select_sleep_state(dev);
>> +}
>> +
>> +static int __maybe_unused rkisp1_runtime_resume(struct device *dev)
>> +{
>> + struct rkisp1_device *isp_dev = dev_get_drvdata(dev);
>> + int ret;
>> +
>> + ret = pinctrl_pm_select_default_state(dev);
>> + if (ret < 0)
>> + return ret;
>> + ret = clk_bulk_prepare_enable(isp_dev->clk_size, isp_dev->clks);
>> + if (ret < 0)
>> + return ret;
>> +
>> + return 0;
>> +}
>> +
>> +static const struct dev_pm_ops rkisp1_plat_pm_ops = {
>> + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
>> + pm_runtime_force_resume)
>> + SET_RUNTIME_PM_OPS(rkisp1_runtime_suspend, rkisp1_runtime_resume, NULL)
>> +};
>> +
>> +static struct platform_driver rkisp1_plat_drv = {
>> + .driver = {
>> + .name = DRIVER_NAME,
>> + .of_match_table = of_match_ptr(rkisp1_plat_of_match),
>> + .pm = &rkisp1_plat_pm_ops,
>> + },
>> + .probe = rkisp1_plat_probe,
>> + .remove = rkisp1_plat_remove,
>> +};
>> +
>> +module_platform_driver(rkisp1_plat_drv);
>> +MODULE_AUTHOR("Rockchip Camera/ISP team");
>> +MODULE_DESCRIPTION("Rockchip ISP1 platform driver");
>> +MODULE_LICENSE("Dual BSD/GPL");
>
> BSD or MIT?
Thanks for spotting this, I'll verify.
>
>> diff --git a/drivers/media/platform/rockchip/isp1/dev.h b/drivers/media/platform/rockchip/isp1/dev.h
>> new file mode 100644
>> index 000000000000..f7cbee316523
>> --- /dev/null
>> +++ b/drivers/media/platform/rockchip/isp1/dev.h
>> @@ -0,0 +1,97 @@
>> +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
>> +/*
>> + * Rockchip isp1 driver
>> + *
>> + * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
>> + */
>> +
>> +#ifndef _RKISP1_DEV_H
>> +#define _RKISP1_DEV_H
>> +
>> +#include <linux/clk.h>
>> +
>> +#include "capture.h"
>> +#include "rkisp1.h"
>> +#include "isp_params.h"
>> +#include "isp_stats.h"
>> +
>> +#define DRIVER_NAME "rkisp1"
>> +#define ISP_VDEV_NAME DRIVER_NAME "_ispdev"
>> +#define SP_VDEV_NAME DRIVER_NAME "_selfpath"
>> +#define MP_VDEV_NAME DRIVER_NAME "_mainpath"
>> +#define DMA_VDEV_NAME DRIVER_NAME "_dmapath"
>> +
>> +#define GRP_ID_SENSOR BIT(0)
>> +#define GRP_ID_MIPIPHY BIT(1)
>> +#define GRP_ID_ISP BIT(2)
>> +#define GRP_ID_ISP_MP BIT(3)
>> +#define GRP_ID_ISP_SP BIT(4)
>> +
>> +#define RKISP1_MAX_BUS_CLK 8
>> +#define RKISP1_MAX_SENSOR 2
>> +#define RKISP1_MAX_PIPELINE 4
>> +
>> +/*
>> + * struct rkisp1_pipeline - An ISP hardware pipeline
>> + *
>> + * Capture device call other devices via pipeline
>> + *
>> + * @num_subdevs: number of linked subdevs
>> + * @power_cnt: pipeline power count
>> + * @stream_cnt: stream power count
>> + */
>> +struct rkisp1_pipeline {
>> + struct media_pipeline pipe;
>> + int num_subdevs;
>> + atomic_t power_cnt;
>> + atomic_t stream_cnt;
>> + struct v4l2_subdev *subdevs[RKISP1_MAX_PIPELINE];
>> + int (*open)(struct rkisp1_pipeline *p,
>> + struct media_entity *me, bool prepare);
>> + int (*close)(struct rkisp1_pipeline *p);
>> + int (*set_stream)(struct rkisp1_pipeline *p, bool on);
>> +};
>> +
>> +/*
>> + * struct rkisp1_sensor - Sensor information
>> + * @mbus: media bus configuration
>> + */
>> +struct rkisp1_sensor {
>> + struct v4l2_subdev *sd;
>> + struct v4l2_mbus_config mbus;
>> + unsigned int lanes;
>> + struct phy *dphy;
>> + struct list_head list;
>> +};
>
> You seem to also have struct sensor_async_subdev that appears to contain
> similar information. Would it be possible to unify the two?
>
> This would appear to allow you getting rid of functions such as
> sd_to_sensor, for instance.
ack, I managed to get rid of this, and I don't even need to keep them
on a list, I'll submit in the next version.
Thanks a lot for your review
Helen
>
>> +
>> +/*
>> + * struct rkisp1_device - ISP platform device
>> + * @base_addr: base register address
>> + * @active_sensor: sensor in-use, set when streaming on
>> + * @isp_sdev: ISP sub-device
>> + * @rkisp1_stream: capture video device
>> + * @stats_vdev: ISP statistics output device
>> + * @params_vdev: ISP input parameters device
>> + */
>> +struct rkisp1_device {
>> + void __iomem *base_addr;
>> + int irq;
>> + struct device *dev;
>> + unsigned int clk_size;
>> + struct clk_bulk_data clks[RKISP1_MAX_BUS_CLK];
>> + struct v4l2_device v4l2_dev;
>> + struct v4l2_ctrl_handler ctrl_handler;
>> + struct media_device media_dev;
>> + struct v4l2_async_notifier notifier;
>> + struct v4l2_subdev *subdevs[RKISP1_SD_MAX];
>> + struct rkisp1_sensor *active_sensor;
>> + struct list_head sensors;
>> + struct rkisp1_isp_subdev isp_sdev;
>> + struct rkisp1_stream stream[RKISP1_MAX_STREAM];
>> + struct rkisp1_isp_stats_vdev stats_vdev;
>> + struct rkisp1_isp_params_vdev params_vdev;
>> + struct rkisp1_pipeline pipe;
>> + struct vb2_alloc_ctx *alloc_ctx;
>> +};
>> +
>> +#endif
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 22/22] ARM: omap1: enable multiplatform
From: Arnd Bergmann @ 2019-08-08 21:47 UTC (permalink / raw)
To: Tony Lindgren, Aaro Koskinen
Cc: Arnd Bergmann, Bartlomiej Zolnierkiewicz, Greg Kroah-Hartman,
Linus Walleij, linux-kernel, Tomi Valkeinen, linux-omap,
linux-arm-kernel
In-Reply-To: <20190808212234.2213262-1-arnd@arndb.de>
With all the header files out of the way, and the clock driver
converted to drivers/clk/, nothing stops us from building
OMAP together with the other platforms.
As usual, the decompressor support is a victim here, and is
only available when CONFIG_DEBUG_LL is configured for the
particular board.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
arch/arm/Kconfig | 18 ---
arch/arm/configs/omap1_defconfig | 3 +
arch/arm/mach-omap1/Kconfig | 20 ++-
arch/arm/mach-omap1/Makefile | 4 +
arch/arm/mach-omap1/hardware.h | 2 +-
arch/arm/mach-omap1/include/mach/uncompress.h | 117 ------------------
arch/arm/mach-omap1/serial.c | 3 +-
.../mach-omap1/{include/mach => }/serial.h | 0
arch/arm/plat-omap/Makefile | 1 +
9 files changed, 26 insertions(+), 142 deletions(-)
delete mode 100644 arch/arm/mach-omap1/include/mach/uncompress.h
rename arch/arm/mach-omap1/{include/mach => }/serial.h (100%)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 17a21f75f386..8542dfc5cf84 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -490,24 +490,6 @@ config ARCH_S3C24XX
(<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or the
Samsung SMDK2410 development board (and derivatives).
-config ARCH_OMAP1
- bool "TI OMAP1"
- select ARCH_HAS_HOLES_MEMORYMODEL
- select ARCH_OMAP
- select CLKDEV_LOOKUP
- select CLKSRC_MMIO
- select COMMON_CLK
- select FORCE_PCI if PCCARD
- select GENERIC_CLOCKEVENTS
- select GENERIC_IRQ_CHIP
- select GENERIC_IRQ_MULTI_HANDLER
- select GPIOLIB
- select HAVE_IDE
- select IRQ_DOMAIN
- select SPARSE_IRQ
- help
- Support for older TI OMAP1 (omap7xx, omap15xx or omap16xx)
-
endchoice
menu "Multiple platform selection"
diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig
index 0c43c589f191..902125f89315 100644
--- a/arch/arm/configs/omap1_defconfig
+++ b/arch/arm/configs/omap1_defconfig
@@ -20,6 +20,9 @@ CONFIG_MODULE_FORCE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_MULTI_V4T=y
+CONFIG_ARCH_MULTI_V5=y
+# CONFIG_ARCH_MULTI_V7 is not set
CONFIG_ARCH_OMAP=y
CONFIG_ARCH_OMAP1=y
CONFIG_OMAP_RESET_CLOCKS=y
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index 6a2c441ab579..5b1d3a24462f 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -1,4 +1,16 @@
# SPDX-License-Identifier: GPL-2.0-only
+menuconfig ARCH_OMAP1
+ bool "TI OMAP1"
+ depends on ARCH_MULTI_V4T || ARCH_MULTI_V5
+ select ARCH_HAS_HOLES_MEMORYMODEL
+ select ARCH_OMAP
+ select CLKSRC_MMIO
+ select FORCE_PCI if PCCARD
+ select GPIOLIB
+ select HAVE_IDE
+ help
+ Support for older TI OMAP1 (omap7xx, omap15xx or omap16xx)
+
if ARCH_OMAP1
menu "TI OMAP1 specific features"
@@ -14,27 +26,27 @@ config ARCH_OMAP1_AUTO
select MACH_OMAP_GENERIC if (ARCH_OMAP15XX || ARCH_OMAP16XX)
config ARCH_OMAP730
- depends on ARCH_OMAP1
+ depends on ARCH_MULTI_V5
bool "OMAP730 Based System"
select ARCH_OMAP_OTG
select CPU_ARM926T
select OMAP_MPU_TIMER
config ARCH_OMAP850
- depends on ARCH_OMAP1
+ depends on ARCH_MULTI_V5
bool "OMAP850 Based System"
select ARCH_OMAP_OTG
select CPU_ARM926T
config ARCH_OMAP15XX
- depends on ARCH_OMAP1
+ depends on ARCH_MULTI_V4T
default y
bool "OMAP15xx Based System"
select CPU_ARM925T
select OMAP_MPU_TIMER
config ARCH_OMAP16XX
- depends on ARCH_OMAP1
+ depends on ARCH_MULTI_V5
bool "OMAP16xx Based System"
select ARCH_OMAP_OTG
select CPU_ARM926T
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index 1337d7a2754c..1f0f97868953 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -3,6 +3,10 @@
# Makefile for the linux kernel.
#
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) += -I$(srctree)/arch/arm/mach-omap1/include
+asflags-$(CONFIG_ARCH_MULTIPLATFORM) += -I$(srctree)/arch/arm/mach-omap1/include
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) += -I$(srctree)/arch/arm/plat-omap/include
+
# Common support
obj-y := io.o id.o sram-init.o sram.o time.o irq.o mux.o flash.o \
serial.o devices.o dma.o fb.o
diff --git a/arch/arm/mach-omap1/hardware.h b/arch/arm/mach-omap1/hardware.h
index 2cfc342c069c..232b8deef907 100644
--- a/arch/arm/mach-omap1/hardware.h
+++ b/arch/arm/mach-omap1/hardware.h
@@ -64,7 +64,7 @@ static inline u32 omap_cs3_phys(void)
#define OMAP1_IO_OFFSET 0x01000000 /* Virtual IO = 0xfefb0000 */
#define OMAP1_IO_ADDRESS(pa) IOMEM((pa) - OMAP1_IO_OFFSET)
-#include <mach/serial.h>
+#include "serial.h"
/*
* ---------------------------------------------------------------------------
diff --git a/arch/arm/mach-omap1/include/mach/uncompress.h b/arch/arm/mach-omap1/include/mach/uncompress.h
deleted file mode 100644
index 9cca6a56788f..000000000000
--- a/arch/arm/mach-omap1/include/mach/uncompress.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/uncompress.h
- *
- * Serial port stubs for kernel decompress status messages
- *
- * Initially based on:
- * linux-2.4.15-rmk1-dsplinux1.6/arch/arm/plat-omap/include/mach1510/uncompress.h
- * Copyright (C) 2000 RidgeRun, Inc.
- * Author: Greg Lonnon <glonnon@ridgerun.com>
- *
- * Rewritten by:
- * Author: <source@mvista.com>
- * 2004 (c) MontaVista Software, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-#include <linux/types.h>
-#include <linux/serial_reg.h>
-
-#include <asm/memory.h>
-#include <asm/mach-types.h>
-
-#include "serial.h"
-
-#define MDR1_MODE_MASK 0x07
-
-volatile u8 *uart_base;
-int uart_shift;
-
-/*
- * Store the DEBUG_LL uart number into memory.
- * See also debug-macro.S, and serial.c for related code.
- */
-static void set_omap_uart_info(unsigned char port)
-{
- /*
- * Get address of some.bss variable and round it down
- * a la CONFIG_AUTO_ZRELADDR.
- */
- u32 ram_start = (u32)&uart_shift & 0xf8000000;
- u32 *uart_info = (u32 *)(ram_start + OMAP_UART_INFO_OFS);
- *uart_info = port;
-}
-
-static inline void putc(int c)
-{
- if (!uart_base)
- return;
-
- /* Check for UART 16x mode */
- if ((uart_base[UART_OMAP_MDR1 << uart_shift] & MDR1_MODE_MASK) != 0)
- return;
-
- while (!(uart_base[UART_LSR << uart_shift] & UART_LSR_THRE))
- barrier();
- uart_base[UART_TX << uart_shift] = c;
-}
-
-static inline void flush(void)
-{
-}
-
-/*
- * Macros to configure UART1 and debug UART
- */
-#define _DEBUG_LL_ENTRY(mach, dbg_uart, dbg_shft, dbg_id) \
- if (machine_is_##mach()) { \
- uart_base = (volatile u8 *)(dbg_uart); \
- uart_shift = (dbg_shft); \
- port = (dbg_id); \
- set_omap_uart_info(port); \
- break; \
- }
-
-#define DEBUG_LL_OMAP7XX(p, mach) \
- _DEBUG_LL_ENTRY(mach, OMAP1_UART##p##_BASE, OMAP7XX_PORT_SHIFT, \
- OMAP1UART##p)
-
-#define DEBUG_LL_OMAP1(p, mach) \
- _DEBUG_LL_ENTRY(mach, OMAP1_UART##p##_BASE, OMAP_PORT_SHIFT, \
- OMAP1UART##p)
-
-static inline void arch_decomp_setup(void)
-{
- int port = 0;
-
- /*
- * Initialize the port based on the machine ID from the bootloader.
- * Note that we're using macros here instead of switch statement
- * as machine_is functions are optimized out for the boards that
- * are not selected.
- */
- do {
- /* omap7xx/8xx based boards using UART1 with shift 0 */
- DEBUG_LL_OMAP7XX(1, herald);
- DEBUG_LL_OMAP7XX(1, omap_perseus2);
-
- /* omap15xx/16xx based boards using UART1 */
- DEBUG_LL_OMAP1(1, ams_delta);
- DEBUG_LL_OMAP1(1, nokia770);
- DEBUG_LL_OMAP1(1, omap_h2);
- DEBUG_LL_OMAP1(1, omap_h3);
- DEBUG_LL_OMAP1(1, omap_innovator);
- DEBUG_LL_OMAP1(1, omap_osk);
- DEBUG_LL_OMAP1(1, omap_palmte);
- DEBUG_LL_OMAP1(1, omap_palmz71);
-
- /* omap15xx/16xx based boards using UART2 */
- DEBUG_LL_OMAP1(2, omap_palmtt);
-
- /* omap15xx/16xx based boards using UART3 */
- DEBUG_LL_OMAP1(3, sx1);
- } while (0);
-}
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
index d6d1843337a5..a8db332dc72e 100644
--- a/arch/arm/mach-omap1/serial.c
+++ b/arch/arm/mach-omap1/serial.c
@@ -19,8 +19,7 @@
#include <asm/mach-types.h>
-#include <mach/serial.h>
-
+#include "serial.h"
#include "mux.h"
#include "pm.h"
#include "soc.h"
diff --git a/arch/arm/mach-omap1/include/mach/serial.h b/arch/arm/mach-omap1/serial.h
similarity index 100%
rename from arch/arm/mach-omap1/include/mach/serial.h
rename to arch/arm/mach-omap1/serial.h
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 371f2ed00eda..a11c96a093c9 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -4,6 +4,7 @@
#
ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/arch/arm/plat-omap/include
+ccflags-$(CONFIG_ARCH_OMAP1) += -I$(srctree)/arch/arm/mach-omap1/include
# Common support
obj-y := sram.o dma.o counter_32k.o
--
2.20.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH 13/22] input: omap: void using mach/*.h headers
From: Arnd Bergmann @ 2019-08-08 21:46 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Aaro Koskinen, Tony Lindgren, Greg Kroah-Hartman, Linus Walleij,
Bartlomiej Zolnierkiewicz, Linux Kernel Mailing List,
Tomi Valkeinen, open list:HID CORE LAYER, linux-omap, Linux ARM
In-Reply-To: <20190808214257.GF178933@dtor-ws>
On Thu, Aug 8, 2019 at 11:43 PM Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
>
> Hi Arnd,
>
> On Thu, Aug 08, 2019 at 11:22:22PM +0200, Arnd Bergmann wrote:
> > By using the new linux/soc/ti/omap1-io.h header instead,
> > compile-testing can be enabled, and a CONFIG_ARCH_MULTIPLATFORM
> > conversion of omap1 may eventually be possible.
> >
> > The warning in the header file gets removed in order to
> > allow CONFIG_COMPILE_TEST.
>
> Given that we want to migrate people off this driver everywhere but
> OMAP1 I wonder why we would want to improve compile coverage of it.
Mainly for consistency: I'm converting all omap1 drivers in this series to
not rely on mach/* headers and to let them be compiled standalone.
The other drivers don't have a replacement, so I could treat this different
from the rest and skip the Kconfig and platform_data changes if you
prefer.
Arnd
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 21/22] ARM: omap1: use common clk framework
From: Arnd Bergmann @ 2019-08-08 21:43 UTC (permalink / raw)
To: Tony Lindgren, Aaro Koskinen, Paul Walmsley
Cc: Arnd Bergmann, Bartlomiej Zolnierkiewicz, Greg Kroah-Hartman,
Linus Walleij, linux-kernel, Tomi Valkeinen, linux-omap,
linux-arm-kernel
In-Reply-To: <20190808214347.2865294-1-arnd@arndb.de>
The omap1 clock driver now uses types and calling conventions
that are compatible with the common clk core.
Turn on CONFIG_COMMON_CLK and remove all the code that is
now duplicated.
Note: if this previous steps didn't already break it, this one
most likely will, because the interfaces are very likely to
have different semantics.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
arch/arm/Kconfig | 1 +
arch/arm/mach-omap1/clock.c | 413 +-----------------------------------
2 files changed, 4 insertions(+), 410 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0febd7a1d65f..17a21f75f386 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -496,6 +496,7 @@ config ARCH_OMAP1
select ARCH_OMAP
select CLKDEV_LOOKUP
select CLKSRC_MMIO
+ select COMMON_CLK
select FORCE_PCI if PCCARD
select GENERIC_CLOCKEVENTS
select GENERIC_IRQ_CHIP
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index a951c787adb4..1f105c659e7e 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -10,6 +10,7 @@
*/
#include <linux/kernel.h>
#include <linux/export.h>
+#include <linux/clk-provider.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/err.h>
@@ -52,32 +53,6 @@ struct omap1_clk_lookup {
#define CK_16XX (1 << 3) /* 16xx, 17xx, 5912 */
#define CK_1710 (1 << 4) /* 1710 extra for rate selection */
-/**
- * struct clk_ops - some clock function pointers
- * @enable: fn ptr that enables the current clock in hardware
- * @disable: fn ptr that enables the current clock in hardware
- * @recalc_rate: fn ptr that returns the clock's current rate
- * @set_rate: fn ptr that can change the clock's current rate
- * @round_rate: fn ptr that can round the clock's current rate
- * @init: fn ptr to do clock-specific initialization
- *
- * A "companion" clk is an accompanying clock to the one being queried
- * that must be enabled for the IP module connected to the clock to
- * become accessible by the hardware. Neither @find_idlest nor
- * block-specific; the hwmod code has been created to handle this, but
- * until hwmod data is ready and drivers have been converted to use PM
- * runtime calls in place of clk_enable()/clk_disable(), @find_idlest and
- * @find_companion must, unfortunately, remain.
- */
-struct clk_ops {
- int (*enable)(struct clk_hw *);
- void (*disable)(struct clk_hw *);
- unsigned long (*recalc_rate)(struct clk_hw *, unsigned long);
- int (*set_rate)(struct clk_hw *, unsigned long, unsigned long);
- long (*round_rate)(struct clk_hw *, unsigned long, unsigned long *);
- void (*init)(struct clk_hw *);
-};
-
/*
* struct omap1_clk.flags possibilities
*
@@ -90,12 +65,8 @@ struct clk_ops {
/**
* struct omap1_clk - OMAP struct clk
- * @node: list_head connecting this clock into the full clock list
* @ops: struct clkops * for this clock
* @name: the name of the clock in the hardware (used in hwmod data and debug)
- * @parent: pointer to this clock's parent struct clk
- * @children: list_head connecting to the child clks' @sibling list_heads
- * @sibling: list_head connecting this clk to its parent clk's @children
* @rate: current clock rate
* @enable_reg: register to write to enable the clock (see @enable_bit)
* @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
@@ -115,38 +86,13 @@ struct clk_ops {
* clocks and decremented by the clock code when clk_disable() is
* called on child clocks.
*
- * XXX @clkdm, @usecount, @children, @sibling should be marked for
- * internal use only.
- *
- * @children and @sibling are used to optimize parent-to-child clock
- * tree traversals. (child-to-parent traversals use @parent.)
+ * XXX @usecount should be marked for internal use only.
*
* XXX The notion of the clock's current rate probably needs to be
* separated from the clock's target rate.
*/
-struct clk {
- struct clk_hw *clk_hw;
-};
-
-struct clk_init_data {
- const char *name;
- const struct clk_ops *ops;
- const struct clk_hw **parent_hws;
- u8 num_parents;
- unsigned long flags;
-};
-
-struct clk_hw {
- struct clk clk;
- const struct clk_init_data *init;
-};
-
struct omap1_clk {
struct clk_hw clk_hw;
- struct list_head node;
- struct omap1_clk *parent;
- struct list_head children;
- struct list_head sibling; /* node for children */
unsigned long rate;
void __iomem *enable_reg;
u8 enable_bit;
@@ -267,10 +213,6 @@ static u32 cpu_mask;
__u32 arm_idlect1_mask;
static struct clk_hw *api_ck_p, *ck_dpll1_p, *ck_ref_p;
-static LIST_HEAD(clocks);
-static DEFINE_MUTEX(clocks_mutex);
-static DEFINE_SPINLOCK(clockfw_lock);
-
/*
* Omap1 specific clock functions
*/
@@ -677,16 +619,6 @@ static void omap1_init_ext_clk(struct clk_hw *clk_hw)
clk-> rate = 96000000 / dsor;
}
-struct clk_hw *clk_hw_get_parent(const struct clk_hw *clk_hw)
-{
- struct omap1_clk *clk = to_omap1_clk(clk_hw);
-
- if (!clk->parent)
- return NULL;
-
- return &clk->parent->clk_hw;
-}
-
static void omap1_clk_disable(struct clk_hw *clk_hw)
{
struct omap1_clk *clk = to_omap1_clk(clk_hw);
@@ -860,173 +792,11 @@ static const struct clk_ops clkops_uart_16xx = {
.disable = omap1_clk_disable_uart_functional_16xx,
};
-static long omap1_clk_round_rate(struct clk_hw *clk_hw, unsigned long rate)
-{
- struct omap1_clk *clk = to_omap1_clk(clk_hw);
- struct clk_hw *parent = clk_hw_get_parent(clk_hw);
- struct omap1_clk *parent_clk;
- unsigned long parent_rate = 0;
-
- if (parent) {
- parent_clk = to_omap1_clk(parent);
- parent_rate = parent_clk->rate;
- }
-
- if (clk_hw->init->ops->round_rate != NULL)
- return clk_hw->init->ops->round_rate(clk_hw, rate, &parent_rate);
-
- if (parent)
- parent_clk->rate = parent_rate;
-
- return clk->rate;
-}
-
-static int omap1_clk_set_rate(struct clk_hw *clk_hw, unsigned long rate)
-{
- struct clk_hw *parent = clk_hw_get_parent(clk_hw);
- unsigned long parent_rate = 0;
- int ret = -EINVAL;
-
- if (parent)
- parent_rate = to_omap1_clk(parent)->rate;
-
- if (clk_hw->init->ops->set_rate)
- ret = clk_hw->init->ops->set_rate(clk_hw, rate, parent_rate);
-
- return ret;
-}
-
/* Propagate rate to children */
static void propagate_rate(struct omap1_clk *tclk)
{
- struct omap1_clk *clkp;
-
- list_for_each_entry(clkp, &tclk->children, sibling) {
- if (clkp->clk_hw.init->ops->recalc_rate)
- clkp->rate = clkp->clk_hw.init->ops->recalc_rate(&clkp->clk_hw, tclk->rate);
- propagate_rate(clkp);
- }
-}
-
-/*
- * Omap1 clock reset and init functions
- */
-
-int clk_enable(struct clk *clk)
-{
- unsigned long flags;
- int ret;
-
- if (clk == NULL || IS_ERR(clk))
- return -EINVAL;
-
- spin_lock_irqsave(&clockfw_lock, flags);
- ret = omap1_clk_enable(clk->clk_hw);
- spin_unlock_irqrestore(&clockfw_lock, flags);
-
- return ret;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
- unsigned long flags;
- struct omap1_clk *_clk = to_omap1_clk(clk->clk_hw);
-
- if (clk == NULL || IS_ERR(clk))
- return;
-
- spin_lock_irqsave(&clockfw_lock, flags);
- if (_clk->usecount == 0) {
- pr_err("Trying disable clock %s with 0 usecount\n",
- _clk->clk_hw.init->name);
- WARN_ON(1);
- goto out;
- }
-
- omap1_clk_disable(clk->clk_hw);
-
-out:
- spin_unlock_irqrestore(&clockfw_lock, flags);
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
- unsigned long flags;
- unsigned long ret;
-
- if (clk == NULL || IS_ERR(clk))
- return 0;
-
- spin_lock_irqsave(&clockfw_lock, flags);
- ret = to_omap1_clk(clk->clk_hw)->rate;
- spin_unlock_irqrestore(&clockfw_lock, flags);
-
- return ret;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-/*
- * Optional clock functions defined in include/linux/clk.h
- */
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
- unsigned long flags;
- long ret;
-
- if (clk == NULL || IS_ERR(clk))
- return 0;
-
- spin_lock_irqsave(&clockfw_lock, flags);
- ret = omap1_clk_round_rate(clk->clk_hw, rate);
- spin_unlock_irqrestore(&clockfw_lock, flags);
-
- return ret;
+ clk_set_rate(tclk->clk_hw.clk, tclk->rate);
}
-EXPORT_SYMBOL(clk_round_rate);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
- unsigned long flags;
- int ret = -EINVAL;
-
- if (clk == NULL || IS_ERR(clk))
- return ret;
-
- spin_lock_irqsave(&clockfw_lock, flags);
- ret = omap1_clk_set_rate(clk->clk_hw, rate);
- if (ret == 0)
- propagate_rate(to_omap1_clk(clk->clk_hw));
- spin_unlock_irqrestore(&clockfw_lock, flags);
-
- return ret;
-}
-EXPORT_SYMBOL(clk_set_rate);
-
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
- WARN_ONCE(1, "clk_set_parent() not implemented for OMAP1\n");
-
- return -EINVAL;
-}
-EXPORT_SYMBOL(clk_set_parent);
-
-struct clk *clk_get_parent(struct clk *clk)
-{
- struct clk_hw *parent = clk_hw_get_parent(clk->clk_hw);
-
- if (!parent)
- return NULL;
-
- return &parent->clk;
-}
-EXPORT_SYMBOL(clk_get_parent);
-
-/*
- * OMAP specific clock functions shared between omap1 and omap2
- */
/* Used for clocks that always have same value as the parent clock */
static unsigned long followparent_recalc(struct clk_hw *clk_hw, unsigned long parent_rate)
@@ -1047,47 +817,6 @@ static unsigned long omap_fixed_divisor_recalc(struct clk_hw *clk_hw, unsigned l
return parent_rate / clk->fixed_div;
}
-/**
- * clk_preinit - initialize any fields in the struct omap1_clk before clk init
- * @clk: struct omap1_clk * to initialize
- *
- * Initialize any struct omap1_clk fields needed before normal clk initialization
- * can run. No return value.
- */
-static void clk_preinit(struct omap1_clk *clk)
-{
- INIT_LIST_HEAD(&clk->children);
-}
-
-static int clk_register(struct device *dev, struct clk_hw *clk_hw)
-{
- struct omap1_clk *clk = to_omap1_clk(clk_hw);
-
- if (clk == NULL || IS_ERR(clk))
- return -EINVAL;
-
- /*
- * trap out already registered clocks
- */
- if (clk->node.next || clk->node.prev)
- return 0;
-
- clk_hw->clk.clk_hw = clk_hw;
-
- mutex_lock(&clocks_mutex);
- if (clk_hw->init->num_parents) {
- clk->parent = to_omap1_clk(clk_hw->init->parent_hws[0]);
- list_add(&clk->sibling, &clk->parent->children);
- }
-
- list_add(&clk->node, &clocks);
- if (clk_hw->init->ops->init)
- clk_hw->init->ops->init(clk_hw);
- mutex_unlock(&clocks_mutex);
-
- return 0;
-}
-
/*
* Low level helpers
*/
@@ -1135,139 +864,6 @@ static struct omap1_clk dummy_ck = {
CLK_INIT_ROOT("dummy", &clkops_null),
};
-/*
- *
- */
-
-#ifdef CONFIG_OMAP_RESET_CLOCKS
-/*
- * Disable any unused clocks left on by the bootloader
- */
-static void omap1_clk_disable_unused(struct omap1_clk *clk)
-{
- __u32 regval32;
-
- /* Clocks in the DSP domain need api_ck. Just assume bootloader
- * has not enabled any DSP clocks */
- if (clk->enable_reg == DSP_IDLECT2) {
- pr_info("Skipping reset check for DSP domain clock \"%s\"\n",
- clk->clk_hw.init->name);
- return;
- }
-
- /* Is the clock already disabled? */
- if (clk->flags & ENABLE_REG_32BIT)
- regval32 = __raw_readl(clk->enable_reg);
- else
- regval32 = __raw_readw(clk->enable_reg);
-
- if ((regval32 & (1 << clk->enable_bit)) == 0)
- return;
-
- printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->clk_hw.init->name);
- clk->clk_hw.init->ops->disable(&clk->clk_hw);
- printk(" done\n");
-}
-
-static int __init clk_disable_unused(void)
-{
- struct omap1_clk *ck;
- unsigned long flags;
-
- pr_info("clock: disabling unused clocks to save power\n");
-
- spin_lock_irqsave(&clockfw_lock, flags);
- list_for_each_entry(ck, &clocks, node) {
- if (ck->clk_hw.init->ops == &clkops_null)
- continue;
-
- if (ck->usecount > 0 || !ck->enable_reg)
- continue;
-
- omap1_clk_disable_unused(ck);
- }
- spin_unlock_irqrestore(&clockfw_lock, flags);
-
- return 0;
-}
-late_initcall(clk_disable_unused);
-#endif
-
-#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
-/*
- * debugfs support to trace clock tree hierarchy and attributes
- */
-
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-
-static struct dentry *clk_debugfs_root;
-
-static int debug_clock_show(struct seq_file *s, void *unused)
-{
- struct omap1_clk *c;
- struct omap1_clk *pa;
-
- mutex_lock(&clocks_mutex);
- seq_printf(s, "%-30s %-30s %-10s %s\n",
- "clock-name", "parent-name", "rate", "use-count");
-
- list_for_each_entry(c, &clocks, node) {
- pa = c->parent;
- seq_printf(s, "%-30s %-30s %-10lu %d\n",
- c->name, pa ? pa->name : "none", c->rate,
- c->usecount);
- }
- mutex_unlock(&clocks_mutex);
-
- return 0;
-}
-
-DEFINE_SHOW_ATTRIBUTE(debug_clock);
-
-static void clk_debugfs_register_one(struct omap1_clk *c)
-{
- struct dentry *d;
- struct omap1_clk *pa = c->parent;
-
- d = debugfs_create_dir(c->name, pa ? pa->dent : clk_debugfs_root);
- c->dent = d;
-
- debugfs_create_u8("usecount", S_IRUGO, c->dent, &c->usecount);
- debugfs_create_ulong("rate", S_IRUGO, c->dent, &c->rate);
- debugfs_create_x8("flags", S_IRUGO, c->dent, &c->flags);
-}
-
-static void clk_debugfs_register(struct omap1_clk *c)
-{
- struct omap1_clk *pa = c->parent;
-
- if (pa && !pa->dent)
- clk_debugfs_register(pa);
-
- if (!c->dent)
- clk_debugfs_register_one(c);
-}
-
-static int __init clk_debugfs_init(void)
-{
- struct omap1_clk *c;
- struct dentry *d;
-
- d = debugfs_create_dir("clock", NULL);
- clk_debugfs_root = d;
-
- list_for_each_entry(c, &clocks, node)
- clk_debugfs_register(c);
-
- debugfs_create_file("summary", S_IRUGO, d, NULL, &debug_clock_fops);
-
- return 0;
-}
-late_initcall(clk_debugfs_init);
-
-#endif /* defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) */
-
/*
* Omap1 clocks
*/
@@ -1897,9 +1493,6 @@ int __init omap1_clk_init(void)
/* By default all idlect1 clocks are allowed to idle */
arm_idlect1_mask = ~0;
- for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++)
- clk_preinit(to_omap1_clk(c->lk.clk_hw));
-
cpu_mask = 0;
if (cpu_is_omap1710())
cpu_mask |= CK_1710;
--
2.20.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 20/22] ARM: omap1: clk: use clk_init_data
From: Arnd Bergmann @ 2019-08-08 21:43 UTC (permalink / raw)
To: Tony Lindgren, Aaro Koskinen, Paul Walmsley
Cc: Arnd Bergmann, Bartlomiej Zolnierkiewicz, Greg Kroah-Hartman,
Linus Walleij, linux-kernel, Tomi Valkeinen, linux-omap,
linux-arm-kernel
In-Reply-To: <20190808212234.2213262-1-arnd@arndb.de>
The common_clk layer requires common data to be passed
as clk_init_data, so mimic this here.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
arch/arm/mach-omap1/clock.c | 266 ++++++++++++++----------------------
1 file changed, 99 insertions(+), 167 deletions(-)
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index 8b4d5ee13ba0..a951c787adb4 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -128,15 +128,22 @@ struct clk {
struct clk_hw *clk_hw;
};
+struct clk_init_data {
+ const char *name;
+ const struct clk_ops *ops;
+ const struct clk_hw **parent_hws;
+ u8 num_parents;
+ unsigned long flags;
+};
+
struct clk_hw {
struct clk clk;
+ const struct clk_init_data *init;
};
struct omap1_clk {
struct clk_hw clk_hw;
struct list_head node;
- const struct clk_ops *ops;
- const char *name;
struct omap1_clk *parent;
struct list_head children;
struct list_head sibling; /* node for children */
@@ -686,7 +693,7 @@ static void omap1_clk_disable(struct clk_hw *clk_hw)
struct clk_hw *parent = clk_hw_get_parent(clk_hw);
if (clk->usecount > 0 && !(--clk->usecount)) {
- clk->ops->disable(clk_hw);
+ clk->clk_hw.init->ops->disable(&clk->clk_hw);
if (likely(parent)) {
omap1_clk_disable(parent);
if (clk->flags & CLOCK_NO_IDLE_PARENT)
@@ -711,7 +718,7 @@ static omap1_clk_enable(struct clk_hw *clk_hw)
omap1_clk_deny_idle(parent);
}
- ret = clk->ops->enable(&clk->clk_hw);
+ ret = clk->clk_hw.init->ops->enable(&clk->clk_hw);
if (ret) {
if (parent)
omap1_clk_disable(parent);
@@ -733,7 +740,7 @@ static int omap1_clk_enable_generic(struct clk_hw *clk_hw)
if (unlikely(clk->enable_reg == NULL)) {
printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
- clk->name);
+ clk->clk_hw.init->name);
return -EINVAL;
}
@@ -865,8 +872,8 @@ static long omap1_clk_round_rate(struct clk_hw *clk_hw, unsigned long rate)
parent_rate = parent_clk->rate;
}
- if (clk->ops->round_rate != NULL)
- return clk->ops->round_rate(clk_hw, rate, &parent_rate);
+ if (clk_hw->init->ops->round_rate != NULL)
+ return clk_hw->init->ops->round_rate(clk_hw, rate, &parent_rate);
if (parent)
parent_clk->rate = parent_rate;
@@ -876,7 +883,6 @@ static long omap1_clk_round_rate(struct clk_hw *clk_hw, unsigned long rate)
static int omap1_clk_set_rate(struct clk_hw *clk_hw, unsigned long rate)
{
- struct omap1_clk *clk = to_omap1_clk(clk_hw);
struct clk_hw *parent = clk_hw_get_parent(clk_hw);
unsigned long parent_rate = 0;
int ret = -EINVAL;
@@ -884,8 +890,9 @@ static int omap1_clk_set_rate(struct clk_hw *clk_hw, unsigned long rate)
if (parent)
parent_rate = to_omap1_clk(parent)->rate;
- if (clk->ops->set_rate)
- ret = clk->ops->set_rate(clk_hw, rate, parent_rate);
+ if (clk_hw->init->ops->set_rate)
+ ret = clk_hw->init->ops->set_rate(clk_hw, rate, parent_rate);
+
return ret;
}
@@ -895,8 +902,8 @@ static void propagate_rate(struct omap1_clk *tclk)
struct omap1_clk *clkp;
list_for_each_entry(clkp, &tclk->children, sibling) {
- if (clkp->ops->recalc_rate)
- clkp->rate = clkp->ops->recalc_rate(&clkp->clk_hw, tclk->rate);
+ if (clkp->clk_hw.init->ops->recalc_rate)
+ clkp->rate = clkp->clk_hw.init->ops->recalc_rate(&clkp->clk_hw, tclk->rate);
propagate_rate(clkp);
}
}
@@ -932,7 +939,7 @@ void clk_disable(struct clk *clk)
spin_lock_irqsave(&clockfw_lock, flags);
if (_clk->usecount == 0) {
pr_err("Trying disable clock %s with 0 usecount\n",
- _clk->name);
+ _clk->clk_hw.init->name);
WARN_ON(1);
goto out;
}
@@ -1068,12 +1075,14 @@ static int clk_register(struct device *dev, struct clk_hw *clk_hw)
clk_hw->clk.clk_hw = clk_hw;
mutex_lock(&clocks_mutex);
- if (clk->parent)
+ if (clk_hw->init->num_parents) {
+ clk->parent = to_omap1_clk(clk_hw->init->parent_hws[0]);
list_add(&clk->sibling, &clk->parent->children);
+ }
list_add(&clk->node, &clocks);
- if (clk->ops->init)
- clk->ops->init(&clk->clk_hw);
+ if (clk_hw->init->ops->init)
+ clk_hw->init->ops->init(clk_hw);
mutex_unlock(&clocks_mutex);
return 0;
@@ -1102,14 +1111,28 @@ static const struct clk_ops clkops_followparent = {
.recalc_rate = followparent_recalc,
};
+#define CLK_INIT(_name, _ops, _parent) \
+ .clk_hw.init = &(struct clk_init_data) { \
+ .name = (_name), \
+ .ops = (_ops), \
+ .parent_hws = (const struct clk_hw *[1])\
+ {&(_parent)->clk_hw}, \
+ .num_parents = 1, \
+ }
+
+#define CLK_INIT_ROOT(_name, _ops) \
+ .clk_hw.init = &(struct clk_init_data) { \
+ .name = (_name), \
+ .ops = (_ops), \
+ }
+
/*
* Dummy clock
*
* Used for clock aliases that are needed on some OMAPs, but not others
*/
static struct omap1_clk dummy_ck = {
- .name = "dummy",
- .ops = &clkops_null,
+ CLK_INIT_ROOT("dummy", &clkops_null),
};
/*
@@ -1128,7 +1151,7 @@ static void omap1_clk_disable_unused(struct omap1_clk *clk)
* has not enabled any DSP clocks */
if (clk->enable_reg == DSP_IDLECT2) {
pr_info("Skipping reset check for DSP domain clock \"%s\"\n",
- clk->name);
+ clk->clk_hw.init->name);
return;
}
@@ -1141,8 +1164,8 @@ static void omap1_clk_disable_unused(struct omap1_clk *clk)
if ((regval32 & (1 << clk->enable_bit)) == 0)
return;
- printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name);
- clk->ops->disable(&clk->clk_hw);
+ printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->clk_hw.init->name);
+ clk->clk_hw.init->ops->disable(&clk->clk_hw);
printk(" done\n");
}
@@ -1155,7 +1178,7 @@ static int __init clk_disable_unused(void)
spin_lock_irqsave(&clockfw_lock, flags);
list_for_each_entry(ck, &clocks, node) {
- if (ck->ops == &clkops_null)
+ if (ck->clk_hw.init->ops == &clkops_null)
continue;
if (ck->usecount > 0 || !ck->enable_reg)
@@ -1248,17 +1271,13 @@ late_initcall(clk_debugfs_init);
/*
* Omap1 clocks
*/
-
static struct omap1_clk ck_ref = {
- .name = "ck_ref",
- .ops = &clkops_null,
+ CLK_INIT_ROOT("ck_ref", &clkops_null),
.rate = 12000000,
};
static struct omap1_clk ck_dpll1 = {
- .name = "ck_dpll1",
- .ops = &clkops_null,
- .parent = &ck_ref,
+ CLK_INIT("ck_dpll1", &clkops_null, &ck_ref),
};
static const struct clk_ops clkops_generic_followparent = {
@@ -1273,9 +1292,7 @@ static const struct clk_ops clkops_generic_followparent = {
*/
static struct arm_idlect1_clk ck_dpll1out = {
.clk = {
- .name = "ck_dpll1out",
- .ops = &clkops_generic_followparent,
- .parent = &ck_dpll1,
+ CLK_INIT("ck_dpll1out", &clkops_generic_followparent, &ck_dpll1),
.flags = CLOCK_IDLE_CONTROL | ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_CKOUT_ARM,
@@ -1291,15 +1308,13 @@ static const struct clk_ops clkops_sossi = {
};
static struct omap1_clk sossi_ck = {
- .name = "ck_sossi",
- .ops = &clkops_sossi,
- .parent = &ck_dpll1out.clk,
+ CLK_INIT("ck_sossi", &clkops_sossi, &ck_dpll1out.clk),
.flags = CLOCK_NO_IDLE_PARENT | ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1),
.enable_bit = CONF_MOD_SOSSI_CLK_EN_R,
};
-struct clk_ops clkops_null_ckctl = {
+static const struct clk_ops clkops_null_ckctl = {
.enable = clkll_enable_null,
.disable = clkll_disable_null,
.recalc_rate = omap1_ckctl_recalc,
@@ -1308,13 +1323,11 @@ struct clk_ops clkops_null_ckctl = {
};
static struct omap1_clk arm_ck = {
- .name = "arm_ck",
- .ops = &clkops_null_ckctl,
- .parent = &ck_dpll1,
+ CLK_INIT("arm_ck", &clkops_null_ckctl, &ck_dpll1),
.rate_offset = CKCTL_ARMDIV_OFFSET,
};
-struct clk_ops clkops_generic_ckctl = {
+static const struct clk_ops clkops_generic_ckctl = {
.enable = omap1_clk_enable_generic,
.disable = omap1_clk_disable_generic,
.recalc_rate = omap1_ckctl_recalc,
@@ -1324,9 +1337,7 @@ struct clk_ops clkops_generic_ckctl = {
static struct arm_idlect1_clk armper_ck = {
.clk = {
- .name = "armper_ck",
- .ops = &clkops_generic_ckctl,
- .parent = &ck_dpll1,
+ CLK_INIT("armper_ck", &clkops_generic_ckctl, &ck_dpll1),
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_PERCK,
@@ -1340,18 +1351,14 @@ static struct arm_idlect1_clk armper_ck = {
* activation. [ GPIO code for 1510 ]
*/
static struct omap1_clk arm_gpio_ck = {
- .name = "ick",
- .ops = &clkops_generic_followparent,
- .parent = &ck_dpll1,
+ CLK_INIT("ick", &clkops_generic_followparent, &ck_dpll1),
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_GPIOCK,
};
static struct arm_idlect1_clk armxor_ck = {
.clk = {
- .name = "armxor_ck",
- .ops = &clkops_generic_followparent,
- .parent = &ck_ref,
+ CLK_INIT("armxor_ck", &clkops_generic_followparent, &ck_ref),
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_XORPCK,
@@ -1361,9 +1368,7 @@ static struct arm_idlect1_clk armxor_ck = {
static struct arm_idlect1_clk armtim_ck = {
.clk = {
- .name = "armtim_ck",
- .ops = &clkops_generic_followparent,
- .parent = &ck_ref,
+ CLK_INIT("armtim_ck", &clkops_generic_followparent, &ck_ref),
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_TIMCK,
@@ -1379,9 +1384,7 @@ static const struct clk_ops clkops_fixed_divisor = {
static struct arm_idlect1_clk armwdt_ck = {
.clk = {
- .name = "armwdt_ck",
- .ops = &clkops_generic,
- .parent = &ck_ref,
+ CLK_INIT("armwdt_ck", &clkops_generic, &ck_ref),
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_WDTCK,
@@ -1391,9 +1394,7 @@ static struct arm_idlect1_clk armwdt_ck = {
};
static struct omap1_clk arminth_ck16xx = {
- .name = "arminth_ck",
- .ops = &clkops_followparent,
- .parent = &arm_ck,
+ CLK_INIT("arminth_ck", &clkops_followparent, &arm_ck),
/* Note: On 16xx the frequency can be divided by 2 by programming
* ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
*
@@ -1402,18 +1403,14 @@ static struct omap1_clk arminth_ck16xx = {
};
static struct omap1_clk dsp_ck = {
- .name = "dsp_ck",
- .ops = &clkops_generic_ckctl,
- .parent = &ck_dpll1,
+ CLK_INIT("dsp_ck", &clkops_generic_ckctl, &ck_dpll1),
.enable_reg = OMAP1_IO_ADDRESS(ARM_CKCTL),
.enable_bit = EN_DSPCK,
.rate_offset = CKCTL_DSPDIV_OFFSET,
};
static struct omap1_clk dspmmu_ck = {
- .name = "dspmmu_ck",
- .ops = &clkops_null_ckctl,
- .parent = &ck_dpll1,
+ CLK_INIT("dspmmu_ck", &clkops_null_ckctl, &ck_dpll1),
.rate_offset = CKCTL_DSPMMUDIV_OFFSET,
};
@@ -1426,9 +1423,7 @@ static const struct clk_ops clkops_dspck = {
};
static struct omap1_clk dspper_ck = {
- .name = "dspper_ck",
- .ops = &clkops_dspck,
- .parent = &ck_dpll1,
+ CLK_INIT("dspper_ck", &clkops_dspck, &ck_dpll1),
.enable_reg = DSP_IDLECT2,
.enable_bit = EN_PERCK,
.rate_offset = CKCTL_PERDIV_OFFSET,
@@ -1441,26 +1436,20 @@ static const struct clk_ops clkops_dspck_followparent = {
};
static struct omap1_clk dspxor_ck = {
- .name = "dspxor_ck",
- .ops = &clkops_dspck_followparent,
- .parent = &ck_ref,
+ CLK_INIT("dspxor_ck", &clkops_dspck_followparent, &ck_ref),
.enable_reg = DSP_IDLECT2,
.enable_bit = EN_XORPCK,
};
static struct omap1_clk dsptim_ck = {
- .name = "dsptim_ck",
- .ops = &clkops_dspck_followparent,
- .parent = &ck_ref,
+ CLK_INIT("dsptim_ck", &clkops_dspck_followparent, &ck_ref),
.enable_reg = DSP_IDLECT2,
.enable_bit = EN_DSPTIMCK,
};
static struct arm_idlect1_clk tc_ck = {
.clk = {
- .name = "tc_ck",
- .ops = &clkops_null_ckctl,
- .parent = &ck_dpll1,
+ CLK_INIT("tc_ck", &clkops_null_ckctl, &ck_dpll1),
.flags = CLOCK_IDLE_CONTROL,
.rate_offset = CKCTL_TCDIV_OFFSET,
},
@@ -1468,9 +1457,7 @@ static struct arm_idlect1_clk tc_ck = {
};
static struct omap1_clk arminth_ck1510 = {
- .name = "arminth_ck",
- .ops = &clkops_followparent,
- .parent = &tc_ck.clk,
+ CLK_INIT("arminth_ck", &clkops_followparent, &tc_ck.clk),
/* Note: On 1510 the frequency follows TC_CK
*
* 16xx version is in MPU clocks.
@@ -1479,24 +1466,18 @@ static struct omap1_clk arminth_ck1510 = {
static struct omap1_clk tipb_ck = {
/* No-idle controlled by "tc_ck" */
- .name = "tipb_ck",
- .ops = &clkops_followparent,
- .parent = &tc_ck.clk,
+ CLK_INIT("tipb_ck", &clkops_followparent, &tc_ck.clk),
};
static struct omap1_clk l3_ocpi_ck = {
/* No-idle controlled by "tc_ck" */
- .name = "l3_ocpi_ck",
- .ops = &clkops_generic_followparent,
- .parent = &tc_ck.clk,
+ CLK_INIT("l3_ocpi_ck", &clkops_generic_followparent, &tc_ck.clk),
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3),
.enable_bit = EN_OCPI_CK,
};
static struct omap1_clk tc1_ck = {
- .name = "tc1_ck",
- .ops = &clkops_generic_followparent,
- .parent = &tc_ck.clk,
+ CLK_INIT("tc1_ck", &clkops_generic_followparent, &tc_ck.clk),
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3),
.enable_bit = EN_TC1_CK,
};
@@ -1506,31 +1487,23 @@ static struct omap1_clk tc1_ck = {
* activation. [ pm.c (SRAM), CCP, Camera ]
*/
static struct omap1_clk tc2_ck = {
- .name = "tc2_ck",
- .ops = &clkops_generic_followparent,
- .parent = &tc_ck.clk,
+ CLK_INIT("tc2_ck", &clkops_generic_followparent, &tc_ck.clk),
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3),
.enable_bit = EN_TC2_CK,
};
static struct omap1_clk dma_ck = {
/* No-idle controlled by "tc_ck" */
- .name = "dma_ck",
- .ops = &clkops_followparent,
- .parent = &tc_ck.clk,
+ CLK_INIT("dma_ck", &clkops_followparent, &tc_ck.clk),
};
static struct omap1_clk dma_lcdfree_ck = {
- .name = "dma_lcdfree_ck",
- .ops = &clkops_followparent,
- .parent = &tc_ck.clk,
+ CLK_INIT("dma_lcdfree_ck", &clkops_followparent, &tc_ck.clk),
};
static struct arm_idlect1_clk api_ck = {
.clk = {
- .name = "api_ck",
- .ops = &clkops_generic_followparent,
- .parent = &tc_ck.clk,
+ CLK_INIT("api_ck", &clkops_generic_followparent, &tc_ck.clk),
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_APICK,
@@ -1540,9 +1513,7 @@ static struct arm_idlect1_clk api_ck = {
static struct arm_idlect1_clk lb_ck = {
.clk = {
- .name = "lb_ck",
- .ops = &clkops_generic_followparent,
- .parent = &tc_ck.clk,
+ CLK_INIT("lb_ck", &clkops_generic_followparent, &tc_ck.clk),
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_LBCK,
@@ -1551,21 +1522,15 @@ static struct arm_idlect1_clk lb_ck = {
};
static struct omap1_clk rhea1_ck = {
- .name = "rhea1_ck",
- .ops = &clkops_followparent,
- .parent = &tc_ck.clk,
+ CLK_INIT("rhea1_ck", &clkops_followparent, &tc_ck.clk),
};
static struct omap1_clk rhea2_ck = {
- .name = "rhea2_ck",
- .ops = &clkops_followparent,
- .parent = &tc_ck.clk,
+ CLK_INIT("rhea2_ck", &clkops_followparent, &tc_ck.clk),
};
static struct omap1_clk lcd_ck_16xx = {
- .name = "lcd_ck",
- .ops = &clkops_generic_ckctl,
- .parent = &ck_dpll1,
+ CLK_INIT("lcd_ck", &clkops_generic_ckctl, &ck_dpll1),
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_LCDCK,
.rate_offset = CKCTL_LCDDIV_OFFSET,
@@ -1573,9 +1538,7 @@ static struct omap1_clk lcd_ck_16xx = {
static struct arm_idlect1_clk lcd_ck_1510 = {
.clk = {
- .name = "lcd_ck",
- .ops = &clkops_generic_ckctl,
- .parent = &ck_dpll1,
+ CLK_INIT("lcd_ck", &clkops_generic_ckctl, &ck_dpll1),
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_LCDCK,
@@ -1598,10 +1561,8 @@ static const struct clk_ops clkops_uart = {
* XXX does this need SYSC register handling?
*/
static struct omap1_clk uart1_1510 = {
- .name = "uart1_ck",
- .ops = &clkops_uart,
/* Direct from ULPD, no real parent */
- .parent = &armper_ck.clk,
+ CLK_INIT("uart1_ck", &clkops_uart, &armper_ck.clk),
.rate = 12000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
@@ -1616,10 +1577,8 @@ static struct omap1_clk uart1_1510 = {
*/
static struct uart_clk uart1_16xx = {
.clk = {
- .name = "uart1_ck",
- .ops = &clkops_uart_16xx,
/* Direct from ULPD, no real parent */
- .parent = &armper_ck.clk,
+ CLK_INIT("uart1_ck", &clkops_uart_16xx, &armper_ck.clk),
.rate = 48000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
@@ -1635,10 +1594,8 @@ static struct uart_clk uart1_16xx = {
* XXX does this need SYSC register handling?
*/
static struct omap1_clk uart2_ck = {
- .name = "uart2_ck",
- .ops = &clkops_uart,
/* Direct from ULPD, no real parent */
- .parent = &armper_ck.clk,
+ CLK_INIT("uart2_ck", &clkops_uart, &armper_ck.clk),
.rate = 12000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
@@ -1652,10 +1609,8 @@ static struct omap1_clk uart2_ck = {
* XXX does this need SYSC register handling?
*/
static struct omap1_clk uart3_1510 = {
- .name = "uart3_ck",
- .ops = &clkops_uart,
/* Direct from ULPD, no real parent */
- .parent = &armper_ck.clk,
+ CLK_INIT("uart3_ck", &clkops_uart, &armper_ck.clk),
.rate = 12000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
@@ -1670,10 +1625,8 @@ static struct omap1_clk uart3_1510 = {
*/
static struct uart_clk uart3_16xx = {
.clk = {
- .name = "uart3_ck",
- .ops = &clkops_uart_16xx,
/* Direct from ULPD, no real parent */
- .parent = &armper_ck.clk,
+ CLK_INIT("uart3_ck", &clkops_uart_16xx, &armper_ck.clk),
.rate = 48000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
@@ -1683,9 +1636,8 @@ static struct uart_clk uart3_16xx = {
};
static struct omap1_clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
- .name = "usb_clko",
- .ops = &clkops_generic,
/* Direct from ULPD, no parent */
+ CLK_INIT_ROOT("usb_clko", &clkops_generic),
.rate = 6000000,
.flags = ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(ULPD_CLOCK_CTRL),
@@ -1693,9 +1645,8 @@ static struct omap1_clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
};
static struct omap1_clk usb_hhc_ck1510 = {
- .name = "usb_hhc_ck",
- .ops = &clkops_generic,
/* Direct from ULPD, no parent */
+ CLK_INIT_ROOT("usb_hhc_ck", &clkops_generic),
.rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
.flags = ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
@@ -1703,9 +1654,8 @@ static struct omap1_clk usb_hhc_ck1510 = {
};
static struct omap1_clk usb_hhc_ck16xx = {
- .name = "usb_hhc_ck",
- .ops = &clkops_generic,
/* Direct from ULPD, no parent */
+ CLK_INIT_ROOT("usb_hhc_ck", &clkops_generic),
.rate = 48000000,
/* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
.flags = ENABLE_REG_32BIT,
@@ -1714,36 +1664,32 @@ static struct omap1_clk usb_hhc_ck16xx = {
};
static struct omap1_clk usb_dc_ck = {
- .name = "usb_dc_ck",
- .ops = &clkops_generic,
/* Direct from ULPD, no parent */
+ CLK_INIT_ROOT("usb_dc_ck", &clkops_generic),
.rate = 48000000,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = SOFT_USB_OTG_DPLL_REQ_SHIFT,
};
static struct omap1_clk uart1_7xx = {
- .name = "uart1_ck",
- .ops = &clkops_generic,
/* Direct from ULPD, no parent */
+ CLK_INIT_ROOT("uart1_ck", &clkops_generic),
.rate = 12000000,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = 9,
};
static struct omap1_clk uart2_7xx = {
- .name = "uart2_ck",
- .ops = &clkops_generic,
/* Direct from ULPD, no parent */
+ CLK_INIT_ROOT("uart2_ck", &clkops_generic),
.rate = 12000000,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = 11,
};
static struct omap1_clk mclk_1510 = {
- .name = "mclk",
- .ops = &clkops_generic,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
+ CLK_INIT_ROOT("mclk", &clkops_generic),
.rate = 12000000,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = SOFT_COM_MCKO_REQ_SHIFT,
@@ -1758,33 +1704,28 @@ static const struct clk_ops clkops_ext_clk = {
};
static struct omap1_clk mclk_16xx = {
- .name = "mclk",
- .ops = &clkops_ext_clk,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
+ CLK_INIT_ROOT("mclk", &clkops_ext_clk),
.enable_reg = OMAP1_IO_ADDRESS(COM_CLK_DIV_CTRL_SEL),
.enable_bit = COM_ULPD_PLL_CLK_REQ,
};
static struct omap1_clk bclk_1510 = {
- .name = "bclk",
- .ops = &clkops_generic,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
+ CLK_INIT_ROOT("bclk", &clkops_generic),
.rate = 12000000,
};
static struct omap1_clk bclk_16xx = {
- .name = "bclk",
- .ops = &clkops_ext_clk,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
+ CLK_INIT_ROOT("bclk", &clkops_ext_clk),
.enable_reg = OMAP1_IO_ADDRESS(SWD_CLK_DIV_CTRL_SEL),
.enable_bit = SWD_ULPD_PLL_CLK_REQ,
};
static struct omap1_clk mmc1_ck = {
- .name = "mmc1_ck",
- .ops = &clkops_generic,
/* Functional clock is direct from ULPD, interface clock is ARMPER */
- .parent = &armper_ck.clk,
+ CLK_INIT("mmc1_ck", &clkops_generic, &armper_ck.clk),
.rate = 48000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
@@ -1796,10 +1737,8 @@ static struct omap1_clk mmc1_ck = {
* CONF_MOD_MCBSP3_AUXON ??
*/
static struct omap1_clk mmc2_ck = {
- .name = "mmc2_ck",
- .ops = &clkops_generic,
/* Functional clock is direct from ULPD, interface clock is ARMPER */
- .parent = &armper_ck.clk,
+ CLK_INIT("mmc2_ck", &clkops_generic, &armper_ck.clk),
.rate = 48000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
@@ -1807,10 +1746,8 @@ static struct omap1_clk mmc2_ck = {
};
static struct omap1_clk mmc3_ck = {
- .name = "mmc3_ck",
- .ops = &clkops_generic,
/* Functional clock is direct from ULPD, interface clock is ARMPER */
- .parent = &armper_ck.clk,
+ CLK_INIT("mmc3_ck", &clkops_generic, &armper_ck.clk),
.rate = 48000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
@@ -1826,25 +1763,20 @@ static const struct clk_ops clkops_mpu = {
};
static struct omap1_clk virtual_ck_mpu = {
- .name = "mpu",
- .ops = &clkops_mpu,
- .parent = &arm_ck, /* Is smarter alias for */
+ /* Is smarter alias for */
+ CLK_INIT("mpu", &clkops_mpu, &arm_ck),
};
/* virtual functional clock domain for I2C. Just for making sure that ARMXOR_CK
remains active during MPU idle whenever this is enabled */
static struct omap1_clk i2c_fck = {
- .name = "i2c_fck",
- .ops = &clkops_followparent,
+ CLK_INIT("i2c_fck", &clkops_followparent, &armxor_ck.clk),
.flags = CLOCK_NO_IDLE_PARENT,
- .parent = &armxor_ck.clk,
};
static struct omap1_clk i2c_ick = {
- .name = "i2c_ick",
- .ops = &clkops_followparent,
+ CLK_INIT("i2c_ick", &clkops_followparent, &armper_ck.clk),
.flags = CLOCK_NO_IDLE_PARENT,
- .parent = &armper_ck.clk,
};
/*
--
2.20.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 19/22] ARM: omap1: clk: use common_clk-like callbacks
From: Arnd Bergmann @ 2019-08-08 21:41 UTC (permalink / raw)
To: Tony Lindgren, Aaro Koskinen, Paul Walmsley
Cc: Arnd Bergmann, Bartlomiej Zolnierkiewicz, Greg Kroah-Hartman,
Linus Walleij, linux-kernel, Tomi Valkeinen, linux-omap,
linux-arm-kernel
In-Reply-To: <20190808214232.2798396-1-arnd@arndb.de>
The callbacks for clocks are almost the same as those used
on common_clk, now reduce the number of remaining differences:
- make .recalc_rate and .round_rate take a parent_rate argument
- move .recalc_rate/.set_rate/.round_rate/.init from
'struct clk_hw' into 'struct clk_ops'.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
arch/arm/mach-omap1/clock.c | 368 ++++++++++++++++++++----------------
1 file changed, 200 insertions(+), 168 deletions(-)
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index 577686f61b3b..8b4d5ee13ba0 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -56,6 +56,10 @@ struct omap1_clk_lookup {
* struct clk_ops - some clock function pointers
* @enable: fn ptr that enables the current clock in hardware
* @disable: fn ptr that enables the current clock in hardware
+ * @recalc_rate: fn ptr that returns the clock's current rate
+ * @set_rate: fn ptr that can change the clock's current rate
+ * @round_rate: fn ptr that can round the clock's current rate
+ * @init: fn ptr to do clock-specific initialization
*
* A "companion" clk is an accompanying clock to the one being queried
* that must be enabled for the IP module connected to the clock to
@@ -66,8 +70,12 @@ struct omap1_clk_lookup {
* @find_companion must, unfortunately, remain.
*/
struct clk_ops {
- int (*enable)(struct clk_hw *);
- void (*disable)(struct clk_hw *);
+ int (*enable)(struct clk_hw *);
+ void (*disable)(struct clk_hw *);
+ unsigned long (*recalc_rate)(struct clk_hw *, unsigned long);
+ int (*set_rate)(struct clk_hw *, unsigned long, unsigned long);
+ long (*round_rate)(struct clk_hw *, unsigned long, unsigned long *);
+ void (*init)(struct clk_hw *);
};
/*
@@ -90,10 +98,6 @@ struct clk_ops {
* @sibling: list_head connecting this clk to its parent clk's @children
* @rate: current clock rate
* @enable_reg: register to write to enable the clock (see @enable_bit)
- * @recalc: fn ptr that returns the clock's current rate
- * @set_rate: fn ptr that can change the clock's current rate
- * @round_rate: fn ptr that can round the clock's current rate
- * @init: fn ptr to do clock-specific initialization
* @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
* @usecount: number of users that have requested this clock to be enabled
* @fixed_div: when > 0, this clock's rate is its parent's rate / @fixed_div
@@ -138,10 +142,6 @@ struct omap1_clk {
struct list_head sibling; /* node for children */
unsigned long rate;
void __iomem *enable_reg;
- unsigned long (*recalc)(struct clk_hw *);
- int (*set_rate)(struct clk_hw *, unsigned long);
- long (*round_rate)(struct clk_hw *, unsigned long);
- void (*init)(struct clk_hw *);
u8 enable_bit;
s8 usecount;
u8 fixed_div;
@@ -268,22 +268,21 @@ static DEFINE_SPINLOCK(clockfw_lock);
* Omap1 specific clock functions
*/
-static unsigned long omap1_uart_recalc(struct clk_hw *clk_hw)
+static unsigned long omap1_uart_recalc(struct clk_hw *clk_hw, unsigned long parent_rate)
{
struct omap1_clk *clk = to_omap1_clk(clk_hw);
unsigned int val = __raw_readl(clk->enable_reg);
return val & clk->enable_bit ? 48000000 : 12000000;
}
-static unsigned long omap1_sossi_recalc(struct clk_hw *clk_hw)
+static unsigned long omap1_sossi_recalc(struct clk_hw *clk_hw, unsigned long parent_rate)
{
- struct omap1_clk *clk = to_omap1_clk(clk_hw);
u32 div = omap_readl(MOD_CONF_CTRL_1);
div = (div >> 17) & 0x7;
div++;
- return clk->parent->rate / div;
+ return parent_rate / div;
}
static void omap1_clk_allow_idle(struct clk_hw *clk_hw)
@@ -363,7 +362,7 @@ static __u16 verify_ckctl_value(__u16 newval)
return newval;
}
-static int calc_dsor_exp(struct omap1_clk *clk, unsigned long rate)
+static int calc_dsor_exp(struct omap1_clk *clk, unsigned long rate, unsigned long parent_rate)
{
/* Note: If target frequency is too low, this function will return 4,
* which is invalid value. Caller must check for this value and act
@@ -377,14 +376,9 @@ static int calc_dsor_exp(struct omap1_clk *clk, unsigned long rate)
* DSPMMU_CK >= TC_CK
*/
unsigned long realrate;
- struct omap1_clk * parent;
unsigned dsor_exp;
- parent = clk->parent;
- if (unlikely(parent == NULL))
- return -EIO;
-
- realrate = parent->rate;
+ realrate = parent_rate;
for (dsor_exp=0; dsor_exp<4; dsor_exp++) {
if (realrate <= rate)
break;
@@ -395,13 +389,13 @@ static int calc_dsor_exp(struct omap1_clk *clk, unsigned long rate)
return dsor_exp;
}
-static unsigned long omap1_ckctl_recalc(struct clk_hw *clk_hw)
+static unsigned long omap1_ckctl_recalc(struct clk_hw *clk_hw, unsigned long parent_rate)
{
struct omap1_clk *clk = to_omap1_clk(clk_hw);
/* Calculate divisor encoded as 2-bit exponent */
int dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
- return clk->parent->rate / dsor;
+ return parent_rate / dsor;
}
/*-------------------------------------------------------------------------
@@ -453,7 +447,7 @@ static struct mpu_rate omap1_rate_table[] = {
};
/* MPU virtual clock functions */
-static int omap1_select_table_rate(struct clk_hw *clk_hw, unsigned long rate)
+static int omap1_select_table_rate(struct clk_hw *clk_hw, unsigned long rate, unsigned long parent_rate)
{
/* Find the highest supported frequency <= rate and switch to it */
struct mpu_rate * ptr;
@@ -488,13 +482,13 @@ static int omap1_select_table_rate(struct clk_hw *clk_hw, unsigned long rate)
return 0;
}
-static int omap1_clk_set_rate_dsp_domain(struct clk_hw *clk_hw, unsigned long rate)
+static int omap1_clk_set_rate_dsp_domain(struct clk_hw *clk_hw, unsigned long rate, unsigned long parent_rate)
{
struct omap1_clk *clk = to_omap1_clk(clk_hw);
int dsor_exp;
u16 regval;
- dsor_exp = calc_dsor_exp(clk, rate);
+ dsor_exp = calc_dsor_exp(clk, rate, parent_rate);
if (dsor_exp > 3)
dsor_exp = -EINVAL;
if (dsor_exp < 0)
@@ -504,29 +498,29 @@ static int omap1_clk_set_rate_dsp_domain(struct clk_hw *clk_hw, unsigned long ra
regval &= ~(3 << clk->rate_offset);
regval |= dsor_exp << clk->rate_offset;
__raw_writew(regval, DSP_CKCTL);
- clk->rate = clk->parent->rate / (1 << dsor_exp);
+ clk->rate = parent_rate / (1 << dsor_exp);
return 0;
}
-static long omap1_clk_round_rate_ckctl_arm(struct clk_hw *clk_hw, unsigned long rate)
+static long omap1_clk_round_rate_ckctl_arm(struct clk_hw *clk_hw, unsigned long rate, unsigned long *parent_rate)
{
struct omap1_clk *clk = to_omap1_clk(clk_hw);
- int dsor_exp = calc_dsor_exp(clk, rate);
+ int dsor_exp = calc_dsor_exp(clk, rate, *parent_rate);
if (dsor_exp < 0)
return dsor_exp;
if (dsor_exp > 3)
dsor_exp = 3;
- return clk->parent->rate / (1 << dsor_exp);
+ return *parent_rate / (1 << dsor_exp);
}
-static int omap1_clk_set_rate_ckctl_arm(struct clk_hw *clk_hw, unsigned long rate)
+static int omap1_clk_set_rate_ckctl_arm(struct clk_hw *clk_hw, unsigned long rate, unsigned long parent_rate)
{
struct omap1_clk *clk = to_omap1_clk(clk_hw);
int dsor_exp;
u16 regval;
- dsor_exp = calc_dsor_exp(clk, rate);
+ dsor_exp = calc_dsor_exp(clk, rate, parent_rate);
if (dsor_exp > 3)
dsor_exp = -EINVAL;
if (dsor_exp < 0)
@@ -537,11 +531,11 @@ static int omap1_clk_set_rate_ckctl_arm(struct clk_hw *clk_hw, unsigned long rat
regval |= dsor_exp << clk->rate_offset;
regval = verify_ckctl_value(regval);
omap_writew(regval, ARM_CKCTL);
- clk->rate = clk->parent->rate / (1 << dsor_exp);
+ clk->rate = parent_rate / (1 << dsor_exp);
return 0;
}
-static long omap1_round_to_table_rate(struct clk_hw *clk_hw, unsigned long rate)
+static long omap1_round_to_table_rate(struct clk_hw *clk_hw, unsigned long rate, unsigned long *parent_rate)
{
/* Find the highest supported frequency <= rate */
struct mpu_rate * ptr;
@@ -592,7 +586,7 @@ static unsigned calc_ext_dsor(unsigned long rate)
}
/* XXX Only needed on 1510 */
-static int omap1_set_uart_rate(struct clk_hw *clk_hw, unsigned long rate)
+static int omap1_set_uart_rate(struct clk_hw *clk_hw, unsigned long rate, unsigned long parent_rate)
{
struct omap1_clk *clk = to_omap1_clk(clk_hw);
unsigned int val;
@@ -611,7 +605,7 @@ static int omap1_set_uart_rate(struct clk_hw *clk_hw, unsigned long rate)
}
/* External clock (MCLK & BCLK) functions */
-static int omap1_set_ext_clk_rate(struct clk_hw *clk_hw, unsigned long rate)
+static int omap1_set_ext_clk_rate(struct clk_hw *clk_hw, unsigned long rate, unsigned long parent_rate)
{
struct omap1_clk *clk = to_omap1_clk(clk_hw);
unsigned dsor;
@@ -630,16 +624,14 @@ static int omap1_set_ext_clk_rate(struct clk_hw *clk_hw, unsigned long rate)
return 0;
}
-static int omap1_set_sossi_rate(struct clk_hw *clk_hw, unsigned long rate)
+static int omap1_set_sossi_rate(struct clk_hw *clk_hw, unsigned long rate, unsigned long parent_rate)
{
struct omap1_clk *clk = to_omap1_clk(clk_hw);
u32 l;
int div;
- unsigned long p_rate;
- p_rate = clk->parent->rate;
/* Round towards slower frequency */
- div = (p_rate + rate - 1) / rate;
+ div = (parent_rate + rate - 1) / rate;
div--;
if (div < 0 || div > 7)
return -EINVAL;
@@ -649,12 +641,12 @@ static int omap1_set_sossi_rate(struct clk_hw *clk_hw, unsigned long rate)
l |= div << 17;
omap_writel(l, MOD_CONF_CTRL_1);
- clk->rate = p_rate / (div + 1);
+ clk->rate = parent_rate / (div + 1);
return 0;
}
-static long omap1_round_ext_clk_rate(struct clk_hw *clk_hw, unsigned long rate)
+static long omap1_round_ext_clk_rate(struct clk_hw *clk_hw, unsigned long rate, unsigned long *parent_rate)
{
return 96000000 / calc_ext_dsor(rate);
}
@@ -678,16 +670,27 @@ static void omap1_init_ext_clk(struct clk_hw *clk_hw)
clk-> rate = 96000000 / dsor;
}
+struct clk_hw *clk_hw_get_parent(const struct clk_hw *clk_hw)
+{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
+
+ if (!clk->parent)
+ return NULL;
+
+ return &clk->parent->clk_hw;
+}
+
static void omap1_clk_disable(struct clk_hw *clk_hw)
{
struct omap1_clk *clk = to_omap1_clk(clk_hw);
+ struct clk_hw *parent = clk_hw_get_parent(clk_hw);
if (clk->usecount > 0 && !(--clk->usecount)) {
- clk->ops->disable(&clk->clk_hw);
- if (likely(clk->parent)) {
- omap1_clk_disable(&clk->parent->clk_hw);
+ clk->ops->disable(clk_hw);
+ if (likely(parent)) {
+ omap1_clk_disable(parent);
if (clk->flags & CLOCK_NO_IDLE_PARENT)
- omap1_clk_allow_idle(&clk->parent->clk_hw);
+ omap1_clk_allow_idle(parent);
}
}
}
@@ -695,22 +698,23 @@ static void omap1_clk_disable(struct clk_hw *clk_hw)
static omap1_clk_enable(struct clk_hw *clk_hw)
{
struct omap1_clk *clk = to_omap1_clk(clk_hw);
+ struct clk_hw *parent = clk_hw_get_parent(clk_hw);
int ret = 0;
if (clk->usecount++ == 0) {
- if (clk->parent) {
- ret = omap1_clk_enable(&clk->parent->clk_hw);
+ if (parent) {
+ ret = omap1_clk_enable(parent);
if (ret)
goto err;
if (clk->flags & CLOCK_NO_IDLE_PARENT)
- omap1_clk_deny_idle(&clk->parent->clk_hw);
+ omap1_clk_deny_idle(parent);
}
ret = clk->ops->enable(&clk->clk_hw);
if (ret) {
- if (clk->parent)
- omap1_clk_disable(&clk->parent->clk_hw);
+ if (parent)
+ omap1_clk_disable(parent);
goto err;
}
}
@@ -771,7 +775,7 @@ static const struct clk_ops clkops_generic = {
.disable = omap1_clk_disable_generic,
};
-static unsigned long omap1_ckctl_recalc_dsp_domain(struct clk_hw *clk_hw)
+static unsigned long omap1_ckctl_recalc_dsp_domain(struct clk_hw *clk_hw, unsigned long parent_rate)
{
struct omap1_clk *clk = to_omap1_clk(clk_hw);
int dsor;
@@ -787,7 +791,7 @@ static unsigned long omap1_ckctl_recalc_dsp_domain(struct clk_hw *clk_hw)
dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset));
omap1_clk_disable(api_ck_p);
- return clk->parent->rate / dsor;
+ return parent_rate / dsor;
}
static int omap1_clk_enable_dsp_domain(struct clk_hw *clk_hw)
@@ -812,11 +816,6 @@ static void omap1_clk_disable_dsp_domain(struct clk_hw *clk_hw)
}
}
-static const struct clk_ops clkops_dspck = {
- .enable = omap1_clk_enable_dsp_domain,
- .disable = omap1_clk_disable_dsp_domain,
-};
-
/* XXX SYSC register handling does not belong in the clock framework */
static int omap1_clk_enable_uart_functional_16xx(struct clk_hw *clk_hw)
{
@@ -857,9 +856,20 @@ static const struct clk_ops clkops_uart_16xx = {
static long omap1_clk_round_rate(struct clk_hw *clk_hw, unsigned long rate)
{
struct omap1_clk *clk = to_omap1_clk(clk_hw);
+ struct clk_hw *parent = clk_hw_get_parent(clk_hw);
+ struct omap1_clk *parent_clk;
+ unsigned long parent_rate = 0;
+
+ if (parent) {
+ parent_clk = to_omap1_clk(parent);
+ parent_rate = parent_clk->rate;
+ }
+
+ if (clk->ops->round_rate != NULL)
+ return clk->ops->round_rate(clk_hw, rate, &parent_rate);
- if (clk->round_rate != NULL)
- return clk->round_rate(clk_hw, rate);
+ if (parent)
+ parent_clk->rate = parent_rate;
return clk->rate;
}
@@ -867,10 +877,15 @@ static long omap1_clk_round_rate(struct clk_hw *clk_hw, unsigned long rate)
static int omap1_clk_set_rate(struct clk_hw *clk_hw, unsigned long rate)
{
struct omap1_clk *clk = to_omap1_clk(clk_hw);
+ struct clk_hw *parent = clk_hw_get_parent(clk_hw);
+ unsigned long parent_rate = 0;
int ret = -EINVAL;
- if (clk->set_rate)
- ret = clk->set_rate(clk_hw, rate);
+ if (parent)
+ parent_rate = to_omap1_clk(parent)->rate;
+
+ if (clk->ops->set_rate)
+ ret = clk->ops->set_rate(clk_hw, rate, parent_rate);
return ret;
}
@@ -880,8 +895,8 @@ static void propagate_rate(struct omap1_clk *tclk)
struct omap1_clk *clkp;
list_for_each_entry(clkp, &tclk->children, sibling) {
- if (clkp->recalc)
- clkp->rate = clkp->recalc(&clkp->clk_hw);
+ if (clkp->ops->recalc_rate)
+ clkp->rate = clkp->ops->recalc_rate(&clkp->clk_hw, tclk->rate);
propagate_rate(clkp);
}
}
@@ -993,9 +1008,12 @@ EXPORT_SYMBOL(clk_set_parent);
struct clk *clk_get_parent(struct clk *clk)
{
- struct omap1_clk *parent = to_omap1_clk(clk->clk_hw)->parent;
+ struct clk_hw *parent = clk_hw_get_parent(clk->clk_hw);
+
+ if (!parent)
+ return NULL;
- return &parent->clk_hw.clk;
+ return &parent->clk;
}
EXPORT_SYMBOL(clk_get_parent);
@@ -1004,24 +1022,22 @@ EXPORT_SYMBOL(clk_get_parent);
*/
/* Used for clocks that always have same value as the parent clock */
-static unsigned long followparent_recalc(struct clk_hw *clk_hw)
+static unsigned long followparent_recalc(struct clk_hw *clk_hw, unsigned long parent_rate)
{
- struct omap1_clk *clk = to_omap1_clk(clk_hw);
-
- return clk->parent->rate;
+ return parent_rate;
}
/*
* Used for clocks that have the same value as the parent clock,
* divided by some factor
*/
-static unsigned long omap_fixed_divisor_recalc(struct clk_hw *clk_hw)
+static unsigned long omap_fixed_divisor_recalc(struct clk_hw *clk_hw, unsigned long parent_rate)
{
struct omap1_clk *clk = to_omap1_clk(clk_hw);
WARN_ON(!clk->fixed_div);
- return clk->parent->rate / clk->fixed_div;
+ return parent_rate / clk->fixed_div;
}
/**
@@ -1056,8 +1072,8 @@ static int clk_register(struct device *dev, struct clk_hw *clk_hw)
list_add(&clk->sibling, &clk->parent->children);
list_add(&clk->node, &clocks);
- if (clk->init)
- clk->init(&clk->clk_hw);
+ if (clk->ops->init)
+ clk->ops->init(&clk->clk_hw);
mutex_unlock(&clocks_mutex);
return 0;
@@ -1080,6 +1096,12 @@ static const struct clk_ops clkops_null = {
.disable = clkll_disable_null,
};
+static const struct clk_ops clkops_followparent = {
+ .enable = clkll_enable_null,
+ .disable = clkll_disable_null,
+ .recalc_rate = followparent_recalc,
+};
+
/*
* Dummy clock
*
@@ -1239,6 +1261,12 @@ static struct omap1_clk ck_dpll1 = {
.parent = &ck_ref,
};
+static const struct clk_ops clkops_generic_followparent = {
+ .enable = omap1_clk_enable_generic,
+ .disable = omap1_clk_disable_generic,
+ .recalc_rate = followparent_recalc,
+};
+
/*
* FIXME: This clock seems to be necessary but no-one has asked for its
* activation. [ FIX: SoSSI, SSR ]
@@ -1246,33 +1274,50 @@ static struct omap1_clk ck_dpll1 = {
static struct arm_idlect1_clk ck_dpll1out = {
.clk = {
.name = "ck_dpll1out",
- .ops = &clkops_generic,
+ .ops = &clkops_generic_followparent,
.parent = &ck_dpll1,
.flags = CLOCK_IDLE_CONTROL | ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_CKOUT_ARM,
- .recalc = &followparent_recalc,
},
.idlect_shift = IDL_CLKOUT_ARM_SHIFT,
};
+static const struct clk_ops clkops_sossi = {
+ .enable = omap1_clk_enable_generic,
+ .disable = omap1_clk_disable_generic,
+ .recalc_rate = &omap1_sossi_recalc,
+ .set_rate = &omap1_set_sossi_rate,
+};
+
static struct omap1_clk sossi_ck = {
.name = "ck_sossi",
- .ops = &clkops_generic,
+ .ops = &clkops_sossi,
.parent = &ck_dpll1out.clk,
.flags = CLOCK_NO_IDLE_PARENT | ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1),
.enable_bit = CONF_MOD_SOSSI_CLK_EN_R,
- .recalc = &omap1_sossi_recalc,
- .set_rate = &omap1_set_sossi_rate,
+};
+
+struct clk_ops clkops_null_ckctl = {
+ .enable = clkll_enable_null,
+ .disable = clkll_disable_null,
+ .recalc_rate = omap1_ckctl_recalc,
+ .round_rate = omap1_clk_round_rate_ckctl_arm,
+ .set_rate = omap1_clk_set_rate_ckctl_arm,
};
static struct omap1_clk arm_ck = {
.name = "arm_ck",
- .ops = &clkops_null,
+ .ops = &clkops_null_ckctl,
.parent = &ck_dpll1,
.rate_offset = CKCTL_ARMDIV_OFFSET,
- .recalc = &omap1_ckctl_recalc,
+};
+
+struct clk_ops clkops_generic_ckctl = {
+ .enable = omap1_clk_enable_generic,
+ .disable = omap1_clk_disable_generic,
+ .recalc_rate = omap1_ckctl_recalc,
.round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_rate_ckctl_arm,
};
@@ -1280,15 +1325,12 @@ static struct omap1_clk arm_ck = {
static struct arm_idlect1_clk armper_ck = {
.clk = {
.name = "armper_ck",
- .ops = &clkops_generic,
+ .ops = &clkops_generic_ckctl,
.parent = &ck_dpll1,
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_PERCK,
.rate_offset = CKCTL_PERDIV_OFFSET,
- .recalc = &omap1_ckctl_recalc,
- .round_rate = omap1_clk_round_rate_ckctl_arm,
- .set_rate = omap1_clk_set_rate_ckctl_arm,
},
.idlect_shift = IDLPER_ARM_SHIFT,
};
@@ -1299,22 +1341,20 @@ static struct arm_idlect1_clk armper_ck = {
*/
static struct omap1_clk arm_gpio_ck = {
.name = "ick",
- .ops = &clkops_generic,
+ .ops = &clkops_generic_followparent,
.parent = &ck_dpll1,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_GPIOCK,
- .recalc = &followparent_recalc,
};
static struct arm_idlect1_clk armxor_ck = {
.clk = {
.name = "armxor_ck",
- .ops = &clkops_generic,
+ .ops = &clkops_generic_followparent,
.parent = &ck_ref,
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_XORPCK,
- .recalc = &followparent_recalc,
},
.idlect_shift = IDLXORP_ARM_SHIFT,
};
@@ -1322,16 +1362,21 @@ static struct arm_idlect1_clk armxor_ck = {
static struct arm_idlect1_clk armtim_ck = {
.clk = {
.name = "armtim_ck",
- .ops = &clkops_generic,
+ .ops = &clkops_generic_followparent,
.parent = &ck_ref,
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_TIMCK,
- .recalc = &followparent_recalc,
},
.idlect_shift = IDLTIM_ARM_SHIFT,
};
+static const struct clk_ops clkops_fixed_divisor = {
+ .enable = omap1_clk_enable_generic,
+ .disable = omap1_clk_disable_generic,
+ .recalc_rate = omap_fixed_divisor_recalc,
+};
+
static struct arm_idlect1_clk armwdt_ck = {
.clk = {
.name = "armwdt_ck",
@@ -1341,16 +1386,14 @@ static struct arm_idlect1_clk armwdt_ck = {
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_WDTCK,
.fixed_div = 14,
- .recalc = &omap_fixed_divisor_recalc,
},
.idlect_shift = IDLWDT_ARM_SHIFT,
};
static struct omap1_clk arminth_ck16xx = {
.name = "arminth_ck",
- .ops = &clkops_null,
+ .ops = &clkops_followparent,
.parent = &arm_ck,
- .recalc = &followparent_recalc,
/* Note: On 16xx the frequency can be divided by 2 by programming
* ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
*
@@ -1360,24 +1403,26 @@ static struct omap1_clk arminth_ck16xx = {
static struct omap1_clk dsp_ck = {
.name = "dsp_ck",
- .ops = &clkops_generic,
+ .ops = &clkops_generic_ckctl,
.parent = &ck_dpll1,
.enable_reg = OMAP1_IO_ADDRESS(ARM_CKCTL),
.enable_bit = EN_DSPCK,
.rate_offset = CKCTL_DSPDIV_OFFSET,
- .recalc = &omap1_ckctl_recalc,
- .round_rate = omap1_clk_round_rate_ckctl_arm,
- .set_rate = omap1_clk_set_rate_ckctl_arm,
};
static struct omap1_clk dspmmu_ck = {
.name = "dspmmu_ck",
- .ops = &clkops_null,
+ .ops = &clkops_null_ckctl,
.parent = &ck_dpll1,
.rate_offset = CKCTL_DSPMMUDIV_OFFSET,
- .recalc = &omap1_ckctl_recalc,
+};
+
+static const struct clk_ops clkops_dspck = {
+ .enable = omap1_clk_enable_dsp_domain,
+ .disable = omap1_clk_disable_dsp_domain,
+ .recalc_rate = omap1_ckctl_recalc_dsp_domain,
.round_rate = omap1_clk_round_rate_ckctl_arm,
- .set_rate = omap1_clk_set_rate_ckctl_arm,
+ .set_rate = omap1_clk_set_rate_dsp_domain,
};
static struct omap1_clk dspper_ck = {
@@ -1387,48 +1432,45 @@ static struct omap1_clk dspper_ck = {
.enable_reg = DSP_IDLECT2,
.enable_bit = EN_PERCK,
.rate_offset = CKCTL_PERDIV_OFFSET,
- .recalc = &omap1_ckctl_recalc_dsp_domain,
- .round_rate = omap1_clk_round_rate_ckctl_arm,
- .set_rate = &omap1_clk_set_rate_dsp_domain,
+};
+
+static const struct clk_ops clkops_dspck_followparent = {
+ .enable = omap1_clk_enable_dsp_domain,
+ .disable = omap1_clk_disable_dsp_domain,
+ .recalc_rate = followparent_recalc,
};
static struct omap1_clk dspxor_ck = {
.name = "dspxor_ck",
- .ops = &clkops_dspck,
+ .ops = &clkops_dspck_followparent,
.parent = &ck_ref,
.enable_reg = DSP_IDLECT2,
.enable_bit = EN_XORPCK,
- .recalc = &followparent_recalc,
};
static struct omap1_clk dsptim_ck = {
.name = "dsptim_ck",
- .ops = &clkops_dspck,
+ .ops = &clkops_dspck_followparent,
.parent = &ck_ref,
.enable_reg = DSP_IDLECT2,
.enable_bit = EN_DSPTIMCK,
- .recalc = &followparent_recalc,
};
static struct arm_idlect1_clk tc_ck = {
.clk = {
.name = "tc_ck",
- .ops = &clkops_null,
+ .ops = &clkops_null_ckctl,
.parent = &ck_dpll1,
.flags = CLOCK_IDLE_CONTROL,
.rate_offset = CKCTL_TCDIV_OFFSET,
- .recalc = &omap1_ckctl_recalc,
- .round_rate = omap1_clk_round_rate_ckctl_arm,
- .set_rate = omap1_clk_set_rate_ckctl_arm,
},
.idlect_shift = IDLIF_ARM_SHIFT,
};
static struct omap1_clk arminth_ck1510 = {
.name = "arminth_ck",
- .ops = &clkops_null,
+ .ops = &clkops_followparent,
.parent = &tc_ck.clk,
- .recalc = &followparent_recalc,
/* Note: On 1510 the frequency follows TC_CK
*
* 16xx version is in MPU clocks.
@@ -1438,28 +1480,25 @@ static struct omap1_clk arminth_ck1510 = {
static struct omap1_clk tipb_ck = {
/* No-idle controlled by "tc_ck" */
.name = "tipb_ck",
- .ops = &clkops_null,
+ .ops = &clkops_followparent,
.parent = &tc_ck.clk,
- .recalc = &followparent_recalc,
};
static struct omap1_clk l3_ocpi_ck = {
/* No-idle controlled by "tc_ck" */
.name = "l3_ocpi_ck",
- .ops = &clkops_generic,
+ .ops = &clkops_generic_followparent,
.parent = &tc_ck.clk,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3),
.enable_bit = EN_OCPI_CK,
- .recalc = &followparent_recalc,
};
static struct omap1_clk tc1_ck = {
.name = "tc1_ck",
- .ops = &clkops_generic,
+ .ops = &clkops_generic_followparent,
.parent = &tc_ck.clk,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3),
.enable_bit = EN_TC1_CK,
- .recalc = &followparent_recalc,
};
/*
@@ -1468,37 +1507,33 @@ static struct omap1_clk tc1_ck = {
*/
static struct omap1_clk tc2_ck = {
.name = "tc2_ck",
- .ops = &clkops_generic,
+ .ops = &clkops_generic_followparent,
.parent = &tc_ck.clk,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3),
.enable_bit = EN_TC2_CK,
- .recalc = &followparent_recalc,
};
static struct omap1_clk dma_ck = {
/* No-idle controlled by "tc_ck" */
.name = "dma_ck",
- .ops = &clkops_null,
+ .ops = &clkops_followparent,
.parent = &tc_ck.clk,
- .recalc = &followparent_recalc,
};
static struct omap1_clk dma_lcdfree_ck = {
.name = "dma_lcdfree_ck",
- .ops = &clkops_null,
+ .ops = &clkops_followparent,
.parent = &tc_ck.clk,
- .recalc = &followparent_recalc,
};
static struct arm_idlect1_clk api_ck = {
.clk = {
.name = "api_ck",
- .ops = &clkops_generic,
+ .ops = &clkops_generic_followparent,
.parent = &tc_ck.clk,
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_APICK,
- .recalc = &followparent_recalc,
},
.idlect_shift = IDLAPI_ARM_SHIFT,
};
@@ -1506,58 +1541,56 @@ static struct arm_idlect1_clk api_ck = {
static struct arm_idlect1_clk lb_ck = {
.clk = {
.name = "lb_ck",
- .ops = &clkops_generic,
+ .ops = &clkops_generic_followparent,
.parent = &tc_ck.clk,
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_LBCK,
- .recalc = &followparent_recalc,
},
.idlect_shift = IDLLB_ARM_SHIFT,
};
static struct omap1_clk rhea1_ck = {
.name = "rhea1_ck",
- .ops = &clkops_null,
+ .ops = &clkops_followparent,
.parent = &tc_ck.clk,
- .recalc = &followparent_recalc,
};
static struct omap1_clk rhea2_ck = {
.name = "rhea2_ck",
- .ops = &clkops_null,
+ .ops = &clkops_followparent,
.parent = &tc_ck.clk,
- .recalc = &followparent_recalc,
};
static struct omap1_clk lcd_ck_16xx = {
.name = "lcd_ck",
- .ops = &clkops_generic,
+ .ops = &clkops_generic_ckctl,
.parent = &ck_dpll1,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_LCDCK,
.rate_offset = CKCTL_LCDDIV_OFFSET,
- .recalc = &omap1_ckctl_recalc,
- .round_rate = omap1_clk_round_rate_ckctl_arm,
- .set_rate = omap1_clk_set_rate_ckctl_arm,
};
static struct arm_idlect1_clk lcd_ck_1510 = {
.clk = {
.name = "lcd_ck",
- .ops = &clkops_generic,
+ .ops = &clkops_generic_ckctl,
.parent = &ck_dpll1,
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_LCDCK,
.rate_offset = CKCTL_LCDDIV_OFFSET,
- .recalc = &omap1_ckctl_recalc,
- .round_rate = omap1_clk_round_rate_ckctl_arm,
- .set_rate = omap1_clk_set_rate_ckctl_arm,
},
.idlect_shift = OMAP1510_IDLLCD_ARM_SHIFT,
};
+static const struct clk_ops clkops_uart = {
+ .enable = clkll_enable_null,
+ .disable = clkll_disable_null,
+ .set_rate = omap1_set_uart_rate,
+ .recalc_rate = omap1_uart_recalc,
+};
+
/*
* XXX The enable_bit here is misused - it simply switches between 12MHz
* and 48MHz. Reimplement with clksel.
@@ -1566,15 +1599,13 @@ static struct arm_idlect1_clk lcd_ck_1510 = {
*/
static struct omap1_clk uart1_1510 = {
.name = "uart1_ck",
- .ops = &clkops_null,
+ .ops = &clkops_uart,
/* Direct from ULPD, no real parent */
.parent = &armper_ck.clk,
.rate = 12000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = CONF_MOD_UART1_CLK_MODE_R,
- .set_rate = &omap1_set_uart_rate,
- .recalc = &omap1_uart_recalc,
};
/*
@@ -1605,15 +1636,13 @@ static struct uart_clk uart1_16xx = {
*/
static struct omap1_clk uart2_ck = {
.name = "uart2_ck",
- .ops = &clkops_null,
+ .ops = &clkops_uart,
/* Direct from ULPD, no real parent */
.parent = &armper_ck.clk,
.rate = 12000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = CONF_MOD_UART2_CLK_MODE_R,
- .set_rate = &omap1_set_uart_rate,
- .recalc = &omap1_uart_recalc,
};
/*
@@ -1624,15 +1653,13 @@ static struct omap1_clk uart2_ck = {
*/
static struct omap1_clk uart3_1510 = {
.name = "uart3_ck",
- .ops = &clkops_null,
+ .ops = &clkops_uart,
/* Direct from ULPD, no real parent */
.parent = &armper_ck.clk,
.rate = 12000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = CONF_MOD_UART3_CLK_MODE_R,
- .set_rate = &omap1_set_uart_rate,
- .recalc = &omap1_uart_recalc,
};
/*
@@ -1722,15 +1749,20 @@ static struct omap1_clk mclk_1510 = {
.enable_bit = SOFT_COM_MCKO_REQ_SHIFT,
};
+static const struct clk_ops clkops_ext_clk = {
+ .enable = omap1_clk_enable_generic,
+ .disable = omap1_clk_disable_generic,
+ .set_rate = omap1_set_ext_clk_rate,
+ .round_rate = omap1_round_ext_clk_rate,
+ .init = omap1_init_ext_clk,
+};
+
static struct omap1_clk mclk_16xx = {
.name = "mclk",
- .ops = &clkops_generic,
+ .ops = &clkops_ext_clk,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
.enable_reg = OMAP1_IO_ADDRESS(COM_CLK_DIV_CTRL_SEL),
.enable_bit = COM_ULPD_PLL_CLK_REQ,
- .set_rate = &omap1_set_ext_clk_rate,
- .round_rate = &omap1_round_ext_clk_rate,
- .init = &omap1_init_ext_clk,
};
static struct omap1_clk bclk_1510 = {
@@ -1742,13 +1774,10 @@ static struct omap1_clk bclk_1510 = {
static struct omap1_clk bclk_16xx = {
.name = "bclk",
- .ops = &clkops_generic,
+ .ops = &clkops_ext_clk,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
.enable_reg = OMAP1_IO_ADDRESS(SWD_CLK_DIV_CTRL_SEL),
.enable_bit = SWD_ULPD_PLL_CLK_REQ,
- .set_rate = &omap1_set_ext_clk_rate,
- .round_rate = &omap1_round_ext_clk_rate,
- .init = &omap1_init_ext_clk,
};
static struct omap1_clk mmc1_ck = {
@@ -1788,31 +1817,34 @@ static struct omap1_clk mmc3_ck = {
.enable_bit = SOFT_MMC_DPLL_REQ_SHIFT,
};
+static const struct clk_ops clkops_mpu = {
+ .enable = clkll_enable_null,
+ .disable = clkll_disable_null,
+ .recalc_rate = followparent_recalc,
+ .set_rate = omap1_select_table_rate,
+ .round_rate = omap1_round_to_table_rate,
+};
+
static struct omap1_clk virtual_ck_mpu = {
.name = "mpu",
- .ops = &clkops_null,
+ .ops = &clkops_mpu,
.parent = &arm_ck, /* Is smarter alias for */
- .recalc = &followparent_recalc,
- .set_rate = &omap1_select_table_rate,
- .round_rate = &omap1_round_to_table_rate,
};
/* virtual functional clock domain for I2C. Just for making sure that ARMXOR_CK
remains active during MPU idle whenever this is enabled */
static struct omap1_clk i2c_fck = {
.name = "i2c_fck",
- .ops = &clkops_null,
+ .ops = &clkops_followparent,
.flags = CLOCK_NO_IDLE_PARENT,
.parent = &armxor_ck.clk,
- .recalc = &followparent_recalc,
};
static struct omap1_clk i2c_ick = {
.name = "i2c_ick",
- .ops = &clkops_null,
+ .ops = &clkops_followparent,
.flags = CLOCK_NO_IDLE_PARENT,
.parent = &armper_ck.clk,
- .recalc = &followparent_recalc,
};
/*
@@ -2057,7 +2089,7 @@ void __init omap1_clk_late_init(void)
unsigned long rate = ck_dpll1.rate;
/* Find the highest supported frequency and enable it */
- if (omap1_select_table_rate(&virtual_ck_mpu.clk_hw, ~0)) {
+ if (omap1_select_table_rate(&virtual_ck_mpu.clk_hw, ~0, 0)) {
pr_err("System frequencies not set, using default. Check your config.\n");
/*
* Reprogramming the DPLL is tricky, it must be done from SRAM.
--
2.20.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 18/22] ARM: omap1: clk: rework 'struct clk'
From: Arnd Bergmann @ 2019-08-08 21:41 UTC (permalink / raw)
To: Tony Lindgren, Aaro Koskinen, Paul Walmsley
Cc: Arnd Bergmann, Bartlomiej Zolnierkiewicz, Greg Kroah-Hartman,
Linus Walleij, linux-kernel, Tomi Valkeinen, linux-omap,
linux-arm-kernel
In-Reply-To: <20190808214232.2798396-1-arnd@arndb.de>
To get closer to the way the common_clk code works, rename
the omap1 struct clk to 'omap1_clk', and add trivial 'clk_hw'
and 'clk' wrapper to work like the generic counterparts.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
arch/arm/mach-omap1/clock.c | 364 ++++++++++++++++++++----------------
1 file changed, 205 insertions(+), 159 deletions(-)
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index b2b0355fae4c..577686f61b3b 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -28,20 +28,20 @@
#include "sram.h"
#include "usb.h"
-struct clk;
+struct omap1_clk;
-struct omap_clk {
+struct omap1_clk_lookup {
u16 cpu;
struct clk_lookup lk;
};
#define CLK(dev, con, ck, cp) \
{ \
- .cpu = cp, \
+ .cpu = cp, \
.lk = { \
+ .clk_hw = (&(ck)->clk_hw), \
.dev_id = dev, \
.con_id = con, \
- .clk = ck, \
}, \
}
@@ -53,7 +53,7 @@ struct omap_clk {
#define CK_1710 (1 << 4) /* 1710 extra for rate selection */
/**
- * struct clkops - some clock function pointers
+ * struct clk_ops - some clock function pointers
* @enable: fn ptr that enables the current clock in hardware
* @disable: fn ptr that enables the current clock in hardware
*
@@ -65,13 +65,13 @@ struct omap_clk {
* runtime calls in place of clk_enable()/clk_disable(), @find_idlest and
* @find_companion must, unfortunately, remain.
*/
-struct clkops {
- int (*enable)(struct clk *);
- void (*disable)(struct clk *);
+struct clk_ops {
+ int (*enable)(struct clk_hw *);
+ void (*disable)(struct clk_hw *);
};
/*
- * struct clk.flags possibilities
+ * struct omap1_clk.flags possibilities
*
* XXX document the rest of the clock flags here
*
@@ -81,7 +81,7 @@ struct clkops {
#define CLOCK_NO_IDLE_PARENT (1 << 2)
/**
- * struct clk - OMAP struct clk
+ * struct omap1_clk - OMAP struct clk
* @node: list_head connecting this clock into the full clock list
* @ops: struct clkops * for this clock
* @name: the name of the clock in the hardware (used in hwmod data and debug)
@@ -121,18 +121,27 @@ struct clkops {
* separated from the clock's target rate.
*/
struct clk {
+ struct clk_hw *clk_hw;
+};
+
+struct clk_hw {
+ struct clk clk;
+};
+
+struct omap1_clk {
+ struct clk_hw clk_hw;
struct list_head node;
- const struct clkops *ops;
+ const struct clk_ops *ops;
const char *name;
- struct clk *parent;
+ struct omap1_clk *parent;
struct list_head children;
struct list_head sibling; /* node for children */
unsigned long rate;
void __iomem *enable_reg;
- unsigned long (*recalc)(struct clk *);
- int (*set_rate)(struct clk *, unsigned long);
- long (*round_rate)(struct clk *, unsigned long);
- void (*init)(struct clk *);
+ unsigned long (*recalc)(struct clk_hw *);
+ int (*set_rate)(struct clk_hw *, unsigned long);
+ long (*round_rate)(struct clk_hw *, unsigned long);
+ void (*init)(struct clk_hw *);
u8 enable_bit;
s8 usecount;
u8 fixed_div;
@@ -143,14 +152,16 @@ struct clk {
#endif
};
+#define to_omap1_clk(__hw) container_of((__hw), struct omap1_clk, clk_hw)
+
struct uart_clk {
- struct clk clk;
+ struct omap1_clk clk;
unsigned long sysc_addr;
};
/* Provide a method for preventing idling some ARM IDLECT clocks */
struct arm_idlect1_clk {
- struct clk clk;
+ struct omap1_clk clk;
unsigned long no_idle_count;
__u8 idlect_shift;
};
@@ -217,20 +228,20 @@ static u32 cpu_mask;
#define IDLXORP_ARM_SHIFT 1
#define IDLWDT_ARM_SHIFT 0
-/* Some MOD_CONF_CTRL_0 bit shifts - used in struct clk.enable_bit */
+/* Some MOD_CONF_CTRL_0 bit shifts - used in struct omap1_clk.enable_bit */
#define CONF_MOD_UART3_CLK_MODE_R 31
#define CONF_MOD_UART2_CLK_MODE_R 30
#define CONF_MOD_UART1_CLK_MODE_R 29
#define CONF_MOD_MMC_SD_CLK_REQ_R 23
#define CONF_MOD_MCBSP3_AUXON 20
-/* Some MOD_CONF_CTRL_1 bit shifts - used in struct clk.enable_bit */
+/* Some MOD_CONF_CTRL_1 bit shifts - used in struct omap1_clk.enable_bit */
#define CONF_MOD_SOSSI_CLK_EN_R 16
/* Some OTG_SYSCON_2-specific bit fields */
#define OTG_SYSCON_2_UHOST_EN_SHIFT 8
-/* Some SOFT_REQ_REG bit fields - used in struct clk.enable_bit */
+/* Some SOFT_REQ_REG bit fields - used in struct omap1_clk.enable_bit */
#define SOFT_MMC2_DPLL_REQ_SHIFT 13
#define SOFT_MMC_DPLL_REQ_SHIFT 12
#define SOFT_UART3_DPLL_REQ_SHIFT 11
@@ -247,7 +258,7 @@ static u32 cpu_mask;
#define SOFT_DPLL_REQ_SHIFT 0
__u32 arm_idlect1_mask;
-static struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;
+static struct clk_hw *api_ck_p, *ck_dpll1_p, *ck_ref_p;
static LIST_HEAD(clocks);
static DEFINE_MUTEX(clocks_mutex);
@@ -257,14 +268,16 @@ static DEFINE_SPINLOCK(clockfw_lock);
* Omap1 specific clock functions
*/
-static unsigned long omap1_uart_recalc(struct clk *clk)
+static unsigned long omap1_uart_recalc(struct clk_hw *clk_hw)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
unsigned int val = __raw_readl(clk->enable_reg);
return val & clk->enable_bit ? 48000000 : 12000000;
}
-static unsigned long omap1_sossi_recalc(struct clk *clk)
+static unsigned long omap1_sossi_recalc(struct clk_hw *clk_hw)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
u32 div = omap_readl(MOD_CONF_CTRL_1);
div = (div >> 17) & 0x7;
@@ -273,9 +286,10 @@ static unsigned long omap1_sossi_recalc(struct clk *clk)
return clk->parent->rate / div;
}
-static void omap1_clk_allow_idle(struct clk *clk)
+static void omap1_clk_allow_idle(struct clk_hw *clk_hw)
{
- struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
+ struct arm_idlect1_clk * iclk = container_of(clk, struct arm_idlect1_clk, clk);
if (!(clk->flags & CLOCK_IDLE_CONTROL))
return;
@@ -284,9 +298,10 @@ static void omap1_clk_allow_idle(struct clk *clk)
arm_idlect1_mask |= 1 << iclk->idlect_shift;
}
-static void omap1_clk_deny_idle(struct clk *clk)
+static void omap1_clk_deny_idle(struct clk_hw *clk_hw)
{
- struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
+ struct arm_idlect1_clk * iclk = container_of(clk, struct arm_idlect1_clk, clk);
if (!(clk->flags & CLOCK_IDLE_CONTROL))
return;
@@ -348,7 +363,7 @@ static __u16 verify_ckctl_value(__u16 newval)
return newval;
}
-static int calc_dsor_exp(struct clk *clk, unsigned long rate)
+static int calc_dsor_exp(struct omap1_clk *clk, unsigned long rate)
{
/* Note: If target frequency is too low, this function will return 4,
* which is invalid value. Caller must check for this value and act
@@ -362,7 +377,7 @@ static int calc_dsor_exp(struct clk *clk, unsigned long rate)
* DSPMMU_CK >= TC_CK
*/
unsigned long realrate;
- struct clk * parent;
+ struct omap1_clk * parent;
unsigned dsor_exp;
parent = clk->parent;
@@ -380,8 +395,9 @@ static int calc_dsor_exp(struct clk *clk, unsigned long rate)
return dsor_exp;
}
-static unsigned long omap1_ckctl_recalc(struct clk *clk)
+static unsigned long omap1_ckctl_recalc(struct clk_hw *clk_hw)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
/* Calculate divisor encoded as 2-bit exponent */
int dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
@@ -437,13 +453,13 @@ static struct mpu_rate omap1_rate_table[] = {
};
/* MPU virtual clock functions */
-static int omap1_select_table_rate(struct clk *clk, unsigned long rate)
+static int omap1_select_table_rate(struct clk_hw *clk_hw, unsigned long rate)
{
/* Find the highest supported frequency <= rate and switch to it */
struct mpu_rate * ptr;
unsigned long ref_rate;
- ref_rate = ck_ref_p->rate;
+ ref_rate = to_omap1_clk(ck_ref_p)->rate;
for (ptr = omap1_rate_table; ptr->rate; ptr++) {
if (!(ptr->flags & cpu_mask))
@@ -467,13 +483,14 @@ static int omap1_select_table_rate(struct clk *clk, unsigned long rate)
omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val);
/* XXX Do we need to recalculate the tree below DPLL1 at this point? */
- ck_dpll1_p->rate = ptr->pll_rate;
+ to_omap1_clk(ck_dpll1_p)->rate = ptr->pll_rate;
return 0;
}
-static int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate)
+static int omap1_clk_set_rate_dsp_domain(struct clk_hw *clk_hw, unsigned long rate)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
int dsor_exp;
u16 regval;
@@ -492,8 +509,9 @@ static int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate)
return 0;
}
-static long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate)
+static long omap1_clk_round_rate_ckctl_arm(struct clk_hw *clk_hw, unsigned long rate)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
int dsor_exp = calc_dsor_exp(clk, rate);
if (dsor_exp < 0)
return dsor_exp;
@@ -502,8 +520,9 @@ static long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate)
return clk->parent->rate / (1 << dsor_exp);
}
-static int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate)
+static int omap1_clk_set_rate_ckctl_arm(struct clk_hw *clk_hw, unsigned long rate)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
int dsor_exp;
u16 regval;
@@ -522,14 +541,14 @@ static int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate)
return 0;
}
-static long omap1_round_to_table_rate(struct clk *clk, unsigned long rate)
+static long omap1_round_to_table_rate(struct clk_hw *clk_hw, unsigned long rate)
{
/* Find the highest supported frequency <= rate */
struct mpu_rate * ptr;
long highest_rate;
unsigned long ref_rate;
- ref_rate = ck_ref_p->rate;
+ ref_rate = to_omap1_clk(ck_ref_p)->rate;
highest_rate = -EINVAL;
@@ -573,8 +592,9 @@ static unsigned calc_ext_dsor(unsigned long rate)
}
/* XXX Only needed on 1510 */
-static int omap1_set_uart_rate(struct clk *clk, unsigned long rate)
+static int omap1_set_uart_rate(struct clk_hw *clk_hw, unsigned long rate)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
unsigned int val;
val = __raw_readl(clk->enable_reg);
@@ -591,8 +611,9 @@ static int omap1_set_uart_rate(struct clk *clk, unsigned long rate)
}
/* External clock (MCLK & BCLK) functions */
-static int omap1_set_ext_clk_rate(struct clk *clk, unsigned long rate)
+static int omap1_set_ext_clk_rate(struct clk_hw *clk_hw, unsigned long rate)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
unsigned dsor;
__u16 ratio_bits;
@@ -609,8 +630,9 @@ static int omap1_set_ext_clk_rate(struct clk *clk, unsigned long rate)
return 0;
}
-static int omap1_set_sossi_rate(struct clk *clk, unsigned long rate)
+static int omap1_set_sossi_rate(struct clk_hw *clk_hw, unsigned long rate)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
u32 l;
int div;
unsigned long p_rate;
@@ -632,13 +654,14 @@ static int omap1_set_sossi_rate(struct clk *clk, unsigned long rate)
return 0;
}
-static long omap1_round_ext_clk_rate(struct clk *clk, unsigned long rate)
+static long omap1_round_ext_clk_rate(struct clk_hw *clk_hw, unsigned long rate)
{
return 96000000 / calc_ext_dsor(rate);
}
-static void omap1_init_ext_clk(struct clk *clk)
+static void omap1_init_ext_clk(struct clk_hw *clk_hw)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
unsigned dsor;
__u16 ratio_bits;
@@ -655,36 +678,39 @@ static void omap1_init_ext_clk(struct clk *clk)
clk-> rate = 96000000 / dsor;
}
-static void omap1_clk_disable(struct clk *clk)
+static void omap1_clk_disable(struct clk_hw *clk_hw)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
+
if (clk->usecount > 0 && !(--clk->usecount)) {
- clk->ops->disable(clk);
+ clk->ops->disable(&clk->clk_hw);
if (likely(clk->parent)) {
- omap1_clk_disable(clk->parent);
+ omap1_clk_disable(&clk->parent->clk_hw);
if (clk->flags & CLOCK_NO_IDLE_PARENT)
- omap1_clk_allow_idle(clk->parent);
+ omap1_clk_allow_idle(&clk->parent->clk_hw);
}
}
}
-static omap1_clk_enable(struct clk *clk)
+static omap1_clk_enable(struct clk_hw *clk_hw)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
int ret = 0;
if (clk->usecount++ == 0) {
if (clk->parent) {
- ret = omap1_clk_enable(clk->parent);
+ ret = omap1_clk_enable(&clk->parent->clk_hw);
if (ret)
goto err;
if (clk->flags & CLOCK_NO_IDLE_PARENT)
- omap1_clk_deny_idle(clk->parent);
+ omap1_clk_deny_idle(&clk->parent->clk_hw);
}
- ret = clk->ops->enable(clk);
+ ret = clk->ops->enable(&clk->clk_hw);
if (ret) {
if (clk->parent)
- omap1_clk_disable(clk->parent);
+ omap1_clk_disable(&clk->parent->clk_hw);
goto err;
}
}
@@ -695,8 +721,9 @@ static omap1_clk_enable(struct clk *clk)
return ret;
}
-static int omap1_clk_enable_generic(struct clk *clk)
+static int omap1_clk_enable_generic(struct clk_hw *clk_hw)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
__u16 regval16;
__u32 regval32;
@@ -719,8 +746,9 @@ static int omap1_clk_enable_generic(struct clk *clk)
return 0;
}
-static void omap1_clk_disable_generic(struct clk *clk)
+static void omap1_clk_disable_generic(struct clk_hw *clk_hw)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
__u16 regval16;
__u32 regval32;
@@ -738,13 +766,14 @@ static void omap1_clk_disable_generic(struct clk *clk)
}
}
-static const struct clkops clkops_generic = {
+static const struct clk_ops clkops_generic = {
.enable = omap1_clk_enable_generic,
.disable = omap1_clk_disable_generic,
};
-static unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk)
+static unsigned long omap1_ckctl_recalc_dsp_domain(struct clk_hw *clk_hw)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
int dsor;
/* Calculate divisor encoded as 2-bit exponent
@@ -761,42 +790,44 @@ static unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk)
return clk->parent->rate / dsor;
}
-static int omap1_clk_enable_dsp_domain(struct clk *clk)
+static int omap1_clk_enable_dsp_domain(struct clk_hw *clk_hw)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
int retval;
retval = omap1_clk_enable(api_ck_p);
if (!retval) {
- retval = omap1_clk_enable_generic(clk);
+ retval = omap1_clk_enable_generic(&clk->clk_hw);
omap1_clk_disable(api_ck_p);
}
return retval;
}
-static void omap1_clk_disable_dsp_domain(struct clk *clk)
+static void omap1_clk_disable_dsp_domain(struct clk_hw *clk_hw)
{
if (omap1_clk_enable(api_ck_p) == 0) {
- omap1_clk_disable_generic(clk);
+ omap1_clk_disable_generic(clk_hw);
omap1_clk_disable(api_ck_p);
}
}
-static const struct clkops clkops_dspck = {
+static const struct clk_ops clkops_dspck = {
.enable = omap1_clk_enable_dsp_domain,
.disable = omap1_clk_disable_dsp_domain,
};
/* XXX SYSC register handling does not belong in the clock framework */
-static int omap1_clk_enable_uart_functional_16xx(struct clk *clk)
+static int omap1_clk_enable_uart_functional_16xx(struct clk_hw *clk_hw)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
int ret;
struct uart_clk *uclk;
- ret = omap1_clk_enable_generic(clk);
+ ret = omap1_clk_enable_generic(&clk->clk_hw);
if (ret == 0) {
/* Set smart idle acknowledgement mode */
- uclk = (struct uart_clk *)clk;
+ uclk = container_of(clk, struct uart_clk, clk);
omap_writeb((omap_readb(uclk->sysc_addr) & ~0x10) | 8,
uclk->sysc_addr);
}
@@ -805,48 +836,52 @@ static int omap1_clk_enable_uart_functional_16xx(struct clk *clk)
}
/* XXX SYSC register handling does not belong in the clock framework */
-static void omap1_clk_disable_uart_functional_16xx(struct clk *clk)
+static void omap1_clk_disable_uart_functional_16xx(struct clk_hw *clk_hw)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
struct uart_clk *uclk;
/* Set force idle acknowledgement mode */
- uclk = (struct uart_clk *)clk;
+ uclk = container_of(clk, struct uart_clk, clk);
omap_writeb((omap_readb(uclk->sysc_addr) & ~0x18), uclk->sysc_addr);
- omap1_clk_disable_generic(clk);
+ omap1_clk_disable_generic(clk_hw);
}
/* XXX SYSC register handling does not belong in the clock framework */
-static const struct clkops clkops_uart_16xx = {
+static const struct clk_ops clkops_uart_16xx = {
.enable = omap1_clk_enable_uart_functional_16xx,
.disable = omap1_clk_disable_uart_functional_16xx,
};
-static long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
+static long omap1_clk_round_rate(struct clk_hw *clk_hw, unsigned long rate)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
+
if (clk->round_rate != NULL)
- return clk->round_rate(clk, rate);
+ return clk->round_rate(clk_hw, rate);
return clk->rate;
}
-static int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
+static int omap1_clk_set_rate(struct clk_hw *clk_hw, unsigned long rate)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
int ret = -EINVAL;
if (clk->set_rate)
- ret = clk->set_rate(clk, rate);
+ ret = clk->set_rate(clk_hw, rate);
return ret;
}
/* Propagate rate to children */
-static void propagate_rate(struct clk *tclk)
+static void propagate_rate(struct omap1_clk *tclk)
{
- struct clk *clkp;
+ struct omap1_clk *clkp;
list_for_each_entry(clkp, &tclk->children, sibling) {
if (clkp->recalc)
- clkp->rate = clkp->recalc(clkp);
+ clkp->rate = clkp->recalc(&clkp->clk_hw);
propagate_rate(clkp);
}
}
@@ -864,7 +899,7 @@ int clk_enable(struct clk *clk)
return -EINVAL;
spin_lock_irqsave(&clockfw_lock, flags);
- ret = omap1_clk_enable(clk);
+ ret = omap1_clk_enable(clk->clk_hw);
spin_unlock_irqrestore(&clockfw_lock, flags);
return ret;
@@ -874,19 +909,20 @@ EXPORT_SYMBOL(clk_enable);
void clk_disable(struct clk *clk)
{
unsigned long flags;
+ struct omap1_clk *_clk = to_omap1_clk(clk->clk_hw);
if (clk == NULL || IS_ERR(clk))
return;
spin_lock_irqsave(&clockfw_lock, flags);
- if (clk->usecount == 0) {
+ if (_clk->usecount == 0) {
pr_err("Trying disable clock %s with 0 usecount\n",
- clk->name);
+ _clk->name);
WARN_ON(1);
goto out;
}
- omap1_clk_disable(clk);
+ omap1_clk_disable(clk->clk_hw);
out:
spin_unlock_irqrestore(&clockfw_lock, flags);
@@ -902,7 +938,7 @@ unsigned long clk_get_rate(struct clk *clk)
return 0;
spin_lock_irqsave(&clockfw_lock, flags);
- ret = clk->rate;
+ ret = to_omap1_clk(clk->clk_hw)->rate;
spin_unlock_irqrestore(&clockfw_lock, flags);
return ret;
@@ -922,7 +958,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
return 0;
spin_lock_irqsave(&clockfw_lock, flags);
- ret = omap1_clk_round_rate(clk, rate);
+ ret = omap1_clk_round_rate(clk->clk_hw, rate);
spin_unlock_irqrestore(&clockfw_lock, flags);
return ret;
@@ -938,9 +974,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
return ret;
spin_lock_irqsave(&clockfw_lock, flags);
- ret = omap1_clk_set_rate(clk, rate);
+ ret = omap1_clk_set_rate(clk->clk_hw, rate);
if (ret == 0)
- propagate_rate(clk);
+ propagate_rate(to_omap1_clk(clk->clk_hw));
spin_unlock_irqrestore(&clockfw_lock, flags);
return ret;
@@ -957,7 +993,9 @@ EXPORT_SYMBOL(clk_set_parent);
struct clk *clk_get_parent(struct clk *clk)
{
- return clk->parent;
+ struct omap1_clk *parent = to_omap1_clk(clk->clk_hw)->parent;
+
+ return &parent->clk_hw.clk;
}
EXPORT_SYMBOL(clk_get_parent);
@@ -966,8 +1004,10 @@ EXPORT_SYMBOL(clk_get_parent);
*/
/* Used for clocks that always have same value as the parent clock */
-static unsigned long followparent_recalc(struct clk *clk)
+static unsigned long followparent_recalc(struct clk_hw *clk_hw)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
+
return clk->parent->rate;
}
@@ -975,27 +1015,31 @@ static unsigned long followparent_recalc(struct clk *clk)
* Used for clocks that have the same value as the parent clock,
* divided by some factor
*/
-static unsigned long omap_fixed_divisor_recalc(struct clk *clk)
+static unsigned long omap_fixed_divisor_recalc(struct clk_hw *clk_hw)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
+
WARN_ON(!clk->fixed_div);
return clk->parent->rate / clk->fixed_div;
}
/**
- * clk_preinit - initialize any fields in the struct clk before clk init
- * @clk: struct clk * to initialize
+ * clk_preinit - initialize any fields in the struct omap1_clk before clk init
+ * @clk: struct omap1_clk * to initialize
*
- * Initialize any struct clk fields needed before normal clk initialization
+ * Initialize any struct omap1_clk fields needed before normal clk initialization
* can run. No return value.
*/
-static void clk_preinit(struct clk *clk)
+static void clk_preinit(struct omap1_clk *clk)
{
INIT_LIST_HEAD(&clk->children);
}
-static int clk_register(struct clk *clk)
+static int clk_register(struct device *dev, struct clk_hw *clk_hw)
{
+ struct omap1_clk *clk = to_omap1_clk(clk_hw);
+
if (clk == NULL || IS_ERR(clk))
return -EINVAL;
@@ -1005,13 +1049,15 @@ static int clk_register(struct clk *clk)
if (clk->node.next || clk->node.prev)
return 0;
+ clk_hw->clk.clk_hw = clk_hw;
+
mutex_lock(&clocks_mutex);
if (clk->parent)
list_add(&clk->sibling, &clk->parent->children);
list_add(&clk->node, &clocks);
if (clk->init)
- clk->init(clk);
+ clk->init(&clk->clk_hw);
mutex_unlock(&clocks_mutex);
return 0;
@@ -1020,16 +1066,16 @@ static int clk_register(struct clk *clk)
/*
* Low level helpers
*/
-static int clkll_enable_null(struct clk *clk)
+static int clkll_enable_null(struct clk_hw *clk_hw)
{
return 0;
}
-static void clkll_disable_null(struct clk *clk)
+static void clkll_disable_null(struct clk_hw *clk_hw)
{
}
-static const struct clkops clkops_null = {
+static const struct clk_ops clkops_null = {
.enable = clkll_enable_null,
.disable = clkll_disable_null,
};
@@ -1039,7 +1085,7 @@ static const struct clkops clkops_null = {
*
* Used for clock aliases that are needed on some OMAPs, but not others
*/
-static struct clk dummy_ck = {
+static struct omap1_clk dummy_ck = {
.name = "dummy",
.ops = &clkops_null,
};
@@ -1052,7 +1098,7 @@ static struct clk dummy_ck = {
/*
* Disable any unused clocks left on by the bootloader
*/
-static void omap1_clk_disable_unused(struct clk *clk)
+static void omap1_clk_disable_unused(struct omap1_clk *clk)
{
__u32 regval32;
@@ -1074,13 +1120,13 @@ static void omap1_clk_disable_unused(struct clk *clk)
return;
printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name);
- clk->ops->disable(clk);
+ clk->ops->disable(&clk->clk_hw);
printk(" done\n");
}
static int __init clk_disable_unused(void)
{
- struct clk *ck;
+ struct omap1_clk *ck;
unsigned long flags;
pr_info("clock: disabling unused clocks to save power\n");
@@ -1114,8 +1160,8 @@ static struct dentry *clk_debugfs_root;
static int debug_clock_show(struct seq_file *s, void *unused)
{
- struct clk *c;
- struct clk *pa;
+ struct omap1_clk *c;
+ struct omap1_clk *pa;
mutex_lock(&clocks_mutex);
seq_printf(s, "%-30s %-30s %-10s %s\n",
@@ -1134,10 +1180,10 @@ static int debug_clock_show(struct seq_file *s, void *unused)
DEFINE_SHOW_ATTRIBUTE(debug_clock);
-static void clk_debugfs_register_one(struct clk *c)
+static void clk_debugfs_register_one(struct omap1_clk *c)
{
struct dentry *d;
- struct clk *pa = c->parent;
+ struct omap1_clk *pa = c->parent;
d = debugfs_create_dir(c->name, pa ? pa->dent : clk_debugfs_root);
c->dent = d;
@@ -1147,9 +1193,9 @@ static void clk_debugfs_register_one(struct clk *c)
debugfs_create_x8("flags", S_IRUGO, c->dent, &c->flags);
}
-static void clk_debugfs_register(struct clk *c)
+static void clk_debugfs_register(struct omap1_clk *c)
{
- struct clk *pa = c->parent;
+ struct omap1_clk *pa = c->parent;
if (pa && !pa->dent)
clk_debugfs_register(pa);
@@ -1160,7 +1206,7 @@ static void clk_debugfs_register(struct clk *c)
static int __init clk_debugfs_init(void)
{
- struct clk *c;
+ struct omap1_clk *c;
struct dentry *d;
d = debugfs_create_dir("clock", NULL);
@@ -1181,13 +1227,13 @@ late_initcall(clk_debugfs_init);
* Omap1 clocks
*/
-static struct clk ck_ref = {
+static struct omap1_clk ck_ref = {
.name = "ck_ref",
.ops = &clkops_null,
.rate = 12000000,
};
-static struct clk ck_dpll1 = {
+static struct omap1_clk ck_dpll1 = {
.name = "ck_dpll1",
.ops = &clkops_null,
.parent = &ck_ref,
@@ -1210,7 +1256,7 @@ static struct arm_idlect1_clk ck_dpll1out = {
.idlect_shift = IDL_CLKOUT_ARM_SHIFT,
};
-static struct clk sossi_ck = {
+static struct omap1_clk sossi_ck = {
.name = "ck_sossi",
.ops = &clkops_generic,
.parent = &ck_dpll1out.clk,
@@ -1221,7 +1267,7 @@ static struct clk sossi_ck = {
.set_rate = &omap1_set_sossi_rate,
};
-static struct clk arm_ck = {
+static struct omap1_clk arm_ck = {
.name = "arm_ck",
.ops = &clkops_null,
.parent = &ck_dpll1,
@@ -1251,7 +1297,7 @@ static struct arm_idlect1_clk armper_ck = {
* FIXME: This clock seems to be necessary but no-one has asked for its
* activation. [ GPIO code for 1510 ]
*/
-static struct clk arm_gpio_ck = {
+static struct omap1_clk arm_gpio_ck = {
.name = "ick",
.ops = &clkops_generic,
.parent = &ck_dpll1,
@@ -1300,7 +1346,7 @@ static struct arm_idlect1_clk armwdt_ck = {
.idlect_shift = IDLWDT_ARM_SHIFT,
};
-static struct clk arminth_ck16xx = {
+static struct omap1_clk arminth_ck16xx = {
.name = "arminth_ck",
.ops = &clkops_null,
.parent = &arm_ck,
@@ -1312,7 +1358,7 @@ static struct clk arminth_ck16xx = {
*/
};
-static struct clk dsp_ck = {
+static struct omap1_clk dsp_ck = {
.name = "dsp_ck",
.ops = &clkops_generic,
.parent = &ck_dpll1,
@@ -1324,7 +1370,7 @@ static struct clk dsp_ck = {
.set_rate = omap1_clk_set_rate_ckctl_arm,
};
-static struct clk dspmmu_ck = {
+static struct omap1_clk dspmmu_ck = {
.name = "dspmmu_ck",
.ops = &clkops_null,
.parent = &ck_dpll1,
@@ -1334,7 +1380,7 @@ static struct clk dspmmu_ck = {
.set_rate = omap1_clk_set_rate_ckctl_arm,
};
-static struct clk dspper_ck = {
+static struct omap1_clk dspper_ck = {
.name = "dspper_ck",
.ops = &clkops_dspck,
.parent = &ck_dpll1,
@@ -1346,7 +1392,7 @@ static struct clk dspper_ck = {
.set_rate = &omap1_clk_set_rate_dsp_domain,
};
-static struct clk dspxor_ck = {
+static struct omap1_clk dspxor_ck = {
.name = "dspxor_ck",
.ops = &clkops_dspck,
.parent = &ck_ref,
@@ -1355,7 +1401,7 @@ static struct clk dspxor_ck = {
.recalc = &followparent_recalc,
};
-static struct clk dsptim_ck = {
+static struct omap1_clk dsptim_ck = {
.name = "dsptim_ck",
.ops = &clkops_dspck,
.parent = &ck_ref,
@@ -1378,7 +1424,7 @@ static struct arm_idlect1_clk tc_ck = {
.idlect_shift = IDLIF_ARM_SHIFT,
};
-static struct clk arminth_ck1510 = {
+static struct omap1_clk arminth_ck1510 = {
.name = "arminth_ck",
.ops = &clkops_null,
.parent = &tc_ck.clk,
@@ -1389,7 +1435,7 @@ static struct clk arminth_ck1510 = {
*/
};
-static struct clk tipb_ck = {
+static struct omap1_clk tipb_ck = {
/* No-idle controlled by "tc_ck" */
.name = "tipb_ck",
.ops = &clkops_null,
@@ -1397,7 +1443,7 @@ static struct clk tipb_ck = {
.recalc = &followparent_recalc,
};
-static struct clk l3_ocpi_ck = {
+static struct omap1_clk l3_ocpi_ck = {
/* No-idle controlled by "tc_ck" */
.name = "l3_ocpi_ck",
.ops = &clkops_generic,
@@ -1407,7 +1453,7 @@ static struct clk l3_ocpi_ck = {
.recalc = &followparent_recalc,
};
-static struct clk tc1_ck = {
+static struct omap1_clk tc1_ck = {
.name = "tc1_ck",
.ops = &clkops_generic,
.parent = &tc_ck.clk,
@@ -1420,7 +1466,7 @@ static struct clk tc1_ck = {
* FIXME: This clock seems to be necessary but no-one has asked for its
* activation. [ pm.c (SRAM), CCP, Camera ]
*/
-static struct clk tc2_ck = {
+static struct omap1_clk tc2_ck = {
.name = "tc2_ck",
.ops = &clkops_generic,
.parent = &tc_ck.clk,
@@ -1429,7 +1475,7 @@ static struct clk tc2_ck = {
.recalc = &followparent_recalc,
};
-static struct clk dma_ck = {
+static struct omap1_clk dma_ck = {
/* No-idle controlled by "tc_ck" */
.name = "dma_ck",
.ops = &clkops_null,
@@ -1437,7 +1483,7 @@ static struct clk dma_ck = {
.recalc = &followparent_recalc,
};
-static struct clk dma_lcdfree_ck = {
+static struct omap1_clk dma_lcdfree_ck = {
.name = "dma_lcdfree_ck",
.ops = &clkops_null,
.parent = &tc_ck.clk,
@@ -1470,21 +1516,21 @@ static struct arm_idlect1_clk lb_ck = {
.idlect_shift = IDLLB_ARM_SHIFT,
};
-static struct clk rhea1_ck = {
+static struct omap1_clk rhea1_ck = {
.name = "rhea1_ck",
.ops = &clkops_null,
.parent = &tc_ck.clk,
.recalc = &followparent_recalc,
};
-static struct clk rhea2_ck = {
+static struct omap1_clk rhea2_ck = {
.name = "rhea2_ck",
.ops = &clkops_null,
.parent = &tc_ck.clk,
.recalc = &followparent_recalc,
};
-static struct clk lcd_ck_16xx = {
+static struct omap1_clk lcd_ck_16xx = {
.name = "lcd_ck",
.ops = &clkops_generic,
.parent = &ck_dpll1,
@@ -1518,7 +1564,7 @@ static struct arm_idlect1_clk lcd_ck_1510 = {
*
* XXX does this need SYSC register handling?
*/
-static struct clk uart1_1510 = {
+static struct omap1_clk uart1_1510 = {
.name = "uart1_ck",
.ops = &clkops_null,
/* Direct from ULPD, no real parent */
@@ -1557,7 +1603,7 @@ static struct uart_clk uart1_16xx = {
*
* XXX does this need SYSC register handling?
*/
-static struct clk uart2_ck = {
+static struct omap1_clk uart2_ck = {
.name = "uart2_ck",
.ops = &clkops_null,
/* Direct from ULPD, no real parent */
@@ -1576,7 +1622,7 @@ static struct clk uart2_ck = {
*
* XXX does this need SYSC register handling?
*/
-static struct clk uart3_1510 = {
+static struct omap1_clk uart3_1510 = {
.name = "uart3_ck",
.ops = &clkops_null,
/* Direct from ULPD, no real parent */
@@ -1609,7 +1655,7 @@ static struct uart_clk uart3_16xx = {
.sysc_addr = 0xfffb9854,
};
-static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
+static struct omap1_clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
.name = "usb_clko",
.ops = &clkops_generic,
/* Direct from ULPD, no parent */
@@ -1619,7 +1665,7 @@ static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
.enable_bit = USB_MCLK_EN_BIT,
};
-static struct clk usb_hhc_ck1510 = {
+static struct omap1_clk usb_hhc_ck1510 = {
.name = "usb_hhc_ck",
.ops = &clkops_generic,
/* Direct from ULPD, no parent */
@@ -1629,7 +1675,7 @@ static struct clk usb_hhc_ck1510 = {
.enable_bit = USB_HOST_HHC_UHOST_EN,
};
-static struct clk usb_hhc_ck16xx = {
+static struct omap1_clk usb_hhc_ck16xx = {
.name = "usb_hhc_ck",
.ops = &clkops_generic,
/* Direct from ULPD, no parent */
@@ -1640,7 +1686,7 @@ static struct clk usb_hhc_ck16xx = {
.enable_bit = OTG_SYSCON_2_UHOST_EN_SHIFT
};
-static struct clk usb_dc_ck = {
+static struct omap1_clk usb_dc_ck = {
.name = "usb_dc_ck",
.ops = &clkops_generic,
/* Direct from ULPD, no parent */
@@ -1649,7 +1695,7 @@ static struct clk usb_dc_ck = {
.enable_bit = SOFT_USB_OTG_DPLL_REQ_SHIFT,
};
-static struct clk uart1_7xx = {
+static struct omap1_clk uart1_7xx = {
.name = "uart1_ck",
.ops = &clkops_generic,
/* Direct from ULPD, no parent */
@@ -1658,7 +1704,7 @@ static struct clk uart1_7xx = {
.enable_bit = 9,
};
-static struct clk uart2_7xx = {
+static struct omap1_clk uart2_7xx = {
.name = "uart2_ck",
.ops = &clkops_generic,
/* Direct from ULPD, no parent */
@@ -1667,7 +1713,7 @@ static struct clk uart2_7xx = {
.enable_bit = 11,
};
-static struct clk mclk_1510 = {
+static struct omap1_clk mclk_1510 = {
.name = "mclk",
.ops = &clkops_generic,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
@@ -1676,7 +1722,7 @@ static struct clk mclk_1510 = {
.enable_bit = SOFT_COM_MCKO_REQ_SHIFT,
};
-static struct clk mclk_16xx = {
+static struct omap1_clk mclk_16xx = {
.name = "mclk",
.ops = &clkops_generic,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
@@ -1687,14 +1733,14 @@ static struct clk mclk_16xx = {
.init = &omap1_init_ext_clk,
};
-static struct clk bclk_1510 = {
+static struct omap1_clk bclk_1510 = {
.name = "bclk",
.ops = &clkops_generic,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
.rate = 12000000,
};
-static struct clk bclk_16xx = {
+static struct omap1_clk bclk_16xx = {
.name = "bclk",
.ops = &clkops_generic,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
@@ -1705,7 +1751,7 @@ static struct clk bclk_16xx = {
.init = &omap1_init_ext_clk,
};
-static struct clk mmc1_ck = {
+static struct omap1_clk mmc1_ck = {
.name = "mmc1_ck",
.ops = &clkops_generic,
/* Functional clock is direct from ULPD, interface clock is ARMPER */
@@ -1720,7 +1766,7 @@ static struct clk mmc1_ck = {
* XXX MOD_CONF_CTRL_0 bit 20 is defined in the 1510 TRM as
* CONF_MOD_MCBSP3_AUXON ??
*/
-static struct clk mmc2_ck = {
+static struct omap1_clk mmc2_ck = {
.name = "mmc2_ck",
.ops = &clkops_generic,
/* Functional clock is direct from ULPD, interface clock is ARMPER */
@@ -1731,7 +1777,7 @@ static struct clk mmc2_ck = {
.enable_bit = 20,
};
-static struct clk mmc3_ck = {
+static struct omap1_clk mmc3_ck = {
.name = "mmc3_ck",
.ops = &clkops_generic,
/* Functional clock is direct from ULPD, interface clock is ARMPER */
@@ -1742,7 +1788,7 @@ static struct clk mmc3_ck = {
.enable_bit = SOFT_MMC_DPLL_REQ_SHIFT,
};
-static struct clk virtual_ck_mpu = {
+static struct omap1_clk virtual_ck_mpu = {
.name = "mpu",
.ops = &clkops_null,
.parent = &arm_ck, /* Is smarter alias for */
@@ -1753,7 +1799,7 @@ static struct clk virtual_ck_mpu = {
/* virtual functional clock domain for I2C. Just for making sure that ARMXOR_CK
remains active during MPU idle whenever this is enabled */
-static struct clk i2c_fck = {
+static struct omap1_clk i2c_fck = {
.name = "i2c_fck",
.ops = &clkops_null,
.flags = CLOCK_NO_IDLE_PARENT,
@@ -1761,7 +1807,7 @@ static struct clk i2c_fck = {
.recalc = &followparent_recalc,
};
-static struct clk i2c_ick = {
+static struct omap1_clk i2c_ick = {
.name = "i2c_ick",
.ops = &clkops_null,
.flags = CLOCK_NO_IDLE_PARENT,
@@ -1773,7 +1819,7 @@ static struct clk i2c_ick = {
* clkdev integration
*/
-static struct omap_clk omap_clks[] = {
+static struct omap1_clk_lookup omap_clks[] = {
/* non-ULPD clocks */
CLK(NULL, "ck_ref", &ck_ref, CK_16XX | CK_1510 | CK_310 | CK_7XX),
CLK(NULL, "ck_dpll1", &ck_dpll1, CK_16XX | CK_1510 | CK_310 | CK_7XX),
@@ -1866,7 +1912,7 @@ static void __init omap1_show_rates(void)
int __init omap1_clk_init(void)
{
- struct omap_clk *c;
+ struct omap1_clk_lookup *c;
int crystal_type = 0; /* Default 12 MHz */
u32 reg;
@@ -1888,7 +1934,7 @@ int __init omap1_clk_init(void)
arm_idlect1_mask = ~0;
for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++)
- clk_preinit(c->lk.clk);
+ clk_preinit(to_omap1_clk(c->lk.clk_hw));
cpu_mask = 0;
if (cpu_is_omap1710())
@@ -1905,13 +1951,13 @@ int __init omap1_clk_init(void)
for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++)
if (c->cpu & cpu_mask) {
clkdev_add(&c->lk);
- clk_register(c->lk.clk);
+ clk_register(NULL, c->lk.clk_hw);
}
/* Pointers to these clocks are needed by code in clock.c */
- api_ck_p = clk_get(NULL, "api_ck");
- ck_dpll1_p = clk_get(NULL, "ck_dpll1");
- ck_ref_p = clk_get(NULL, "ck_ref");
+ api_ck_p = &api_ck.clk.clk_hw;
+ ck_dpll1_p = &ck_dpll1.clk_hw;
+ ck_ref_p = &ck_ref.clk_hw;
if (cpu_is_omap7xx())
ck_ref.rate = 13000000;
@@ -1994,12 +2040,12 @@ int __init omap1_clk_init(void)
* Only enable those clocks we will need, let the drivers
* enable other clocks as necessary
*/
- clk_enable(&armper_ck.clk);
- clk_enable(&armxor_ck.clk);
- clk_enable(&armtim_ck.clk); /* This should be done by timer code */
+ omap1_clk_enable(&armper_ck.clk.clk_hw);
+ omap1_clk_enable(&armxor_ck.clk.clk_hw);
+ omap1_clk_enable(&armtim_ck.clk.clk_hw); /* This should be done by timer code */
if (cpu_is_omap15xx())
- clk_enable(&arm_gpio_ck);
+ omap1_clk_enable(&arm_gpio_ck.clk_hw);
return 0;
}
@@ -2011,7 +2057,7 @@ void __init omap1_clk_late_init(void)
unsigned long rate = ck_dpll1.rate;
/* Find the highest supported frequency and enable it */
- if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) {
+ if (omap1_select_table_rate(&virtual_ck_mpu.clk_hw, ~0)) {
pr_err("System frequencies not set, using default. Check your config.\n");
/*
* Reprogramming the DPLL is tricky, it must be done from SRAM.
--
2.20.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ 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