Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4] dmaengine: sirf: enable generic dt binding for dma channels
From: Vinod Koul @ 2014-01-20  8:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAGsJ_4zcwCx0RNMNx8YaDBFtGE=02-B79+WKDGeky80X5agcuw@mail.gmail.com>

On Mon, Jan 20, 2014 at 05:35:07PM +0800, Barry Song wrote:
> 2014/1/20 Vinod Koul <vinod.koul@intel.com>:
> > On Wed, Jan 08, 2014 at 10:12:49PM +0800, Barry Song wrote:
> >> From: Barry Song <Baohua.Song@csr.com>
> >>
> >> move to support of_dma_request_slave_channel() and dma_request_slave_channel.
> >> we add a xlate() to let dma clients be able to find right dma_chan by generic
> >> "dmas" properties in dts.
> >>
> >> Cc: Mark Rutland <mark.rutland@arm.com>
> >> Cc: Lars-Peter Clausen <lars@metafoo.de>
> >> Signed-off-by: Barry Song <Baohua.Song@csr.com>
> > Look okay, need an ACk from DT maintainers before I can apply...
> 
> Vinod, will i send v5 with your ack to
> devicetree-discuss at lists.ozlabs.org, and CC Grant & Rob?
Which tree are you tragetting this, if dmaengine then my ack make no sense :)

> 
> Hi Rob, will you Ack this one if you have noticed this thread?
I dont think Robs email is avlid anymore, I think he moved to Linaro, if I am
not mistaken.

~Vinod
> > ~Vinod
> >> ---
> >>  -v4: clear dt-binding document according to Mark's feedback
> 
> -barry
> --
> To unsubscribe from this list: send the line "unsubscribe dmaengine" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

^ permalink raw reply

* [PATCH 1/3] mmc: add support for power-on sequencing through DT
From: Ulf Hansson @ 2014-01-20  8:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390190215-22700-2-git-send-email-olof@lixom.net>

On 20 January 2014 04:56, Olof Johansson <olof@lixom.net> wrote:
> This patch enables support for power-on sequencing of SDIO peripherals through DT.
>
> In general, it's quite common that wifi modules and other similar
> peripherals have several signals in addition to the SDIO interface that
> needs wiggling before the module will power on. It's common to have a
> reference clock, one or several power rails and one or several lines
> for reset/enable type functions.
>
> The binding as written today introduces a number of reset gpios,
> a regulator and a clock specifier. The code will handle up to 2 gpio
> reset lines, but it's trivial to increase to more than that if needed
> at some point.
>
> Implementation-wise, the MMC core has been changed to handle this during
> host power up, before the host interface is powered on. I have not yet
> implemented the power-down side, I wanted people to have a chance for
> reporting back w.r.t. issues (or comments on the bindings) first.
>
> I have not tested the regulator portion, since the system and module
> I'm working on doesn't need one (Samsung Chromebook with Marvell
> 8797-based wifi). Testing of those portions (and reporting back) would
> be appreciated.
>
> Signed-off-by: Olof Johansson <olof@lixom.net>
> ---
>  Documentation/devicetree/bindings/mmc/mmc.txt |   11 +++++++
>  drivers/mmc/core/core.c                       |   42 +++++++++++++++++++++++++
>  drivers/mmc/core/host.c                       |   30 +++++++++++++++++-
>  include/linux/mmc/host.h                      |    5 +++
>  4 files changed, 87 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt
> index 458b57f..962e0ee 100644
> --- a/Documentation/devicetree/bindings/mmc/mmc.txt
> +++ b/Documentation/devicetree/bindings/mmc/mmc.txt
> @@ -5,6 +5,8 @@ these definitions.
>  Interpreted by the OF core:
>  - reg: Registers location and length.
>  - interrupts: Interrupts used by the MMC controller.
> +- clocks: Clocks needed for the host controller, if any.
> +- clock-names: Goes with clocks above.
>
>  Card detection:
>  If no property below is supplied, host native card detect is used.
> @@ -30,6 +32,15 @@ Optional properties:
>  - cap-sdio-irq: enable SDIO IRQ signalling on this interface
>  - full-pwr-cycle: full power cycle of the card is supported
>
> +Card power and reset control:
> +The following properties can be specified for cases where the MMC
> +peripheral needs additional reset, regulator and clock lines. It is for
> +example common for WiFi/BT adapters to have these separate from the main
> +MMC bus:
> +  - card-reset-gpios: Specify GPIOs for card reset (reset active low)
> +  - card-external-vcc-supply: Regulator to drive (independent) card VCC
> +  - clock with name "card_ext_clock": External clock provided to the card
> +
>  *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line
>  polarity properties, we have to fix the meaning of the "normal" and "inverted"
>  line levels. We choose to follow the SDHCI standard, which specifies both those
> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> index 098374b..c43e6c8 100644
> --- a/drivers/mmc/core/core.c
> +++ b/drivers/mmc/core/core.c
> @@ -13,11 +13,13 @@
>  #include <linux/module.h>
>  #include <linux/init.h>
>  #include <linux/interrupt.h>
> +#include <linux/clk.h>
>  #include <linux/completion.h>
>  #include <linux/device.h>
>  #include <linux/delay.h>
>  #include <linux/pagemap.h>
>  #include <linux/err.h>
> +#include <linux/gpio.h>
>  #include <linux/leds.h>
>  #include <linux/scatterlist.h>
>  #include <linux/log2.h>
> @@ -1519,6 +1521,43 @@ void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
>         mmc_host_clk_release(host);
>  }
>
> +static void mmc_card_power_up(struct mmc_host *host)
> +{
> +       int i;
> +       struct gpio_desc **gds = host->card_reset_gpios;
> +
> +       for (i = 0; i < ARRAY_SIZE(host->card_reset_gpios); i++) {
> +               if (gds[i]) {
> +                       dev_dbg(host->parent, "Asserting reset line %d", i);
> +                       gpiod_set_value(gds[i], 1);
> +               }
> +       }
> +
> +       if (host->card_regulator) {
> +               dev_dbg(host->parent, "Enabling external regulator");
> +               if (regulator_enable(host->card_regulator))
> +                       dev_err(host->parent, "Failed to enable external regulator");
> +       }
> +
> +       if (host->card_clk) {
> +               dev_dbg(host->parent, "Enabling external clock");
> +               clk_prepare_enable(host->card_clk);
> +       }
> +
> +       /* 2ms delay to let clocks and power settle */
> +       mmc_delay(20);
> +
> +       for (i = 0; i < ARRAY_SIZE(host->card_reset_gpios); i++) {
> +               if (gds[i]) {
> +                       dev_dbg(host->parent, "Deasserting reset line %d", i);
> +                       gpiod_set_value(gds[i], 0);
> +               }
> +       }
> +
> +       /* 2ms delay to after reset release */
> +       mmc_delay(20);
> +}
> +
>  /*
>   * Apply power to the MMC stack.  This is a two-stage process.
>   * First, we enable power to the card without the clock running.
> @@ -1535,6 +1574,9 @@ void mmc_power_up(struct mmc_host *host, u32 ocr)
>         if (host->ios.power_mode == MMC_POWER_ON)
>                 return;
>
> +       /* Power up the card/module first, if needed */
> +       mmc_card_power_up(host);
> +
>         mmc_host_clk_hold(host);
>
>         host->ios.vdd = fls(ocr) - 1;
> diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
> index 49bc403..e6b850b 100644
> --- a/drivers/mmc/core/host.c
> +++ b/drivers/mmc/core/host.c
> @@ -12,14 +12,18 @@
>   *  MMC host class device management
>   */
>
> +#include <linux/kernel.h>
> +#include <linux/clk.h>
>  #include <linux/device.h>
>  #include <linux/err.h>
> +#include <linux/gpio/consumer.h>
>  #include <linux/idr.h>
>  #include <linux/of.h>
>  #include <linux/of_gpio.h>
>  #include <linux/pagemap.h>
>  #include <linux/export.h>
>  #include <linux/leds.h>
> +#include <linux/regulator/consumer.h>
>  #include <linux/slab.h>
>  #include <linux/suspend.h>
>
> @@ -312,7 +316,7 @@ int mmc_of_parse(struct mmc_host *host)
>         u32 bus_width;
>         bool explicit_inv_wp, gpio_inv_wp = false;
>         enum of_gpio_flags flags;
> -       int len, ret, gpio;
> +       int i, len, ret, gpio;
>
>         if (!host->parent || !host->parent->of_node)
>                 return 0;
> @@ -415,6 +419,30 @@ int mmc_of_parse(struct mmc_host *host)
>         if (explicit_inv_wp ^ gpio_inv_wp)
>                 host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
>
> +       /* Parse card power/reset/clock control */

I would like us to prevent to open up for confusion with the "eMMC hw
reset" when adding this. Unless we are able to combine them in some
way?

Could we maybe add some more comments about in what scenarios this DT
property would be useful?

> +       if (of_find_property(np, "card-reset-gpios", NULL)) {
> +               struct gpio_desc *gpd;
> +               for (i = 0; i < ARRAY_SIZE(host->card_reset_gpios); i++) {
> +                       gpd = devm_gpiod_get_index(host->parent, "card-reset", i);
> +                       if (IS_ERR(gpd))
> +                               break;
> +                       gpiod_direction_output(gpd, 0);
> +                       host->card_reset_gpios[i] = gpd;
> +               }
> +
> +               gpd = devm_gpiod_get_index(host->parent, "card-reset", ARRAY_SIZE(host->card_reset_gpios));
> +               if (!IS_ERR(gpd)) {
> +                       dev_warn(host->parent, "More reset gpios than we can handle");
> +                       gpiod_put(gpd);
> +               }
> +       }
> +
> +       host->card_clk = of_clk_get_by_name(np, "card_ext_clock");

of_clk_get_by_name relies on COMMON_CLK, is that really what you want here?

> +       if (IS_ERR(host->card_clk))
> +               host->card_clk = NULL;
> +
> +       host->card_regulator = regulator_get(host->parent, "card-external-vcc");

Is the above regulator related to host->ocr_avail mask? Could the
above regulator be replaced by vmmc?

At the moment host drivers uses mmc_regulator_get_supply(), which
fetches regulators called "vmmc" and "vqmmc". It is also common to
have these defined in DT like "vmmc-supply". This has not been
properly documented for most host cases, and we should fix that. I
also think it would make sense to include these in the documentation
for the common mmc bindings, instead of host specific bindings.

Kind regards
Ulf Hansson

> +
>         if (of_find_property(np, "cap-sd-highspeed", &len))
>                 host->caps |= MMC_CAP_SD_HIGHSPEED;
>         if (of_find_property(np, "cap-mmc-highspeed", &len))
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index 99f5709..6781887 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -297,6 +297,11 @@ struct mmc_host {
>         unsigned long           clkgate_delay;
>  #endif
>
> +       /* card specific properties to deal with power and reset */
> +       struct regulator        *card_regulator; /* External VCC needed by the card */
> +       struct gpio_desc        *card_reset_gpios[2]; /* External resets, active low */
> +       struct clk              *card_clk;      /* External clock needed by the card */
> +
>         /* host specific block data */
>         unsigned int            max_seg_size;   /* see blk_queue_max_segment_size */
>         unsigned short          max_segs;       /* see blk_queue_max_segments */
> --
> 1.7.10.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH V3 2/2] mm/memblock: Add support for excluded memory areas
From: Philipp Hachtmann @ 2014-01-20  8:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <902E09E6452B0E43903E4F2D568737AB0B9852BA@DFRE01.ent.ti.com>

Am Fri, 17 Jan 2014 18:08:13 +0000
schrieb "Strashko, Grygorii" <grygorii.strashko@ti.com>:

Hello Grygorii,

> > The current patch seems to be overly complicated.
> > The following patch contains only the nomap functionality without
> > any cleanup and refactoring. I will post a V4 patch set which will
> > contain this patch.

please see the V4 patch set I've sent to the list. There you will
clearly see that nothing is changed. No API is broken by the patch.
The patch only adds functionality.
Everything that worked before keeps working as before without any
changes needed in any arch's code.

Kind regards

Philipp

^ permalink raw reply

* [RFC v3 08/13] ahci-platform: Allow specifying platform_data through of_device_id
From: Hans de Goede @ 2014-01-20  8:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140120082438.GH16215@pengutronix.de>

Hi,

On 01/20/2014 09:24 AM, Sascha Hauer wrote:
> On Sun, Jan 19, 2014 at 12:48:50AM +0100, Hans de Goede wrote:
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>> ---
>>   drivers/ata/ahci_platform.c | 41 +++++++++++++++++++++++++++++------------
>>   1 file changed, 29 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
>> index 3bc2dab..0676d72 100644
>> --- a/drivers/ata/ahci_platform.c
>> +++ b/drivers/ata/ahci_platform.c
>> @@ -20,6 +20,7 @@
>>   #include <linux/init.h>
>>   #include <linux/interrupt.h>
>>   #include <linux/device.h>
>> +#include <linux/of_device.h>
>>   #include <linux/platform_device.h>
>>   #include <linux/libata.h>
>>   #include <linux/ahci_platform.h>
>> @@ -87,6 +88,30 @@ static struct scsi_host_template ahci_platform_sht = {
>>   	AHCI_SHT("ahci_platform"),
>>   };
>>
>> +static const struct of_device_id ahci_of_match[] = {
>> +	{ .compatible = "snps,spear-ahci", },
>> +	{ .compatible = "snps,exynos5440-ahci", },
>> +	{ .compatible = "ibm,476gtr-ahci", },
>> +	{},
>> +};
>> +MODULE_DEVICE_TABLE(of, ahci_of_match);
>> +
>> +static const struct ahci_platform_data *ahci_get_pdata(struct device *dev)
>> +{
>> +	struct ahci_platform_data *pdata;
>> +	const struct of_device_id *of_id;
>> +
>> +	pdata = dev_get_platdata(dev);
>> +	if (pdata)
>> +		return pdata;
>> +
>> +	of_id = of_match_device(ahci_of_match, dev);
>> +	if (of_id)
>> +		return of_id->data;
>
> I don't think it's a good idea to force of_id->data to be of type struct
> struct ahci_platform_data *. With this we don't have a place to store
> SoC specific data anymore.

?? ahci_platform_data *is* soc specific data, it allows various soc
specific overrides.

Regards,

Hans

^ permalink raw reply

* [RFC v3 08/13] ahci-platform: Allow specifying platform_data through of_device_id
From: Sascha Hauer @ 2014-01-20  8:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390088935-7193-9-git-send-email-hdegoede@redhat.com>

On Sun, Jan 19, 2014 at 12:48:50AM +0100, Hans de Goede wrote:
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/ata/ahci_platform.c | 41 +++++++++++++++++++++++++++++------------
>  1 file changed, 29 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
> index 3bc2dab..0676d72 100644
> --- a/drivers/ata/ahci_platform.c
> +++ b/drivers/ata/ahci_platform.c
> @@ -20,6 +20,7 @@
>  #include <linux/init.h>
>  #include <linux/interrupt.h>
>  #include <linux/device.h>
> +#include <linux/of_device.h>
>  #include <linux/platform_device.h>
>  #include <linux/libata.h>
>  #include <linux/ahci_platform.h>
> @@ -87,6 +88,30 @@ static struct scsi_host_template ahci_platform_sht = {
>  	AHCI_SHT("ahci_platform"),
>  };
>  
> +static const struct of_device_id ahci_of_match[] = {
> +	{ .compatible = "snps,spear-ahci", },
> +	{ .compatible = "snps,exynos5440-ahci", },
> +	{ .compatible = "ibm,476gtr-ahci", },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, ahci_of_match);
> +
> +static const struct ahci_platform_data *ahci_get_pdata(struct device *dev)
> +{
> +	struct ahci_platform_data *pdata;
> +	const struct of_device_id *of_id;
> +
> +	pdata = dev_get_platdata(dev);
> +	if (pdata)
> +		return pdata;
> +
> +	of_id = of_match_device(ahci_of_match, dev);
> +	if (of_id)
> +		return of_id->data;

I don't think it's a good idea to force of_id->data to be of type struct
struct ahci_platform_data *. With this we don't have a place to store
SoC specific data anymore.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply

* [PATCH v2 2/7] clk: samsung: add infrastructure to register cpu clocks
From: Lukasz Majewski @ 2014-01-20  8:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390047057-2239-3-git-send-email-thomas.ab@samsung.com>

Hi Thomas,

> From: Thomas Abraham <thomas.ab@samsung.com>
> 
> The CPU clock provider supplies the clock to the CPU clock domain. The
> composition and organization of the CPU clock provider could vary
> among Exynos SoCs. A CPU clock provider can be composed of clock mux,
> dividers and gates. This patch defines a new clock type for CPU clock
> provider and adds infrastructure to register the CPU clock providers
> for Samsung platforms.
> 
> In addition to this, the arm cpu clock provider for Exynos4210 and
> compatible SoCs is instantiated using the new cpu clock type. The
> clock frequency table and the clock configuration data for this clock
> is obtained from device tree. This implementation is reusable for
> Exynos4x12 and Exynos5250 SoCs as well.
> 
> Cc: Tomasz Figa <t.figa@samsung.com>
> Cc: Lukasz Majewski <l.majewski@majess.pl>
> Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
> ---
>  drivers/clk/samsung/Makefile  |    2 +-
>  drivers/clk/samsung/clk-cpu.c |  345
> +++++++++++++++++++++++++++++++++++++++++
> drivers/clk/samsung/clk.h     |    3 + 3 files changed, 349
> insertions(+), 1 deletions(-) create mode 100644
> drivers/clk/samsung/clk-cpu.c
> 
> diff --git a/drivers/clk/samsung/Makefile
> b/drivers/clk/samsung/Makefile index 8eb4799..e2b453f 100644
> --- a/drivers/clk/samsung/Makefile
> +++ b/drivers/clk/samsung/Makefile
> @@ -2,7 +2,7 @@
>  # Samsung Clock specific Makefile
>  #
>  
> -obj-$(CONFIG_COMMON_CLK)	+= clk.o clk-pll.o
> +obj-$(CONFIG_COMMON_CLK)	+= clk.o clk-pll.o clk-cpu.o
>  obj-$(CONFIG_ARCH_EXYNOS4)	+= clk-exynos4.o
>  obj-$(CONFIG_SOC_EXYNOS5250)	+= clk-exynos5250.o
>  obj-$(CONFIG_SOC_EXYNOS5420)	+= clk-exynos5420.o
> diff --git a/drivers/clk/samsung/clk-cpu.c
> b/drivers/clk/samsung/clk-cpu.c new file mode 100644
> index 0000000..92fba45
> --- /dev/null
> +++ b/drivers/clk/samsung/clk-cpu.c
> @@ -0,0 +1,345 @@
> +/*
> + * Copyright (c) 2014 Samsung Electronics Co., Ltd.
> + * Author: Thomas Abraham <thomas.ab@samsung.com>
> + *
> + * This program is free software; you can redistribute it and/or
> modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This file contains the utility functions to register the cpu
> clocks
> + * for samsung platforms.
> +*/
> +
> +#include <linux/errno.h>
> +#include "clk.h"
> +
> +#define SRC_CPU			0x0
> +#define STAT_CPU		0x200
> +#define DIV_CPU0		0x300
> +#define DIV_CPU1		0x304
> +#define DIV_STAT_CPU0		0x400
> +#define DIV_STAT_CPU1		0x404
> +
> +/**
> + * struct samsung_cpuclk_freq_table: table of frequency supported by
> + * a cpu clock and associated data if any.
> + * @freq: points to a table of supported frequencies (in KHz)
> + * @freq_count: number of entries in the frequency table
> + * @data: cpu clock specific data, if any
> + *
> + * This structure holds the frequency options supported by the cpu
> clock in
> + * which this structure is contained. The data pointer is an
> optional data
> + * that can provide any additional configuration options for the
> supported
> + * frequencies. This structure is intended to be reusable for all
> cpu clocks
> + * in Samsung SoC based platforms
> + */
> +struct samsung_cpuclk_freq_table {
> +	const unsigned long	*freq;       /* in KHz */
> +	unsigned long		freq_count;
> +	const void		*data;
> +};
> +
> +/**
> + * struct exynos4210_freq_data: format of auxillary data associated
> with
> + * each frequency supported by the cpu clock for exynos4210.
> + * @parent_freq: The frequency of the parent clock required to
> generate the
> + * supported cpu clock speed.
> + * @div0: value to be programmed in the div_cpu0 register.
> + * @div1: value to be programmed in the div_cpu1 register.
> + *
> + * This structure holds the auxillary configuration data for each
> supported
> + * cpu clock frequency on Exynos4210 and compatible SoCs.
> + */
> +struct exynos4210_freq_data {
> +	unsigned long	parent_freq;
> +	unsigned int	div0;
> +	unsigned int	div1;
> +};
> +
> +/**
> + * struct samsung_cpuclk: information about clock supplied to a CPU
> core.
> + * @hw: handle between ccf and cpu clock.
> + * @ctrl_base: base address of the clock controller.
> + * @offset: offset from the ctrl_base address where the cpu clock
> div/mux
> + *          registers can be accessed.
> + * @parent: clock handle representing the clock output of the parent
> clock.
> + * @freq_table: the frequency table supported by this cpu clock.
> + */
> +struct samsung_cpuclk {
> +	struct clk_hw		hw;
> +	void __iomem		*ctrl_base;
> +	unsigned long		offset;
> +	struct clk		*parent;
> +	const struct samsung_cpuclk_freq_table *freq_table;
> +};
> +
> +#define to_samsung_cpuclk(hw)	container_of(hw, struct
> samsung_cpuclk, hw) +
> +/**
> + * struct samsung_cpuclk_match_data: soc specific data for cpu
> clocks.
> + * @parser: pointer to a function that can parse SoC specific cpu
> clock
> + *	frequency and associated configuration data.
> + * @offset: optional offset from base of clock controller register
> base,
> + *	to be used when accessing clock controller registers
> related to the
> + * cpu clock.
> + * @offset: offset from the ctrl_base address where the cpu clock
> div/mux
> + *	registers can be accessed.
> + */
> +struct samsung_cpuclk_match_data {
> +	int (*parser)(struct device_node *,
> +			struct samsung_cpuclk_freq_table **);
> +	unsigned int offset;
> +};
> +
> +/* This is a helper function to perform clock rounding for cpu
> clocks. */ +static long samsung_cpuclk_round_rate(struct clk_hw *hw,
> +			unsigned long drate, unsigned long *prate)
> +{
> +	struct samsung_cpuclk *cpuclk = to_samsung_cpuclk(hw);
> +	const struct samsung_cpuclk_freq_table *freq_tbl;
> +	int i;
> +
> +	freq_tbl = cpuclk->freq_table;
> +	drate /= 1000;
> +
> +	for (i = 0; i < freq_tbl->freq_count; i++) {
> +		if (drate >= freq_tbl->freq[i])
> +			return freq_tbl->freq[i] * 1000;
> +	}
> +	return freq_tbl->freq[i - 1] * 1000;
> +}
> +
> +#define EXYNOS4210_ARM_DIV1(base) ((readl(base + DIV_CPU0) & 0xf) +
> 1) +#define EXYNOS4210_ARM_DIV2(base) (((readl(base + DIV_CPU0) >>
> 28) & 0xf) + 1) +
> +/*
> + * CPU clock speed for Exynos4210 and compatible SoCs is
> + * parent clock speed / core1_ratio / core2_ratio
> + */
> +static unsigned long exynos4210_armclk_recalc_rate(struct clk_hw *hw,
> +				unsigned long parent_rate)
> +{
> +	struct samsung_cpuclk *armclk = to_samsung_cpuclk(hw);
> +	void __iomem *base = armclk->ctrl_base + armclk->offset;
> +
> +	return parent_rate / EXYNOS4210_ARM_DIV1(base) /
> +				EXYNOS4210_ARM_DIV2(base);
> +}
> +
> +/* set rate callback for cpuclk type on Exynos4210 and similar SoCs
> */ +static int exynos4210_armclk_set_rate(struct clk_hw *hw, unsigned
> long drate,
> +					unsigned long prate)
> +{
> +	struct samsung_cpuclk *armclk = to_samsung_cpuclk(hw);
> +	const struct samsung_cpuclk_freq_table *freq_tbl;
> +	const struct exynos4210_freq_data *freq_data;
> +	unsigned long mux_reg, idx;
> +	void __iomem *base;
> +
> +	if (drate == prate)
> +		return 0;
> +
> +	freq_tbl = armclk->freq_table;
> +	freq_data = freq_tbl->data;
> +	base = armclk->ctrl_base + armclk->offset;
> +
> +	for (idx = 0; idx < freq_tbl->freq_count; idx++, freq_data++)
> +		if ((freq_tbl->freq[idx] * 1000) == drate)
> +			break;
> +
> +	if (drate < prate) {
> +		mux_reg = readl(base + SRC_CPU);
> +		writel(mux_reg | (1 << 16), base + SRC_CPU);
> +		while (((readl(base + STAT_CPU) >> 16) & 0x7) != 2)
> +			;
> +
> +		clk_set_rate(armclk->parent, drate);
> +	}
> +
> +	writel(freq_data->div0, base + DIV_CPU0);
> +	while (readl(base + DIV_STAT_CPU0) != 0)
> +		;
> +	writel(freq_data->div1, base + DIV_CPU1);
> +	while (readl(base + DIV_STAT_CPU1) != 0)
> +		;
> +
> +	if (drate > prate) {
> +		mux_reg = readl(base + SRC_CPU);
> +		writel(mux_reg | (1 << 16), base + SRC_CPU);
> +		while (((readl(base + STAT_CPU) >> 16) & 0x7) != 2)
> +			;
> +
> +		clk_set_rate(armclk->parent, freq_data->parent_freq
> * 1000);
> +	}
> +
> +	mux_reg = readl(base + SRC_CPU);
> +	writel(mux_reg & ~(1 << 16), base + SRC_CPU);
> +	while (((readl(base + STAT_CPU) >> 16) & 0x7) != 1)
> +			;
> +	return 0;
> +}
> +
> +/* clock ops for armclk on Exynos4210 and compatible platforms. */
> +static const struct clk_ops exynos4210_armclk_clk_ops = {
> +	.recalc_rate = exynos4210_armclk_recalc_rate,
> +	.round_rate = samsung_cpuclk_round_rate,
> +	.set_rate = exynos4210_armclk_set_rate,
> +};
> +
> +/* helper function to register a cpu clock */
> +static void __init samsung_cpuclk_register(unsigned int lookup_id,
> +		const char *name, const char *parent, const struct
> clk_ops *ops,
> +		const struct samsung_cpuclk_freq_table *freq_tbl,
> +		void __iomem *reg_base,
> +		const struct samsung_cpuclk_match_data *data)
> +{
> +	struct samsung_cpuclk *cpuclk;
> +	struct clk_init_data init;
> +	struct clk *clk;
> +
> +	cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL);
> +	if (!cpuclk) {
> +		pr_err("%s: could not allocate memory for cpuclk
> %s\n",
> +					__func__, name);
> +		return;
> +	}
> +
> +	init.name = name;
> +	init.flags = CLK_GET_RATE_NOCACHE;
> +	init.parent_names = &parent;
> +	init.num_parents = 1;
> +	init.ops = ops;
> +
> +	cpuclk->hw.init = &init;
> +	cpuclk->ctrl_base = reg_base;
> +	cpuclk->offset = data->offset;
> +	cpuclk->freq_table = freq_tbl;
> +	cpuclk->parent = __clk_lookup(parent);
> +
> +	clk = clk_register(NULL, &cpuclk->hw);
> +	if (IS_ERR(clk)) {
> +		pr_err("%s: could not register cpuclk %s\n",
> __func__,	name);
> +		kfree(cpuclk);
> +		return;
> +	}
> +	samsung_clk_add_lookup(clk, lookup_id);
> +}
> +
> +#define EXYNOS4210_DIV_CPU01(d0, d1, d2, d3, d4, d5, d6,
> d7)		\
> +		((d0 << 28) | (d1 << 24) | (d2 << 20) |	(d3
> << 16) |	\
> +		 (d4 << 12) | (d5 << 8) | (d6 << 4) | (d7 << 0))
> +#define EXYNOS4210_DIV_CPU11(d0, d1,
> d2)				\
> +		((d0 << 8) | (d1 << 4) | (d2 << 0))
> +#define EXYNOS4210_CFG_LEN 13
> +
> +/*
> + * parse cpu clock frequency table and auxillary configuration data
> from dt
> + * for exynos4210 and compatible SoC's.
> + */
> +static int exynos4210_armclk_cfg_parser(struct device_node *np,
> +		struct samsung_cpuclk_freq_table **tbl)
> +{
> +	struct samsung_cpuclk_freq_table *freq_tbl;
> +	struct exynos4210_freq_data *fdata, *t_fdata;
> +	unsigned long *freqs, cfg[EXYNOS4210_CFG_LEN];
> +	const struct property *prop;
> +	unsigned int tbl_sz, i, j;
> +	const __be32 *val;
> +	int ret;
> +
> +	prop = of_find_property(np, "arm-frequency-table", NULL);
> +	if (!prop)
> +		return -EINVAL;
> +	if (!prop->value)
> +		return -EINVAL;
> +	if ((prop->length / sizeof(u32)) % EXYNOS4210_CFG_LEN)

Cannot we have the EXYNOS4210_CFG_LEN parsed from DT as well?

> +		return -EINVAL;
> +	tbl_sz = (prop->length / sizeof(u32)) / EXYNOS4210_CFG_LEN;
> +
> +	freq_tbl = kzalloc(sizeof(*freq_tbl), GFP_KERNEL);
> +	if (!freq_tbl)
> +		return -ENOMEM;
> +
> +	freqs = kzalloc(sizeof(u32) * tbl_sz, GFP_KERNEL);
> +	if (!freqs) {
> +		ret = -ENOMEM;
> +		goto free_freq_tbl;
> +	}
> +
> +	fdata = kzalloc(sizeof(*fdata) * tbl_sz, GFP_KERNEL);
> +	if (!fdata) {
> +		ret = -ENOMEM;
> +		goto free_freqs;
> +	}
> +	t_fdata = fdata;
> +
> +	val = prop->value;
> +	for (i = 0; i < tbl_sz; i++, fdata++) {
> +		for (j = 0; j < EXYNOS4210_CFG_LEN; j++)
> +			cfg[j] = be32_to_cpup(val++);
> +		freqs[i] = cfg[0];
> +		fdata->parent_freq = cfg[1];

Why do we need the separate parent_freq entry here?

In the patch 4/7 the freqs (cfg[0]) and parent_freq (cfg[1]) values are
the same for all supported devices (at "arm-frequency-table").

What is the rationale for having those values duplicated in the DT?


> +		fdata->div0 = EXYNOS4210_DIV_CPU01(cfg[9], cfg[8],
> cfg[7],
> +				cfg[6], cfg[5], cfg[4], cfg[3],
> cfg[2]);
> +		fdata->div1 = EXYNOS4210_DIV_CPU11(cfg[12], cfg[11],
> cfg[10]);
> +	}
> +
> +	freq_tbl->freq = freqs;
> +	freq_tbl->freq_count = tbl_sz;
> +	freq_tbl->data = t_fdata;
> +	*tbl = freq_tbl;
> +	return 0;
> +
> +free_freqs:
> +	kfree(freqs);
> +free_freq_tbl:
> +	kfree(freq_tbl);
> +	return ret;
> +}
> +
> +static struct samsung_cpuclk_match_data exynos4210_cpuclk_match_data
> = {
> +	.parser = exynos4210_armclk_cfg_parser,
> +	.offset = 0x14200,
> +};
> +
> +static struct samsung_cpuclk_match_data exynos5250_cpuclk_match_data
> = {
> +	.parser = exynos4210_armclk_cfg_parser,
> +	.offset = 0x200,
> +};
> +
> +static const struct of_device_id samsung_clock_ids[] = {
> +	{ .compatible = "samsung,exynos4210-clock",
> +			.data = &exynos4210_cpuclk_match_data, },
> +	{ .compatible = "samsung,exynos4412-clock",
> +			.data = &exynos4210_cpuclk_match_data, },
> +	{ .compatible = "samsung,exynos5250-clock",
> +			.data = &exynos5250_cpuclk_match_data, },
> +};
> +
> +int __init samsung_register_arm_clock(struct device_node *np,
> +		unsigned int lookup_id,	const char *parent,
> void __iomem *base) +{
> +	const struct of_device_id *match;
> +	struct samsung_cpuclk_freq_table *freq_table;
> +	const struct samsung_cpuclk_match_data *data;
> +	int ret;
> +
> +	match = of_match_node(samsung_clock_ids, np);
> +	if (!match) {
> +		pr_err("%s: could not determine soc type\n",
> __func__);
> +		return -EINVAL;
> +	}
> +
> +	data = match->data;
> +	ret = data->parser(np, &freq_table);
> +	if (ret) {
> +		pr_err("%s: error %d in parsing arm clock freq
> table",
> +						__func__, ret);
> +		return -EINVAL;
> +	}
> +
> +	samsung_cpuclk_register(lookup_id, "armclk", parent,
> +		&exynos4210_armclk_clk_ops, freq_table, base, data);
> +
> +	return 0;
> +}
> diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
> index 31b4174..a759330 100644
> --- a/drivers/clk/samsung/clk.h
> +++ b/drivers/clk/samsung/clk.h
> @@ -340,4 +340,7 @@ extern void __init
> samsung_clk_register_pll(struct samsung_pll_clock *pll_list, 
>  extern unsigned long _get_rate(const char *clk_name);
>  
> +extern int __init samsung_register_arm_clock(struct device_node *np,
> +		unsigned int lookup_id, const char *parent, void
> __iomem *base); +
>  #endif /* __SAMSUNG_CLK_H */



-- 
Best regards,

Lukasz Majewski

Samsung R&D Institute Poland (SRPOL) | Linux Platform Group

^ permalink raw reply

* [PATCH 06/20] ARM64 / ACPI: Introduce some PCI functions when PCI is enabled
From: Arnd Bergmann @ 2014-01-20  8:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52DCD961.70303@linaro.org>

On Monday 20 January 2014 16:08:01 Hanjun Guo wrote:
> >> diff --git a/drivers/acpi/plat/arm-core.c b/drivers/acpi/plat/arm-core.c
> >> index 3c8521d..1835b21 100644
> >> --- a/drivers/acpi/plat/arm-core.c
> >> +++ b/drivers/acpi/plat/arm-core.c
> >> @@ -100,6 +100,25 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
> >>  }
> >>  EXPORT_SYMBOL_GPL(acpi_gsi_to_irq);
> >>  
> >> +int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
> >> +{
> >> +    return -1;
> >> +}
> >> +
> >> +int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)
> >> +{
> >> +    /* TBD */
> >> +    return -EINVAL;
> >> +}
> >> +EXPORT_SYMBOL(acpi_register_ioapic);
> >> +
> >> +int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base)
> >> +{
> >> +    /* TBD */
> >> +    return -EINVAL;
> >> +}
> >> +EXPORT_SYMBOL(acpi_unregister_ioapic);
> >> +
> > 
> > My feeling is that these are better handled in the ACPI code by not
> > calling them on architectures that have no ISA or no IOAPIC support.
> > 
> > We have configuration symbols for both, so you don't have to make
> > it depend on CONFIG_ARM64 or CONFIG_X86.
> 
> Do you mean introduce a stub function when there is no ISA support?

Do you anticipate ISA devices on ARM64? I hope not ;-)

My guess is that whatever code calls this function should be disabled
in reduced hw mode.

> acpi_register_ioapic()/acpi_unregister_ioapic() will be used for IOAPIC
> hotplug and GIC distributor is something like IOAPIC on x86, so I think
> these two functions can be reserved for future use.

But GIC is not hotplugged, is it? It still sounds x86 specific to me.

	Arnd

^ permalink raw reply

* [PATCH v2] pinctrl: sunxi: Honor GPIO output initial vaules
From: Linus Walleij @ 2014-01-20  8:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1389854063-31016-1-git-send-email-wens@csie.org>

On Thu, Jan 16, 2014 at 7:34 AM, Chen-Yu Tsai <wens@csie.org> wrote:

> Some GPIO users, such as fixed-regulator, request GPIO output with
> initial value of 1. This was ignored by sunxi driver.
>
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> ---
>
> Changes since v2:
>
>   * Set output value before setting the pin function to avoid a glitch.

Patch applied with Maxime's ACK and tagged for stable.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH] pinctrl: capri: add dependency on OF
From: Linus Walleij @ 2014-01-20  8:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52D9BC5B.30304@wwwdotorg.org>

On Sat, Jan 18, 2014 at 12:27 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 01/17/2014 04:13 PM, Linus Walleij wrote:
>> On Sat, Jan 18, 2014 at 12:12 AM, Linus Walleij
>> <linus.walleij@linaro.org> wrote:
>>> On Fri, Jan 17, 2014 at 8:51 PM, Sherman Yin <syin@broadcom.com> wrote:
>>>
>>>> Thanks for the fix, Linus.  While we're visiting this config, should we add
>>>> "depends on MACH_BCM_MOBILE" as well?
>>>
>>> No, it's nice to get the compile coverage.
>>
>> But maybe you can experiment with that special option that only
>> turns on the driver on other platforms to do compile test.
>
> a/k/a
> depends on XXX || COMPILE_TEST

Yep, thanks Stephen :-)

Linus Walleij

^ permalink raw reply

* [PATCH v4 3/4] ARM: pinctrl: Add Broadcom Capri pinctrl driver
From: Linus Walleij @ 2014-01-20  8:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140118025600.GS31049@beef>

On Sat, Jan 18, 2014 at 3:56 AM, Matt Porter <mporter@linaro.org> wrote:

> I wonder if Linus would accept a rename at this point (too late for 3.14
> presumably, but for 3.15) of s/capri/bcm281xx throughout, bcm11351 for
> the compatible string, as we have for the machine compatible, and also
> BCM281XX for the Kconfig option.

Yes, if there is some consensus that this is what we want to do.

I can certainly merge that during the 3.14-rc phase for that matter.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH RFC 4/6] net: rfkill: gpio: add device tree support
From: Heikki Krogerus @ 2014-01-20  8:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CACRpkdZOD4zeA8T5kbJ4c5NsnuzHCg1mw8rRMYNT9c4R-Qnc6A@mail.gmail.com>

Hi,

On Sat, Jan 18, 2014 at 12:11:56AM +0100, Linus Walleij wrote:
> On Fri, Jan 17, 2014 at 6:43 PM, Chen-Yu Tsai <wens@csie.org> wrote:
> > On Sat, Jan 18, 2014 at 12:47 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> 
> >>> +- NAME_shutdown-gpios  : GPIO phandle to shutdown control
> >>> +                         (phandle must be the second)
> >>> +- NAME_reset-gpios     : GPIO phandle to reset control
> >>> +
> >>> +NAME must match the rfkill-name property. NAME_shutdown-gpios or
> >>> +NAME_reset-gpios, or both, must be defined.
> >>> +
> >>
> >> I don't understand this part. Why do you include the name in the
> >> gpios property, rather than just hardcoding the property strings
> >> to "shutdown-gpios" and "reset-gpios"?
> >
> > This quirk is a result of how gpiod_get_index implements device tree
> > lookup.
> 
> Why can't it just have a single property "gpios", where the first
> element is the reset GPIO and the second is the shutdown GPIO?
> 
> rfkill-gpio does this:
> 
> gpio = devm_gpiod_get_index(&pdev->dev, rfkill->reset_name, 0);
> gpio = devm_gpiod_get_index(&pdev->dev, rfkill->shutdown_name, 1);
> 
> The passed con ID name parameter is only there for the device
> tree case it seems. (ACPI ignores it.) So what about you just
> don't pass it at all and patch it to do like this instead:
> 
> gpio = devm_gpiod_get_index(&pdev->dev, NULL, 0);
> gpio = devm_gpiod_get_index(&pdev->dev, NULL, 1);
> 
> Heikki, are you OK with this change?

Yes, definitely. That is much cleaner.

Thanks,

-- 
heikki

^ permalink raw reply

* [PATCH v2 1/7] cpufreq: cpufreq-cpu0: allow optional safe voltage during frequency transitions
From: Lukasz Majewski @ 2014-01-20  8:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390047057-2239-2-git-send-email-thomas.ab@samsung.com>

Hi Thomas,

> From: Thomas Abraham <thomas.ab@samsung.com>
> 
> On some platforms such as the Samsung Exynos, changing the frequency
> of the CPU clock requires changing the frequency of the PLL that is
> supplying the CPU clock. To change the frequency of the PLL, the CPU
> clock is temporarily reparented to another parent clock.
> 
> The clock frequency of this temporary parent clock could be much
> higher than the clock frequency of the PLL at the time of
> reparenting. Due to the temporary increase in the CPU clock speed,
> the CPU (and any other components in the CPU clock domain such as
> dividers, mux, etc.) have to to be operated at a higher voltage
> level, called the safe voltage level. This patch adds optional
> support to temporarily switch to a safe voltage level during CPU
> frequency transitions.
> 
> Cc: Shawn Guo <shawn.guo@linaro.org>
> Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
> ---
>  .../devicetree/bindings/cpufreq/cpufreq-cpu0.txt   |    7 ++++
>  drivers/cpufreq/cpufreq-cpu0.c                     |   37
> +++++++++++++++++-- 2 files changed, 40 insertions(+), 4 deletions(-)
> 
> diff --git
> a/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt
> b/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt index
> f055515..37453ab 100644 ---
> a/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt +++
> b/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt @@ -19,6
> +19,12 @@ Optional properties:
>  - cooling-min-level:
>  - cooling-max-level:
>       Please refer to
> Documentation/devicetree/bindings/thermal/thermal.txt. +- safe-opp:
> Certain platforms require that during a opp transition,
> +  a system should not go below a particular opp level. For such
> systems,
> +  this property specifies the minimum opp to be maintained during the
> +  opp transitions. The safe-opp value is a tuple with first element
> +  representing the safe frequency and the second element
> representing the
> +  safe voltage.
>  
>  Examples:
>  
> @@ -36,6 +42,7 @@ cpus {
>  			396000  950000
>  			198000  850000
>  		>;
> +		safe-opp = <396000 950000>
>  		clock-latency = <61036>; /* two CLK32 periods */
>  		#cooling-cells = <2>;
>  		cooling-min-level = <0>;
> diff --git a/drivers/cpufreq/cpufreq-cpu0.c
> b/drivers/cpufreq/cpufreq-cpu0.c index 0c12ffc..075d3d1 100644
> --- a/drivers/cpufreq/cpufreq-cpu0.c
> +++ b/drivers/cpufreq/cpufreq-cpu0.c
> @@ -27,6 +27,8 @@
>  
>  static unsigned int transition_latency;
>  static unsigned int voltage_tolerance; /* in percentage */
> +static unsigned long safe_frequency;
> +static unsigned long safe_voltage;
>  
>  static struct device *cpu_dev;
>  static struct clk *cpu_clk;
> @@ -64,17 +66,30 @@ static int cpu0_set_target(struct cpufreq_policy
> *policy, unsigned int index) volt_old =
> regulator_get_voltage(cpu_reg); }
>  
> -	pr_debug("%u MHz, %ld mV --> %u MHz, %ld mV\n",
> +	pr_debug("\n\n%u MHz, %ld mV --> %u MHz, %ld mV\n",
>  		 old_freq / 1000, volt_old ? volt_old / 1000 : -1,
>  		 new_freq / 1000, volt ? volt / 1000 : -1);
>  
>  	/* scaling up?  scale voltage before frequency */
> -	if (!IS_ERR(cpu_reg) && new_freq > old_freq) {
> +	if (!IS_ERR(cpu_reg) && new_freq > old_freq &&
> +				new_freq >= safe_frequency) {
>  		ret = regulator_set_voltage_tol(cpu_reg, volt, tol);
>  		if (ret) {
>  			pr_err("failed to scale voltage up: %d\n",
> ret); return ret;
>  		}
> +	} else if (!IS_ERR(cpu_reg) && old_freq < safe_frequency) {
> +		/*
> +		 * the scaled up voltage level for the new_freq is
> lower
> +		 * than the safe voltage level. so set safe_voltage
> +		 * as the intermediate voltage level and revert it
> +		 * back after the frequency has been changed.
> +		 */
> +		ret = regulator_set_voltage_tol(cpu_reg,
> safe_voltage, tol);
> +		if (ret) {
> +			pr_err("failed to set safe voltage: %d\n",
> ret);
> +			return ret;
> +		}
>  	}
>  
>  	ret = clk_set_rate(cpu_clk, freq_exact);
> @@ -86,7 +101,8 @@ static int cpu0_set_target(struct cpufreq_policy
> *policy, unsigned int index) }
>  
>  	/* scaling down?  scale voltage after frequency */
> -	if (!IS_ERR(cpu_reg) && new_freq < old_freq) {
> +	if (!IS_ERR(cpu_reg) &&
> +			(new_freq < old_freq || new_freq <
> safe_frequency)) { ret = regulator_set_voltage_tol(cpu_reg, volt,
> tol); if (ret) {
>  			pr_err("failed to scale voltage down: %d\n",
> ret); @@ -116,6 +132,8 @@ static struct cpufreq_driver
> cpu0_cpufreq_driver = { 
>  static int cpu0_cpufreq_probe(struct platform_device *pdev)
>  {
> +	const struct property *prop;
> +	struct dev_pm_opp *opp;
>  	struct device_node *np;
>  	int ret;
>  
> @@ -165,13 +183,24 @@ static int cpu0_cpufreq_probe(struct
> platform_device *pdev) goto out_put_node;
>  	}
>  
> +	prop = of_find_property(np, "safe-opp", NULL);
> +	if (prop) {
> +		if (prop->value && (prop->length / sizeof(u32)) ==
> 2) {
> +			const __be32 *val;
> +			val = prop->value;
> +			safe_frequency = be32_to_cpup(val++);
> +			safe_voltage = be32_to_cpup(val);
> +		} else {
> +			pr_err("invalid safe-opp level specified\n");
> +		}
> +	}
> +
>  	of_property_read_u32(np, "voltage-tolerance",
> &voltage_tolerance); 
>  	if (of_property_read_u32(np, "clock-latency",
> &transition_latency)) transition_latency = CPUFREQ_ETERNAL;
>  
>  	if (!IS_ERR(cpu_reg)) {
> -		struct dev_pm_opp *opp;
>  		unsigned long min_uV, max_uV;
>  		int i;
>  

Reviewed-by: Lukasz Majewski <l.majewski@samsung.com>

-- 
Best regards,

Lukasz Majewski

Samsung R&D Institute Poland (SRPOL) | Linux Platform Group

^ permalink raw reply

* [PATCH v2 7/7] cpufreq: exynos: remove all exynos specific cpufreq driver support
From: Lukasz Majewski @ 2014-01-20  8:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390047057-2239-8-git-send-email-thomas.ab@samsung.com>

Hi Thomas,

> From: Thomas Abraham <thomas.ab@samsung.com>
> 
> Exynos4210, Exynos4x12 and Exynos5250 based platforms have switched
> over to use cpufreq-cpu0 driver for cpufreq functionality. So the
> Exynos specific cpufreq drivers for these platforms can be removed.
> 
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Cc: Jaecheol Lee <jc.lee@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
> ---
>  drivers/cpufreq/Kconfig.arm          |   36 ----
>  drivers/cpufreq/Makefile             |    4 -
>  drivers/cpufreq/exynos-cpufreq.c     |  292
> ----------------------------------
> drivers/cpufreq/exynos-cpufreq.h     |   91 -----------
> drivers/cpufreq/exynos4210-cpufreq.c |  157 ------------------
> drivers/cpufreq/exynos4x12-cpufreq.c |  211 ------------------------
> drivers/cpufreq/exynos5250-cpufreq.c |  183 --------------------- 7
> files changed, 0 insertions(+), 974 deletions(-) delete mode 100644
> drivers/cpufreq/exynos-cpufreq.c delete mode 100644
> drivers/cpufreq/exynos-cpufreq.h delete mode 100644
> drivers/cpufreq/exynos4210-cpufreq.c delete mode 100644
> drivers/cpufreq/exynos4x12-cpufreq.c delete mode 100644
> drivers/cpufreq/exynos5250-cpufreq.c
> 
> diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
> index 3129749..704656d 100644
> --- a/drivers/cpufreq/Kconfig.arm
> +++ b/drivers/cpufreq/Kconfig.arm
> @@ -16,42 +16,6 @@ config ARM_DT_BL_CPUFREQ
>  	  This enables probing via DT for Generic CPUfreq driver for
> ARM big.LITTLE platform. This gets frequency tables from DT.
>  
> -config ARM_EXYNOS_CPUFREQ
> -	bool
> -
> -config ARM_EXYNOS4210_CPUFREQ
> -	bool "SAMSUNG EXYNOS4210"
> -	depends on CPU_EXYNOS4210
> -	default y
> -	select ARM_EXYNOS_CPUFREQ
> -	help
> -	  This adds the CPUFreq driver for Samsung EXYNOS4210
> -	  SoC (S5PV310 or S5PC210).
> -
> -	  If in doubt, say N.
> -
> -config ARM_EXYNOS4X12_CPUFREQ
> -	bool "SAMSUNG EXYNOS4x12"
> -	depends on (SOC_EXYNOS4212 || SOC_EXYNOS4412)
> -	default y
> -	select ARM_EXYNOS_CPUFREQ
> -	help
> -	  This adds the CPUFreq driver for Samsung EXYNOS4X12
> -	  SoC (EXYNOS4212 or EXYNOS4412).
> -
> -	  If in doubt, say N.
> -
> -config ARM_EXYNOS5250_CPUFREQ
> -	bool "SAMSUNG EXYNOS5250"
> -	depends on SOC_EXYNOS5250
> -	default y
> -	select ARM_EXYNOS_CPUFREQ
> -	help
> -	  This adds the CPUFreq driver for Samsung EXYNOS5250
> -	  SoC.
> -
> -	  If in doubt, say N.
> -
>  config ARM_EXYNOS5440_CPUFREQ
>  	bool "SAMSUNG EXYNOS5440"
>  	depends on SOC_EXYNOS5440
> diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
> index 7494565..3abfe05 100644
> --- a/drivers/cpufreq/Makefile
> +++ b/drivers/cpufreq/Makefile
> @@ -49,10 +49,6 @@ obj-$(CONFIG_ARM_DT_BL_CPUFREQ)		+=
> arm_big_little_dt.o 
>  obj-$(CONFIG_ARCH_DAVINCI_DA850)	+= davinci-cpufreq.o
>  obj-$(CONFIG_UX500_SOC_DB8500)		+= dbx500-cpufreq.o
> -obj-$(CONFIG_ARM_EXYNOS_CPUFREQ)	+= exynos-cpufreq.o
> -obj-$(CONFIG_ARM_EXYNOS4210_CPUFREQ)	+= exynos4210-cpufreq.o
> -obj-$(CONFIG_ARM_EXYNOS4X12_CPUFREQ)	+= exynos4x12-cpufreq.o
> -obj-$(CONFIG_ARM_EXYNOS5250_CPUFREQ)	+= exynos5250-cpufreq.o
>  obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ)	+= exynos5440-cpufreq.o
>  obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ)	+= highbank-cpufreq.o
>  obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)		+= imx6q-cpufreq.o
> diff --git a/drivers/cpufreq/exynos-cpufreq.c
> b/drivers/cpufreq/exynos-cpufreq.c deleted file mode 100644
> index fcd2914..0000000
> --- a/drivers/cpufreq/exynos-cpufreq.c
> +++ /dev/null
> @@ -1,292 +0,0 @@
> -/*
> - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
> - *		http://www.samsung.com
> - *
> - * EXYNOS - CPU frequency scaling support for EXYNOS series
> - *
> - * This program is free software; you can redistribute it and/or
> modify
> - * it under the terms of the GNU General Public License version 2 as
> - * published by the Free Software Foundation.
> -*/
> -
> -#include <linux/kernel.h>
> -#include <linux/err.h>
> -#include <linux/clk.h>
> -#include <linux/io.h>
> -#include <linux/slab.h>
> -#include <linux/regulator/consumer.h>
> -#include <linux/cpufreq.h>
> -#include <linux/suspend.h>
> -#include <linux/platform_device.h>
> -
> -#include <plat/cpu.h>
> -
> -#include "exynos-cpufreq.h"
> -
> -static struct exynos_dvfs_info *exynos_info;
> -
> -static struct regulator *arm_regulator;
> -
> -static unsigned int locking_frequency;
> -static bool frequency_locked;
> -static DEFINE_MUTEX(cpufreq_lock);
> -
> -static int exynos_cpufreq_get_index(unsigned int freq)
> -{
> -	struct cpufreq_frequency_table *freq_table =
> exynos_info->freq_table;
> -	int index;
> -
> -	for (index = 0;
> -		freq_table[index].frequency != CPUFREQ_TABLE_END;
> index++)
> -		if (freq_table[index].frequency == freq)
> -			break;
> -
> -	if (freq_table[index].frequency == CPUFREQ_TABLE_END)
> -		return -EINVAL;
> -
> -	return index;
> -}
> -
> -static int exynos_cpufreq_scale(unsigned int target_freq)
> -{
> -	struct cpufreq_frequency_table *freq_table =
> exynos_info->freq_table;
> -	unsigned int *volt_table = exynos_info->volt_table;
> -	struct cpufreq_policy *policy = cpufreq_cpu_get(0);
> -	unsigned int arm_volt, safe_arm_volt = 0;
> -	unsigned int mpll_freq_khz = exynos_info->mpll_freq_khz;
> -	unsigned int old_freq;
> -	int index, old_index;
> -	int ret = 0;
> -
> -	old_freq = policy->cur;
> -
> -	/*
> -	 * The policy max have been changed so that we cannot get
> proper
> -	 * old_index with cpufreq_frequency_table_target(). Thus,
> ignore
> -	 * policy and get the index from the raw frequency table.
> -	 */
> -	old_index = exynos_cpufreq_get_index(old_freq);
> -	if (old_index < 0) {
> -		ret = old_index;
> -		goto out;
> -	}
> -
> -	index = exynos_cpufreq_get_index(target_freq);
> -	if (index < 0) {
> -		ret = index;
> -		goto out;
> -	}
> -
> -	/*
> -	 * ARM clock source will be changed APLL to MPLL temporary
> -	 * To support this level, need to control regulator for
> -	 * required voltage level
> -	 */
> -	if (exynos_info->need_apll_change != NULL) {
> -		if (exynos_info->need_apll_change(old_index, index)
> &&
> -		   (freq_table[index].frequency < mpll_freq_khz) &&
> -		   (freq_table[old_index].frequency < mpll_freq_khz))
> -			safe_arm_volt =
> volt_table[exynos_info->pll_safe_idx];
> -	}
> -	arm_volt = volt_table[index];
> -
> -	/* When the new frequency is higher than current frequency */
> -	if ((target_freq > old_freq) && !safe_arm_volt) {
> -		/* Firstly, voltage up to increase frequency */
> -		ret = regulator_set_voltage(arm_regulator, arm_volt,
> arm_volt);
> -		if (ret) {
> -			pr_err("%s: failed to set cpu voltage to
> %d\n",
> -				__func__, arm_volt);
> -			return ret;
> -		}
> -	}
> -
> -	if (safe_arm_volt) {
> -		ret = regulator_set_voltage(arm_regulator,
> safe_arm_volt,
> -				      safe_arm_volt);
> -		if (ret) {
> -			pr_err("%s: failed to set cpu voltage to
> %d\n",
> -				__func__, safe_arm_volt);
> -			return ret;
> -		}
> -	}
> -
> -	exynos_info->set_freq(old_index, index);
> -
> -	/* When the new frequency is lower than current frequency */
> -	if ((target_freq < old_freq) ||
> -	   ((target_freq > old_freq) && safe_arm_volt)) {
> -		/* down the voltage after frequency change */
> -		ret = regulator_set_voltage(arm_regulator, arm_volt,
> -				arm_volt);
> -		if (ret) {
> -			pr_err("%s: failed to set cpu voltage to
> %d\n",
> -				__func__, arm_volt);
> -			goto out;
> -		}
> -	}
> -
> -out:
> -	cpufreq_cpu_put(policy);
> -
> -	return ret;
> -}
> -
> -static int exynos_target(struct cpufreq_policy *policy, unsigned int
> index) -{
> -	struct cpufreq_frequency_table *freq_table =
> exynos_info->freq_table;
> -	int ret = 0;
> -
> -	mutex_lock(&cpufreq_lock);
> -
> -	if (frequency_locked)
> -		goto out;
> -
> -	ret = exynos_cpufreq_scale(freq_table[index].frequency);
> -
> -out:
> -	mutex_unlock(&cpufreq_lock);
> -
> -	return ret;
> -}
> -
> -#ifdef CONFIG_PM
> -static int exynos_cpufreq_suspend(struct cpufreq_policy *policy)
> -{
> -	return 0;
> -}
> -
> -static int exynos_cpufreq_resume(struct cpufreq_policy *policy)
> -{
> -	return 0;
> -}
> -#endif
> -
> -/**
> - * exynos_cpufreq_pm_notifier - block CPUFREQ's activities in
> suspend-resume
> - *			context
> - * @notifier
> - * @pm_event
> - * @v
> - *
> - * While frequency_locked == true, target() ignores every frequency
> but
> - * locking_frequency. The locking_frequency value is the initial
> frequency,
> - * which is set by the bootloader. In order to eliminate possible
> - * inconsistency in clock values, we save and restore frequencies
> during
> - * suspend and resume and block CPUFREQ activities. Note that the
> standard
> - * suspend/resume cannot be used as they are too deep (syscore_ops)
> for
> - * regulator actions.
> - */
> -static int exynos_cpufreq_pm_notifier(struct notifier_block
> *notifier,
> -				       unsigned long pm_event, void
> *v) -{
> -	int ret;
> -
> -	switch (pm_event) {
> -	case PM_SUSPEND_PREPARE:
> -		mutex_lock(&cpufreq_lock);
> -		frequency_locked = true;
> -		mutex_unlock(&cpufreq_lock);
> -
> -		ret = exynos_cpufreq_scale(locking_frequency);
> -		if (ret < 0)
> -			return NOTIFY_BAD;
> -
> -		break;
> -
> -	case PM_POST_SUSPEND:
> -		mutex_lock(&cpufreq_lock);
> -		frequency_locked = false;
> -		mutex_unlock(&cpufreq_lock);
> -		break;
> -	}
> -
> -	return NOTIFY_OK;
> -}
> -
> -static struct notifier_block exynos_cpufreq_nb = {
> -	.notifier_call = exynos_cpufreq_pm_notifier,
> -};
> -
> -static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy)
> -{
> -	policy->clk = exynos_info->cpu_clk;
> -	return cpufreq_generic_init(policy, exynos_info->freq_table,
> 100000); -}
> -
> -static struct cpufreq_driver exynos_driver = {
> -	.flags		= CPUFREQ_STICKY |
> CPUFREQ_NEED_INITIAL_FREQ_CHECK,
> -	.verify		=
> cpufreq_generic_frequency_table_verify,
> -	.target_index	= exynos_target,
> -	.get		= cpufreq_generic_get,
> -	.init		= exynos_cpufreq_cpu_init,
> -	.exit		= cpufreq_generic_exit,
> -	.name		= "exynos_cpufreq",
> -	.attr		= cpufreq_generic_attr,
> -#ifdef CONFIG_ARM_EXYNOS_CPU_FREQ_BOOST_SW
> -	.boost_supported = true,
> -#endif
> -#ifdef CONFIG_PM
> -	.suspend	= exynos_cpufreq_suspend,
> -	.resume		= exynos_cpufreq_resume,
> -#endif
> -};
> -
> -static int exynos_cpufreq_probe(struct platform_device *pdev)
> -{
> -	int ret = -EINVAL;
> -
> -	exynos_info = kzalloc(sizeof(*exynos_info), GFP_KERNEL);
> -	if (!exynos_info)
> -		return -ENOMEM;
> -
> -	if (soc_is_exynos4210())
> -		ret = exynos4210_cpufreq_init(exynos_info);
> -	else if (soc_is_exynos4212() || soc_is_exynos4412())
> -		ret = exynos4x12_cpufreq_init(exynos_info);
> -	else if (soc_is_exynos5250())
> -		ret = exynos5250_cpufreq_init(exynos_info);
> -	else
> -		return 0;
> -
> -	if (ret)
> -		goto err_vdd_arm;
> -
> -	if (exynos_info->set_freq == NULL) {
> -		pr_err("%s: No set_freq function (ERR)\n", __func__);
> -		goto err_vdd_arm;
> -	}
> -
> -	arm_regulator = regulator_get(NULL, "vdd_arm");
> -	if (IS_ERR(arm_regulator)) {
> -		pr_err("%s: failed to get resource vdd_arm\n",
> __func__);
> -		goto err_vdd_arm;
> -	}
> -
> -	locking_frequency = clk_get_rate(exynos_info->cpu_clk) /
> 1000; -
> -	register_pm_notifier(&exynos_cpufreq_nb);
> -
> -	if (cpufreq_register_driver(&exynos_driver)) {
> -		pr_err("%s: failed to register cpufreq driver\n",
> __func__);
> -		goto err_cpufreq;
> -	}
> -
> -	return 0;
> -err_cpufreq:
> -	unregister_pm_notifier(&exynos_cpufreq_nb);
> -
> -	regulator_put(arm_regulator);
> -err_vdd_arm:
> -	kfree(exynos_info);
> -	return -EINVAL;
> -}
> -
> -static struct platform_driver exynos_cpufreq_platdrv = {
> -	.driver = {
> -		.name	= "exynos-cpufreq",
> -		.owner	= THIS_MODULE,
> -	},
> -	.probe = exynos_cpufreq_probe,
> -};
> -module_platform_driver(exynos_cpufreq_platdrv);
> diff --git a/drivers/cpufreq/exynos-cpufreq.h
> b/drivers/cpufreq/exynos-cpufreq.h deleted file mode 100644
> index 3ddade8..0000000
> --- a/drivers/cpufreq/exynos-cpufreq.h
> +++ /dev/null
> @@ -1,91 +0,0 @@
> -/*
> - * Copyright (c) 2010 Samsung Electronics Co., Ltd.
> - *		http://www.samsung.com
> - *
> - * EXYNOS - CPUFreq support
> - *
> - * This program is free software; you can redistribute it and/or
> modify
> - * it under the terms of the GNU General Public License version 2 as
> - * published by the Free Software Foundation.
> -*/
> -
> -enum cpufreq_level_index {
> -	L0, L1, L2, L3, L4,
> -	L5, L6, L7, L8, L9,
> -	L10, L11, L12, L13, L14,
> -	L15, L16, L17, L18, L19,
> -	L20,
> -};
> -
> -#define APLL_FREQ(f, a0, a1, a2, a3, a4, a5, a6, a7, b0, b1, b2, m,
> p, s) \
> -	{ \
> -		.freq = (f) * 1000, \
> -		.clk_div_cpu0 = ((a0) | (a1) << 4 | (a2) << 8 | (a3)
> << 12 | \
> -			(a4) << 16 | (a5) << 20 | (a6) << 24 | (a7)
> << 28), \
> -		.clk_div_cpu1 = (b0 << 0 | b1 << 4 | b2 << 8), \
> -		.mps = ((m) << 16 | (p) << 8 | (s)), \
> -	}
> -
> -struct apll_freq {
> -	unsigned int freq;
> -	u32 clk_div_cpu0;
> -	u32 clk_div_cpu1;
> -	u32 mps;
> -};
> -
> -struct exynos_dvfs_info {
> -	unsigned long	mpll_freq_khz;
> -	unsigned int	pll_safe_idx;
> -	struct clk	*cpu_clk;
> -	unsigned int	*volt_table;
> -	struct cpufreq_frequency_table	*freq_table;
> -	void (*set_freq)(unsigned int, unsigned int);
> -	bool (*need_apll_change)(unsigned int, unsigned int);
> -};
> -
> -#ifdef CONFIG_ARM_EXYNOS4210_CPUFREQ
> -extern int exynos4210_cpufreq_init(struct exynos_dvfs_info *);
> -#else
> -static inline int exynos4210_cpufreq_init(struct exynos_dvfs_info
> *info) -{
> -	return -EOPNOTSUPP;
> -}
> -#endif
> -#ifdef CONFIG_ARM_EXYNOS4X12_CPUFREQ
> -extern int exynos4x12_cpufreq_init(struct exynos_dvfs_info *);
> -#else
> -static inline int exynos4x12_cpufreq_init(struct exynos_dvfs_info
> *info) -{
> -	return -EOPNOTSUPP;
> -}
> -#endif
> -#ifdef CONFIG_ARM_EXYNOS5250_CPUFREQ
> -extern int exynos5250_cpufreq_init(struct exynos_dvfs_info *);
> -#else
> -static inline int exynos5250_cpufreq_init(struct exynos_dvfs_info
> *info) -{
> -	return -EOPNOTSUPP;
> -}
> -#endif
> -
> -#include <plat/cpu.h>
> -#include <mach/map.h>
> -
> -#define EXYNOS4_CLKSRC_CPU			(S5P_VA_CMU +
> 0x14200) -#define EXYNOS4_CLKMUX_STATCPU
> (S5P_VA_CMU + 0x14400) -
> -#define EXYNOS4_CLKDIV_CPU			(S5P_VA_CMU +
> 0x14500) -#define EXYNOS4_CLKDIV_CPU1
> (S5P_VA_CMU + 0x14504) -#define
> EXYNOS4_CLKDIV_STATCPU			(S5P_VA_CMU + 0x14600)
> -#define EXYNOS4_CLKDIV_STATCPU1			(S5P_VA_CMU +
> 0x14604) - -#define EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT	(16)
> -#define EXYNOS4_CLKMUX_STATCPU_MUXCORE_MASK	(0x7 <<
> EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT) -
> -#define EXYNOS5_APLL_LOCK			(S5P_VA_CMU +
> 0x00000) -#define EXYNOS5_APLL_CON0
> (S5P_VA_CMU + 0x00100) -#define
> EXYNOS5_CLKMUX_STATCPU			(S5P_VA_CMU + 0x00400)
> -#define EXYNOS5_CLKDIV_CPU0			(S5P_VA_CMU +
> 0x00500) -#define EXYNOS5_CLKDIV_CPU1
> (S5P_VA_CMU + 0x00504) -#define
> EXYNOS5_CLKDIV_STATCPU0			(S5P_VA_CMU + 0x00600)
> -#define EXYNOS5_CLKDIV_STATCPU1			(S5P_VA_CMU +
> 0x00604) diff --git a/drivers/cpufreq/exynos4210-cpufreq.c
> b/drivers/cpufreq/exynos4210-cpufreq.c deleted file mode 100644 index
> 40d84c4..0000000 --- a/drivers/cpufreq/exynos4210-cpufreq.c
> +++ /dev/null @@ -1,157 +0,0 @@
> -/*
> - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
> - *		http://www.samsung.com
> - *
> - * EXYNOS4210 - CPU frequency scaling support
> - *
> - * This program is free software; you can redistribute it and/or
> modify
> - * it under the terms of the GNU General Public License version 2 as
> - * published by the Free Software Foundation.
> -*/
> -
> -#include <linux/module.h>
> -#include <linux/kernel.h>
> -#include <linux/err.h>
> -#include <linux/clk.h>
> -#include <linux/io.h>
> -#include <linux/slab.h>
> -#include <linux/cpufreq.h>
> -
> -#include "exynos-cpufreq.h"
> -
> -static struct clk *cpu_clk;
> -static struct clk *moutcore;
> -static struct clk *mout_mpll;
> -static struct clk *mout_apll;
> -
> -static unsigned int exynos4210_volt_table[] = {
> -	1250000, 1150000, 1050000, 975000, 950000,
> -};
> -
> -static struct cpufreq_frequency_table exynos4210_freq_table[] = {
> -	{L0, 1200 * 1000},
> -	{L1, 1000 * 1000},
> -	{L2,  800 * 1000},
> -	{L3,  500 * 1000},
> -	{L4,  200 * 1000},
> -	{0, CPUFREQ_TABLE_END},
> -};
> -
> -static struct apll_freq apll_freq_4210[] = {
> -	/*
> -	 * values:
> -	 * freq
> -	 * clock divider for CORE, COREM0, COREM1, PERIPH, ATB,
> PCLK_DBG, APLL, RESERVED
> -	 * clock divider for COPY, HPM, RESERVED
> -	 * PLL M, P, S
> -	 */
> -	APLL_FREQ(1200, 0, 3, 7, 3, 4, 1, 7, 0, 5, 0, 0, 150, 3, 1),
> -	APLL_FREQ(1000, 0, 3, 7, 3, 4, 1, 7, 0, 4, 0, 0, 250, 6, 1),
> -	APLL_FREQ(800,  0, 3, 7, 3, 3, 1, 7, 0, 3, 0, 0, 200, 6, 1),
> -	APLL_FREQ(500,  0, 3, 7, 3, 3, 1, 7, 0, 3, 0, 0, 250, 6, 2),
> -	APLL_FREQ(200,  0, 1, 3, 1, 3, 1, 0, 0, 3, 0, 0, 200, 6, 3),
> -};
> -
> -static void exynos4210_set_clkdiv(unsigned int div_index)
> -{
> -	unsigned int tmp;
> -
> -	/* Change Divider - CPU0 */
> -
> -	tmp = apll_freq_4210[div_index].clk_div_cpu0;
> -
> -	__raw_writel(tmp, EXYNOS4_CLKDIV_CPU);
> -
> -	do {
> -		tmp = __raw_readl(EXYNOS4_CLKDIV_STATCPU);
> -	} while (tmp & 0x1111111);
> -
> -	/* Change Divider - CPU1 */
> -
> -	tmp = apll_freq_4210[div_index].clk_div_cpu1;
> -
> -	__raw_writel(tmp, EXYNOS4_CLKDIV_CPU1);
> -
> -	do {
> -		tmp = __raw_readl(EXYNOS4_CLKDIV_STATCPU1);
> -	} while (tmp & 0x11);
> -}
> -
> -static void exynos4210_set_apll(unsigned int index)
> -{
> -	unsigned int tmp, freq = apll_freq_4210[index].freq;
> -
> -	/* MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */
> -	clk_set_parent(moutcore, mout_mpll);
> -
> -	do {
> -		tmp = (__raw_readl(EXYNOS4_CLKMUX_STATCPU)
> -			>> EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT);
> -		tmp &= 0x7;
> -	} while (tmp != 0x2);
> -
> -	clk_set_rate(mout_apll, freq * 1000);
> -
> -	/* MUX_CORE_SEL = APLL */
> -	clk_set_parent(moutcore, mout_apll);
> -
> -	do {
> -		tmp = __raw_readl(EXYNOS4_CLKMUX_STATCPU);
> -		tmp &= EXYNOS4_CLKMUX_STATCPU_MUXCORE_MASK;
> -	} while (tmp != (0x1 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT));
> -}
> -
> -static void exynos4210_set_frequency(unsigned int old_index,
> -				     unsigned int new_index)
> -{
> -	if (old_index > new_index) {
> -		exynos4210_set_clkdiv(new_index);
> -		exynos4210_set_apll(new_index);
> -	} else if (old_index < new_index) {
> -		exynos4210_set_apll(new_index);
> -		exynos4210_set_clkdiv(new_index);
> -	}
> -}
> -
> -int exynos4210_cpufreq_init(struct exynos_dvfs_info *info)
> -{
> -	unsigned long rate;
> -
> -	cpu_clk = clk_get(NULL, "armclk");
> -	if (IS_ERR(cpu_clk))
> -		return PTR_ERR(cpu_clk);
> -
> -	moutcore = clk_get(NULL, "moutcore");
> -	if (IS_ERR(moutcore))
> -		goto err_moutcore;
> -
> -	mout_mpll = clk_get(NULL, "mout_mpll");
> -	if (IS_ERR(mout_mpll))
> -		goto err_mout_mpll;
> -
> -	rate = clk_get_rate(mout_mpll) / 1000;
> -
> -	mout_apll = clk_get(NULL, "mout_apll");
> -	if (IS_ERR(mout_apll))
> -		goto err_mout_apll;
> -
> -	info->mpll_freq_khz = rate;
> -	/* 800Mhz */
> -	info->pll_safe_idx = L2;
> -	info->cpu_clk = cpu_clk;
> -	info->volt_table = exynos4210_volt_table;
> -	info->freq_table = exynos4210_freq_table;
> -	info->set_freq = exynos4210_set_frequency;
> -
> -	return 0;
> -
> -err_mout_apll:
> -	clk_put(mout_mpll);
> -err_mout_mpll:
> -	clk_put(moutcore);
> -err_moutcore:
> -	clk_put(cpu_clk);
> -
> -	pr_debug("%s: failed initialization\n", __func__);
> -	return -EINVAL;
> -}
> diff --git a/drivers/cpufreq/exynos4x12-cpufreq.c
> b/drivers/cpufreq/exynos4x12-cpufreq.c deleted file mode 100644
> index 7c11ace..0000000
> --- a/drivers/cpufreq/exynos4x12-cpufreq.c
> +++ /dev/null
> @@ -1,211 +0,0 @@
> -/*
> - * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
> - *		http://www.samsung.com
> - *
> - * EXYNOS4X12 - CPU frequency scaling support
> - *
> - * This program is free software; you can redistribute it and/or
> modify
> - * it under the terms of the GNU General Public License version 2 as
> - * published by the Free Software Foundation.
> -*/
> -
> -#include <linux/module.h>
> -#include <linux/kernel.h>
> -#include <linux/err.h>
> -#include <linux/clk.h>
> -#include <linux/io.h>
> -#include <linux/slab.h>
> -#include <linux/cpufreq.h>
> -
> -#include "exynos-cpufreq.h"
> -
> -static struct clk *cpu_clk;
> -static struct clk *moutcore;
> -static struct clk *mout_mpll;
> -static struct clk *mout_apll;
> -
> -static unsigned int exynos4x12_volt_table[] = {
> -	1350000, 1287500, 1250000, 1187500, 1137500, 1087500,
> 1037500,
> -	1000000,  987500,  975000,  950000,  925000,  900000,  900000
> -};
> -
> -static struct cpufreq_frequency_table exynos4x12_freq_table[] = {
> -	{CPUFREQ_BOOST_FREQ, 1500 * 1000},

Here, you are removing BOOST support for Exynos4412, without any code,
which brings back this functionality in the new code.

I'd propose adding new property to cpus node and during
operating-points parsing mark the entry at the cpufreq_frequency_table
accordingly.

> -	{L1, 1400 * 1000},
> -	{L2, 1300 * 1000},
> -	{L3, 1200 * 1000},
> -	{L4, 1100 * 1000},
> -	{L5, 1000 * 1000},
> -	{L6,  900 * 1000},
> -	{L7,  800 * 1000},
> -	{L8,  700 * 1000},
> -	{L9,  600 * 1000},
> -	{L10, 500 * 1000},
> -	{L11, 400 * 1000},
> -	{L12, 300 * 1000},
> -	{L13, 200 * 1000},
> -	{0, CPUFREQ_TABLE_END},
> -};
> -
> -static struct apll_freq *apll_freq_4x12;
> -
> -static struct apll_freq apll_freq_4212[] = {
> -	/*
> -	 * values:
> -	 * freq
> -	 * clock divider for CORE, COREM0, COREM1, PERIPH, ATB,
> PCLK_DBG, APLL, CORE2
> -	 * clock divider for COPY, HPM, RESERVED
> -	 * PLL M, P, S
> -	 */
> -	APLL_FREQ(1500, 0, 3, 7, 0, 6, 1, 2, 0, 6, 2, 0, 250, 4, 0),
> -	APLL_FREQ(1400, 0, 3, 7, 0, 6, 1, 2, 0, 6, 2, 0, 175, 3, 0),
> -	APLL_FREQ(1300, 0, 3, 7, 0, 5, 1, 2, 0, 5, 2, 0, 325, 6, 0),
> -	APLL_FREQ(1200, 0, 3, 7, 0, 5, 1, 2, 0, 5, 2, 0, 200, 4, 0),
> -	APLL_FREQ(1100, 0, 3, 6, 0, 4, 1, 2, 0, 4, 2, 0, 275, 6, 0),
> -	APLL_FREQ(1000, 0, 2, 5, 0, 4, 1, 1, 0, 4, 2, 0, 125, 3, 0),
> -	APLL_FREQ(900,  0, 2, 5, 0, 3, 1, 1, 0, 3, 2, 0, 150, 4, 0),
> -	APLL_FREQ(800,  0, 2, 5, 0, 3, 1, 1, 0, 3, 2, 0, 100, 3, 0),
> -	APLL_FREQ(700,  0, 2, 4, 0, 3, 1, 1, 0, 3, 2, 0, 175, 3, 1),
> -	APLL_FREQ(600,  0, 2, 4, 0, 3, 1, 1, 0, 3, 2, 0, 200, 4, 1),
> -	APLL_FREQ(500,  0, 2, 4, 0, 3, 1, 1, 0, 3, 2, 0, 125, 3, 1),
> -	APLL_FREQ(400,  0, 2, 4, 0, 3, 1, 1, 0, 3, 2, 0, 100, 3, 1),
> -	APLL_FREQ(300,  0, 2, 4, 0, 2, 1, 1, 0, 3, 2, 0, 200, 4, 2),
> -	APLL_FREQ(200,  0, 1, 3, 0, 1, 1, 1, 0, 3, 2, 0, 100, 3, 2),
> -};
> -
> -static struct apll_freq apll_freq_4412[] = {
> -	/*
> -	 * values:
> -	 * freq
> -	 * clock divider for CORE, COREM0, COREM1, PERIPH, ATB,
> PCLK_DBG, APLL, CORE2
> -	 * clock divider for COPY, HPM, CORES
> -	 * PLL M, P, S
> -	 */
> -	APLL_FREQ(1500, 0, 3, 7, 0, 6, 1, 2, 0, 6, 0, 7, 250, 4, 0),
> -	APLL_FREQ(1400, 0, 3, 7, 0, 6, 1, 2, 0, 6, 0, 6, 175, 3, 0),
> -	APLL_FREQ(1300, 0, 3, 7, 0, 5, 1, 2, 0, 5, 0, 6, 325, 6, 0),
> -	APLL_FREQ(1200, 0, 3, 7, 0, 5, 1, 2, 0, 5, 0, 5, 200, 4, 0),
> -	APLL_FREQ(1100, 0, 3, 6, 0, 4, 1, 2, 0, 4, 0, 5, 275, 6, 0),
> -	APLL_FREQ(1000, 0, 2, 5, 0, 4, 1, 1, 0, 4, 0, 4, 125, 3, 0),
> -	APLL_FREQ(900,  0, 2, 5, 0, 3, 1, 1, 0, 3, 0, 4, 150, 4, 0),
> -	APLL_FREQ(800,  0, 2, 5, 0, 3, 1, 1, 0, 3, 0, 3, 100, 3, 0),
> -	APLL_FREQ(700,  0, 2, 4, 0, 3, 1, 1, 0, 3, 0, 3, 175, 3, 1),
> -	APLL_FREQ(600,  0, 2, 4, 0, 3, 1, 1, 0, 3, 0, 2, 200, 4, 1),
> -	APLL_FREQ(500,  0, 2, 4, 0, 3, 1, 1, 0, 3, 0, 2, 125, 3, 1),
> -	APLL_FREQ(400,  0, 2, 4, 0, 3, 1, 1, 0, 3, 0, 1, 100, 3, 1),
> -	APLL_FREQ(300,  0, 2, 4, 0, 2, 1, 1, 0, 3, 0, 1, 200, 4, 2),
> -	APLL_FREQ(200,  0, 1, 3, 0, 1, 1, 1, 0, 3, 0, 0, 100, 3, 2),
> -};
> -
> -static void exynos4x12_set_clkdiv(unsigned int div_index)
> -{
> -	unsigned int tmp;
> -	unsigned int stat_cpu1;
> -
> -	/* Change Divider - CPU0 */
> -
> -	tmp = apll_freq_4x12[div_index].clk_div_cpu0;
> -
> -	__raw_writel(tmp, EXYNOS4_CLKDIV_CPU);
> -
> -	while (__raw_readl(EXYNOS4_CLKDIV_STATCPU) & 0x11111111)
> -		cpu_relax();
> -
> -	/* Change Divider - CPU1 */
> -	tmp = apll_freq_4x12[div_index].clk_div_cpu1;
> -
> -	__raw_writel(tmp, EXYNOS4_CLKDIV_CPU1);
> -	if (soc_is_exynos4212())
> -		stat_cpu1 = 0x11;
> -	else
> -		stat_cpu1 = 0x111;
> -
> -	while (__raw_readl(EXYNOS4_CLKDIV_STATCPU1) & stat_cpu1)
> -		cpu_relax();
> -}
> -
> -static void exynos4x12_set_apll(unsigned int index)
> -{
> -	unsigned int tmp, freq = apll_freq_4x12[index].freq;
> -
> -	/* MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */
> -	clk_set_parent(moutcore, mout_mpll);
> -
> -	do {
> -		cpu_relax();
> -		tmp = (__raw_readl(EXYNOS4_CLKMUX_STATCPU)
> -			>> EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT);
> -		tmp &= 0x7;
> -	} while (tmp != 0x2);
> -
> -	clk_set_rate(mout_apll, freq * 1000);
> -
> -	/* MUX_CORE_SEL = APLL */
> -	clk_set_parent(moutcore, mout_apll);
> -
> -	do {
> -		cpu_relax();
> -		tmp = __raw_readl(EXYNOS4_CLKMUX_STATCPU);
> -		tmp &= EXYNOS4_CLKMUX_STATCPU_MUXCORE_MASK;
> -	} while (tmp != (0x1 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT));
> -}
> -
> -static void exynos4x12_set_frequency(unsigned int old_index,
> -				  unsigned int new_index)
> -{
> -	if (old_index > new_index) {
> -		exynos4x12_set_clkdiv(new_index);
> -		exynos4x12_set_apll(new_index);
> -	} else if (old_index < new_index) {
> -		exynos4x12_set_apll(new_index);
> -		exynos4x12_set_clkdiv(new_index);
> -	}
> -}
> -
> -int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
> -{
> -	unsigned long rate;
> -
> -	cpu_clk = clk_get(NULL, "armclk");
> -	if (IS_ERR(cpu_clk))
> -		return PTR_ERR(cpu_clk);
> -
> -	moutcore = clk_get(NULL, "moutcore");
> -	if (IS_ERR(moutcore))
> -		goto err_moutcore;
> -
> -	mout_mpll = clk_get(NULL, "mout_mpll");
> -	if (IS_ERR(mout_mpll))
> -		goto err_mout_mpll;
> -
> -	rate = clk_get_rate(mout_mpll) / 1000;
> -
> -	mout_apll = clk_get(NULL, "mout_apll");
> -	if (IS_ERR(mout_apll))
> -		goto err_mout_apll;
> -
> -	if (soc_is_exynos4212())
> -		apll_freq_4x12 = apll_freq_4212;
> -	else
> -		apll_freq_4x12 = apll_freq_4412;
> -
> -	info->mpll_freq_khz = rate;
> -	/* 800Mhz */
> -	info->pll_safe_idx = L7;
> -	info->cpu_clk = cpu_clk;
> -	info->volt_table = exynos4x12_volt_table;
> -	info->freq_table = exynos4x12_freq_table;
> -	info->set_freq = exynos4x12_set_frequency;
> -
> -	return 0;
> -
> -err_mout_apll:
> -	clk_put(mout_mpll);
> -err_mout_mpll:
> -	clk_put(moutcore);
> -err_moutcore:
> -	clk_put(cpu_clk);
> -
> -	pr_debug("%s: failed initialization\n", __func__);
> -	return -EINVAL;
> -}
> diff --git a/drivers/cpufreq/exynos5250-cpufreq.c
> b/drivers/cpufreq/exynos5250-cpufreq.c deleted file mode 100644
> index 5f90b82..0000000
> --- a/drivers/cpufreq/exynos5250-cpufreq.c
> +++ /dev/null
> @@ -1,183 +0,0 @@
> -/*
> - * Copyright (c) 2010-20122Samsung Electronics Co., Ltd.
> - *		http://www.samsung.com
> - *
> - * EXYNOS5250 - CPU frequency scaling support
> - *
> - * This program is free software; you can redistribute it and/or
> modify
> - * it under the terms of the GNU General Public License version 2 as
> - * published by the Free Software Foundation.
> -*/
> -
> -#include <linux/module.h>
> -#include <linux/kernel.h>
> -#include <linux/err.h>
> -#include <linux/clk.h>
> -#include <linux/io.h>
> -#include <linux/slab.h>
> -#include <linux/cpufreq.h>
> -
> -#include <mach/map.h>
> -
> -#include "exynos-cpufreq.h"
> -
> -static struct clk *cpu_clk;
> -static struct clk *moutcore;
> -static struct clk *mout_mpll;
> -static struct clk *mout_apll;
> -
> -static unsigned int exynos5250_volt_table[] = {
> -	1300000, 1250000, 1225000, 1200000, 1150000,
> -	1125000, 1100000, 1075000, 1050000, 1025000,
> -	1012500, 1000000,  975000,  950000,  937500,
> -	925000
> -};
> -
> -static struct cpufreq_frequency_table exynos5250_freq_table[] = {
> -	{L0, 1700 * 1000},
> -	{L1, 1600 * 1000},
> -	{L2, 1500 * 1000},
> -	{L3, 1400 * 1000},
> -	{L4, 1300 * 1000},
> -	{L5, 1200 * 1000},
> -	{L6, 1100 * 1000},
> -	{L7, 1000 * 1000},
> -	{L8,  900 * 1000},
> -	{L9,  800 * 1000},
> -	{L10, 700 * 1000},
> -	{L11, 600 * 1000},
> -	{L12, 500 * 1000},
> -	{L13, 400 * 1000},
> -	{L14, 300 * 1000},
> -	{L15, 200 * 1000},
> -	{0, CPUFREQ_TABLE_END},
> -};
> -
> -static struct apll_freq apll_freq_5250[] = {
> -	/*
> -	 * values:
> -	 * freq
> -	 * clock divider for ARM, CPUD, ACP, PERIPH, ATB, PCLK_DBG,
> APLL, ARM2
> -	 * clock divider for COPY, HPM, RESERVED
> -	 * PLL M, P, S
> -	 */
> -	APLL_FREQ(1700, 0, 3, 7, 7, 7, 3, 5, 0, 0, 2, 0, 425, 6, 0),
> -	APLL_FREQ(1600, 0, 3, 7, 7, 7, 1, 4, 0, 0, 2, 0, 200, 3, 0),
> -	APLL_FREQ(1500, 0, 2, 7, 7, 7, 1, 4, 0, 0, 2, 0, 250, 4, 0),
> -	APLL_FREQ(1400, 0, 2, 7, 7, 6, 1, 4, 0, 0, 2, 0, 175, 3, 0),
> -	APLL_FREQ(1300, 0, 2, 7, 7, 6, 1, 3, 0, 0, 2, 0, 325, 6, 0),
> -	APLL_FREQ(1200, 0, 2, 7, 7, 5, 1, 3, 0, 0, 2, 0, 200, 4, 0),
> -	APLL_FREQ(1100, 0, 3, 7, 7, 5, 1, 3, 0, 0, 2, 0, 275, 6, 0),
> -	APLL_FREQ(1000, 0, 1, 7, 7, 4, 1, 2, 0, 0, 2, 0, 125, 3, 0),
> -	APLL_FREQ(900,  0, 1, 7, 7, 4, 1, 2, 0, 0, 2, 0, 150, 4, 0),
> -	APLL_FREQ(800,  0, 1, 7, 7, 4, 1, 2, 0, 0, 2, 0, 100, 3, 0),
> -	APLL_FREQ(700,  0, 1, 7, 7, 3, 1, 1, 0, 0, 2, 0, 175, 3, 1),
> -	APLL_FREQ(600,  0, 1, 7, 7, 3, 1, 1, 0, 0, 2, 0, 200, 4, 1),
> -	APLL_FREQ(500,  0, 1, 7, 7, 2, 1, 1, 0, 0, 2, 0, 125, 3, 1),
> -	APLL_FREQ(400,  0, 1, 7, 7, 2, 1, 1, 0, 0, 2, 0, 100, 3, 1),
> -	APLL_FREQ(300,  0, 1, 7, 7, 1, 1, 1, 0, 0, 2, 0, 200, 4, 2),
> -	APLL_FREQ(200,  0, 1, 7, 7, 1, 1, 1, 0, 0, 2, 0, 100, 3, 2),
> -};
> -
> -static void set_clkdiv(unsigned int div_index)
> -{
> -	unsigned int tmp;
> -
> -	/* Change Divider - CPU0 */
> -
> -	tmp = apll_freq_5250[div_index].clk_div_cpu0;
> -
> -	__raw_writel(tmp, EXYNOS5_CLKDIV_CPU0);
> -
> -	while (__raw_readl(EXYNOS5_CLKDIV_STATCPU0) & 0x11111111)
> -		cpu_relax();
> -
> -	/* Change Divider - CPU1 */
> -	tmp = apll_freq_5250[div_index].clk_div_cpu1;
> -
> -	__raw_writel(tmp, EXYNOS5_CLKDIV_CPU1);
> -
> -	while (__raw_readl(EXYNOS5_CLKDIV_STATCPU1) & 0x11)
> -		cpu_relax();
> -}
> -
> -static void set_apll(unsigned int index)
> -{
> -	unsigned int tmp;
> -	unsigned int freq = apll_freq_5250[index].freq;
> -
> -	/* MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */
> -	clk_set_parent(moutcore, mout_mpll);
> -
> -	do {
> -		cpu_relax();
> -		tmp = (__raw_readl(EXYNOS5_CLKMUX_STATCPU) >> 16);
> -		tmp &= 0x7;
> -	} while (tmp != 0x2);
> -
> -	clk_set_rate(mout_apll, freq * 1000);
> -
> -	/* MUX_CORE_SEL = APLL */
> -	clk_set_parent(moutcore, mout_apll);
> -
> -	do {
> -		cpu_relax();
> -		tmp = __raw_readl(EXYNOS5_CLKMUX_STATCPU);
> -		tmp &= (0x7 << 16);
> -	} while (tmp != (0x1 << 16));
> -}
> -
> -static void exynos5250_set_frequency(unsigned int old_index,
> -				  unsigned int new_index)
> -{
> -	if (old_index > new_index) {
> -		set_clkdiv(new_index);
> -		set_apll(new_index);
> -	} else if (old_index < new_index) {
> -		set_apll(new_index);
> -		set_clkdiv(new_index);
> -	}
> -}
> -
> -int exynos5250_cpufreq_init(struct exynos_dvfs_info *info)
> -{
> -	unsigned long rate;
> -
> -	cpu_clk = clk_get(NULL, "armclk");
> -	if (IS_ERR(cpu_clk))
> -		return PTR_ERR(cpu_clk);
> -
> -	moutcore = clk_get(NULL, "mout_cpu");
> -	if (IS_ERR(moutcore))
> -		goto err_moutcore;
> -
> -	mout_mpll = clk_get(NULL, "mout_mpll");
> -	if (IS_ERR(mout_mpll))
> -		goto err_mout_mpll;
> -
> -	rate = clk_get_rate(mout_mpll) / 1000;
> -
> -	mout_apll = clk_get(NULL, "mout_apll");
> -	if (IS_ERR(mout_apll))
> -		goto err_mout_apll;
> -
> -	info->mpll_freq_khz = rate;
> -	/* 800Mhz */
> -	info->pll_safe_idx = L9;
> -	info->cpu_clk = cpu_clk;
> -	info->volt_table = exynos5250_volt_table;
> -	info->freq_table = exynos5250_freq_table;
> -	info->set_freq = exynos5250_set_frequency;
> -
> -	return 0;
> -
> -err_mout_apll:
> -	clk_put(mout_mpll);
> -err_mout_mpll:
> -	clk_put(moutcore);
> -err_moutcore:
> -	clk_put(cpu_clk);
> -
> -	pr_err("%s: failed initialization\n", __func__);
> -	return -EINVAL;
> -}



-- 
Best regards,

Lukasz Majewski

Samsung R&D Institute Poland (SRPOL) | Linux Platform Group

^ permalink raw reply

* [PATCH 06/20] ARM64 / ACPI: Introduce some PCI functions when PCI is enabled
From: Hanjun Guo @ 2014-01-20  8:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201401171504.24525.arnd@arndb.de>

On 2014-1-17 22:04, Arnd Bergmann wrote:
> On Friday 17 January 2014, Hanjun Guo wrote:
>> +++ b/arch/arm64/pci/Makefile
>> @@ -0,0 +1 @@
>> +obj-y                 += pci.o
>> diff --git a/arch/arm64/pci/pci.c b/arch/arm64/pci/pci.c
>> new file mode 100644
>> index 0000000..4e46790
>> --- /dev/null
>> +++ b/arch/arm64/pci/pci.c
>> @@ -0,0 +1,33 @@
>> +#include <linux/acpi.h>
>> +#include <linux/types.h>
>> +#include <linux/kernel.h>
>> +#include <linux/pci.h>
>> +
>> +/**
>> + * raw_pci_read - Platform-specific PCI config space access.
>> + *
>> + * Default empty implementation.  Replace with an architecture-specific setup
>> + * routine, if necessary.
>> + */
>> +int __weak raw_pci_read(unsigned int domain, unsigned int bus,
>> +			unsigned int devfn, int reg, int len, u32 *val)
>> +{
>> +	return -EINVAL;
>> +}
>> +
>> +int __weak raw_pci_write(unsigned int domain, unsigned int bus,
>> +			unsigned int devfn, int reg, int len, u32 val)
>> +{
>> +	return -EINVAL;
>> +}
> 
> I'd rather not see __weak functions here. Just provide them unconditionally
> so that we can add a proper implementation when needed. You could also
> define these as 'static inline' in a header file to keep them from consuming
> space in the object code.

Ok, I will remove __weak in next version.

> 
>> diff --git a/drivers/acpi/plat/arm-core.c b/drivers/acpi/plat/arm-core.c
>> index 3c8521d..1835b21 100644
>> --- a/drivers/acpi/plat/arm-core.c
>> +++ b/drivers/acpi/plat/arm-core.c
>> @@ -100,6 +100,25 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
>>  }
>>  EXPORT_SYMBOL_GPL(acpi_gsi_to_irq);
>>  
>> +int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
>> +{
>> +	return -1;
>> +}
>> +
>> +int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)
>> +{
>> +	/* TBD */
>> +	return -EINVAL;
>> +}
>> +EXPORT_SYMBOL(acpi_register_ioapic);
>> +
>> +int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base)
>> +{
>> +	/* TBD */
>> +	return -EINVAL;
>> +}
>> +EXPORT_SYMBOL(acpi_unregister_ioapic);
>> +
> 
> My feeling is that these are better handled in the ACPI code by not
> calling them on architectures that have no ISA or no IOAPIC support.
> 
> We have configuration symbols for both, so you don't have to make
> it depend on CONFIG_ARM64 or CONFIG_X86.

Do you mean introduce a stub function when there is no ISA support?

acpi_register_ioapic()/acpi_unregister_ioapic() will be used for IOAPIC
hotplug and GIC distributor is something like IOAPIC on x86, so I think
these two functions can be reserved for future use.

Thanks
Hanjun

^ permalink raw reply

* [PATCH] clk: export __clk_get_hw for re-use in others
From: SeongJae Park @ 2014-01-20  8:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAPtuhTikj38yKy-=uF7O+VFG_N4AWee23f9woemM318fM3V4VQ@mail.gmail.com>

On Mon, Jan 20, 2014 at 4:47 PM, Mike Turquette <mturquette@linaro.org> wrote:
> On Sun, Jan 19, 2014 at 9:37 AM, Greg KH <gregkh@linuxfoundation.org> wrote:
>> On Sun, Jan 19, 2014 at 02:55:07PM +0900, SeongJae Park wrote:
>>> Following build comes while modprobe process:
>>> > ERROR: "__clk_get_hw" [drivers/clk/clk-max77686.ko] undefined!
>>> > make[2]: *** [__modpost] Error 1
>>> > make[1]: *** [modules] Error 2
>>>
>>> Export the symbol to fix it and for other part's usecase.
>>>
>>> Signed-off-by: SeongJae Park <sj38.park@gmail.com>
>>> ---
>>>  drivers/clk/clk.c | 1 +
>>>  1 file changed, 1 insertion(+)
>>>
>>> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
>>> index 2b38dc9..3883fba 100644
>>> --- a/drivers/clk/clk.c
>>> +++ b/drivers/clk/clk.c
>>> @@ -575,6 +575,7 @@ struct clk_hw *__clk_get_hw(struct clk *clk)
>>>  {
>>>       return !clk ? NULL : clk->hw;
>>>  }
>>> +EXPORT_SYMBOL_GPL(__clk_get_hw);
>>
>> __ functions should usually only be for "internal" use, why does this
>> get exported to modules?  Why not just put it in a .h file?
>
> It was originally used only within the clock core but it is sensible
> for hardware-specific clock drivers to use this as well. I plan to
> audit all of the double-underscore functions in
> include/linux/clk-provider.h for 3.15.
>
> Regards,
> Mike
>
Thank you very much for answering about it, Mike.

I agree Greg's indication and think Mike's explanation is reasonable.

So, I think it would be better to just export the symbol now
because it would be easier for future functions renaming and
similar issues were solved in this way in past:
https://lkml.org/lkml/2013/4/15/50

Or, maybe I can change the client code of __clk_get_hw to not use the function.

What do you think would be better to fix this build error? Or, do you
have better idea?
I will respect your opinion.

Thanks and Regards.
SeongJae Park.

>>
>> greg k-h

^ permalink raw reply

* [PATCH] dma: Add Xilinx AXI Video Direct Memory Access Engine driver support
From: Srikanth Thokala @ 2014-01-20  8:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201401171713.08550.arnd@arndb.de>

Hi Arnd,

On Fri, Jan 17, 2014 at 9:43 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Thursday 16 January 2014, Srikanth Thokala wrote:
>> @@ -0,0 +1,71 @@
>> +Xilinx AXI VDMA engine, it does transfers between memory and video devices.
>> +It can be configured to have one channel or two channels. If configured
>> +as two channels, one is to transmit to the video device and another is
>> +to receive from the video device.
>> +
>> +Required properties:
>> +- compatible: Should be "xlnx,axi-vdma-1.00.a"
>> +- #dma-cells: Should be <1>, see "dmas" property below
>> +- reg: Should contain VDMA registers location and length.
>> +- interrupts: Should contain per channel VDMA interrupts.
>> +- compatible (child node): It should be either "xlnx,axi-vdma-mm2s-channel" or
>> +       "xlnx,axi-vdma-s2mm-channel". It depends on the hardware design and it
>> +       can also have both channels.
>> +- xlnx,device-id: Should contain device number in each channel. It should be
>> +       {0,1,2...so on} to the number of VDMA devices configured in hardware.
>> +- xlnx,num-fstores: Should be the number of framebuffers as configured in h/w.
>> +- xlnx,data-width: Should contain the stream data width, takes {32,64...so on}.
>> +- xlnx,flush-fsync: (Optional) Tells whether which channel to Flush on Fsync.
>> +       It takes following values:
>> +       {1}, flush both channels
>> +       {2}, flush mm2s channel
>> +       {3}, flush s2mm channel
>> +- xlnx,include-sg: (Optional) Tells whether configured for Scatter-mode in
>> +       the hardware.
>> +- xlnx,include-dre: (Optional) Tells whether hardware is configured for Data
>> +       Realignment Engine.
>> +- xlnx,genlock-mode: (Optional) Tells whether Genlock synchornisation is
>> +       enabled/disabled in hardware.
>
> The documentation doesn't seem to match the example, since you don't mention
> the fact that the channels have separate nodes here, or which properties
> are meant for the parent or the child node. Also, some of the "required"
> properties are absent in the example, which makes no sense.
>

I will fix this ambiguity in my v2.

> I also assume that some of the properties should just go away:
>
> * xlnx,device-id should be the argument in the handle from the slave device

We can have multiple instances of this VDMA IP configured in the FPGA and we
need a unique identifier for each VDMA device that is present in the FPGA.
This device-id dt parameter forms the filter mask for the slave devices. As an
example, this can be used to get a channel of specific VDMA device (assuming
multiple instances) using the API dma_request_channel().  Please note this
is an example of a slave device that doesnt have dt node.

> * data width should be a property of the slave driver that is configured
>   through dma_slave_config(), unless you can have dma engines that only
>   support certain a width.

Yes, this VDMA engine soft IP support only certain widths, which is
configurable during IP synthesis.

Srikanth

>
>         Arnd
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply

* [PATCH] dmaengine: sirf: Add device_slave_caps interface
From: Vinod Koul @ 2014-01-20  7:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140120074757.GI26823@intel.com>

On Mon, Jan 20, 2014 at 01:17:57PM +0530, Vinod Koul wrote:
> On Mon, Dec 23, 2013 at 08:19:21PM +0800, Barry Song wrote:
> > From: Rongjun Ying <rongjun.ying@csr.com>
> > 
> > this patch adds device_slave_caps() callback as SiRF SoC sound drivers
> > depend on it.
> 
> Applied, thanks

Btw you should send incremental patch for granurity reporting after the merge
window. Those changes are getting merged thru ASoC tree.

-- 
~Vinod

^ permalink raw reply

* [PATCH v4] dmaengine: sirf: enable generic dt binding for dma channels
From: Vinod Koul @ 2014-01-20  7:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1389190369-2012-1-git-send-email-21cnbao@gmail.com>

On Wed, Jan 08, 2014 at 10:12:49PM +0800, Barry Song wrote:
> From: Barry Song <Baohua.Song@csr.com>
> 
> move to support of_dma_request_slave_channel() and dma_request_slave_channel.
> we add a xlate() to let dma clients be able to find right dma_chan by generic
> "dmas" properties in dts.
> 
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Signed-off-by: Barry Song <Baohua.Song@csr.com>
Look okay, need an ACk from DT maintainers before I can apply...

--
~Vinod
> ---
>  -v4: clear dt-binding document according to Mark's feedback
> 
>  .../devicetree/bindings/dma/sirfsoc-dma.txt        |   43 ++++++++++++++++++++
>  arch/arm/boot/dts/atlas6.dtsi                      |    2 +
>  arch/arm/boot/dts/prima2.dtsi                      |    2 +
>  drivers/dma/sirf-dma.c                             |   23 ++++++++++
>  4 files changed, 70 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/dma/sirfsoc-dma.txt
> 
> diff --git a/Documentation/devicetree/bindings/dma/sirfsoc-dma.txt b/Documentation/devicetree/bindings/dma/sirfsoc-dma.txt
> new file mode 100644
> index 0000000..ecbc96a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/dma/sirfsoc-dma.txt
> @@ -0,0 +1,43 @@
> +* CSR SiRFSoC DMA controller
> +
> +See dma.txt first
> +
> +Required properties:
> +- compatible: Should be "sirf,prima2-dmac" or "sirf,marco-dmac"
> +- reg: Should contain DMA registers location and length.
> +- interrupts: Should contain one interrupt shared by all channel
> +- #dma-cells: must be <1>. used to represent the number of integer
> +    cells in the dmas property of client device.
> +- clocks: clock required
> +
> +Example:
> +
> +Controller:
> +dmac0: dma-controller at b00b0000 {
> +	compatible = "sirf,prima2-dmac";
> +	reg = <0xb00b0000 0x10000>;
> +	interrupts = <12>;
> +	clocks = <&clks 24>;
> +	#dma-cells = <1>;
> +};
> +
> +
> +Client:
> +Fill the specific dma request line in dmas. In the below example, spi0 read
> +channel request line is 9 of the 2nd dma controller, while write channel uses
> +4 of the 2nd dma controller; spi1 read channel request line is 12 of the 1st
> +dma controller, while write channel uses 13 of the 1st dma controller:
> +
> +spi0: spi at b00d0000 {
> +	compatible = "sirf,prima2-spi";
> +	dmas = <&dmac1 9>,
> +		<&dmac1 4>;
> +	dma-names = "rx", "tx";
> +};
> +
> +spi1: spi at b0170000 {
> +	compatible = "sirf,prima2-spi";
> +	dmas = <&dmac0 12>,
> +		<&dmac0 13>;
> +	dma-names = "rx", "tx";
> +};
> diff --git a/arch/arm/boot/dts/atlas6.dtsi b/arch/arm/boot/dts/atlas6.dtsi
> index b63cfef..4f41f0a 100644
> --- a/arch/arm/boot/dts/atlas6.dtsi
> +++ b/arch/arm/boot/dts/atlas6.dtsi
> @@ -260,6 +260,7 @@
>  				reg = <0xb00b0000 0x10000>;
>  				interrupts = <12>;
>  				clocks = <&clks 24>;
> +				#dma-cells = <1>;
>  			};
>  
>  			dmac1: dma-controller at b0160000 {
> @@ -268,6 +269,7 @@
>  				reg = <0xb0160000 0x10000>;
>  				interrupts = <13>;
>  				clocks = <&clks 25>;
> +				#dma-cells = <1>;
>  			};
>  
>  			vip at b00C0000 {
> diff --git a/arch/arm/boot/dts/prima2.dtsi b/arch/arm/boot/dts/prima2.dtsi
> index b292a5c..19e4e22 100644
> --- a/arch/arm/boot/dts/prima2.dtsi
> +++ b/arch/arm/boot/dts/prima2.dtsi
> @@ -277,6 +277,7 @@
>  				reg = <0xb00b0000 0x10000>;
>  				interrupts = <12>;
>  				clocks = <&clks 24>;
> +				#dma-cells = <1>;
>  			};
>  
>  			dmac1: dma-controller at b0160000 {
> @@ -285,6 +286,7 @@
>  				reg = <0xb0160000 0x10000>;
>  				interrupts = <13>;
>  				clocks = <&clks 25>;
> +				#dma-cells = <1>;
>  			};
>  
>  			vip at b00C0000 {
> diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
> index 6aec3ad..8b74c0d 100644
> --- a/drivers/dma/sirf-dma.c
> +++ b/drivers/dma/sirf-dma.c
> @@ -18,6 +18,7 @@
>  #include <linux/of_device.h>
>  #include <linux/of_platform.h>
>  #include <linux/clk.h>
> +#include <linux/of_dma.h>
>  #include <linux/sirfsoc_dma.h>
>  
>  #include "dmaengine.h"
> @@ -640,6 +641,18 @@ bool sirfsoc_dma_filter_id(struct dma_chan *chan, void *chan_id)
>  }
>  EXPORT_SYMBOL(sirfsoc_dma_filter_id);
>  
> +static struct dma_chan *of_dma_sirfsoc_xlate(struct of_phandle_args *dma_spec,
> +	struct of_dma *ofdma)
> +{
> +	struct sirfsoc_dma *sdma = ofdma->of_dma_data;
> +	unsigned int request = dma_spec->args[0];
> +
> +	if (request > SIRFSOC_DMA_CHANNELS)
> +		return NULL;
> +
> +	return dma_get_slave_channel(&sdma->channels[request].chan);
> +}
> +
>  static int sirfsoc_dma_probe(struct platform_device *op)
>  {
>  	struct device_node *dn = op->dev.of_node;
> @@ -744,11 +757,20 @@ static int sirfsoc_dma_probe(struct platform_device *op)
>  	if (ret)
>  		goto free_irq;
>  
> +	/* Device-tree DMA controller registration */
> +	ret = of_dma_controller_register(dn, of_dma_sirfsoc_xlate, sdma);
> +	if (ret) {
> +		dev_err(dev, "failed to register DMA controller\n");
> +		goto unreg_dma_dev;
> +	}
> +
>  	pm_runtime_enable(&op->dev);
>  	dev_info(dev, "initialized SIRFSOC DMAC driver\n");
>  
>  	return 0;
>  
> +unreg_dma_dev:
> +	dma_async_device_unregister(dma);
>  free_irq:
>  	free_irq(sdma->irq, sdma);
>  irq_dispose:
> @@ -761,6 +783,7 @@ static int sirfsoc_dma_remove(struct platform_device *op)
>  	struct device *dev = &op->dev;
>  	struct sirfsoc_dma *sdma = dev_get_drvdata(dev);
>  
> +	of_dma_controller_free(op->dev.of_node);
>  	dma_async_device_unregister(&sdma->dma);
>  	free_irq(sdma->irq, sdma);
>  	irq_dispose_mapping(sdma->irq);
> -- 
> 1.7.5.4
> 

-- 

^ permalink raw reply

* [PATCH v2 6/7] ARM: Exynos: switch to using generic cpufreq-cpu0 driver
From: Lukasz Majewski @ 2014-01-20  7:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390047057-2239-7-git-send-email-thomas.ab@samsung.com>

Hi Thomas,

> From: Thomas Abraham <thomas.ab@samsung.com>
> 
> Remove the platform device instantiation for Exynos specific cpufreq
> driver and add the platform device for cpufreq-cpu0 driver.
> 
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
> ---
>  arch/arm/mach-exynos/common.c          |    5 -----
>  arch/arm/mach-exynos/common.h          |    1 -
>  arch/arm/mach-exynos/mach-exynos4-dt.c |    2 +-
>  arch/arm/mach-exynos/mach-exynos5-dt.c |    2 +-
>  4 files changed, 2 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm/mach-exynos/common.c
> b/arch/arm/mach-exynos/common.c index f18be40..72ae5d3 100644
> --- a/arch/arm/mach-exynos/common.c
> +++ b/arch/arm/mach-exynos/common.c
> @@ -303,11 +303,6 @@ void __init exynos_cpuidle_init(void)
>  	platform_device_register(&exynos_cpuidle);
>  }
>  
> -void __init exynos_cpufreq_init(void)
> -{
> -	platform_device_register_simple("exynos-cpufreq", -1, NULL,
> 0); -}
> -
>  void __init exynos_init_late(void)
>  {
>  	if (of_machine_is_compatible("samsung,exynos5440"))
> diff --git a/arch/arm/mach-exynos/common.h
> b/arch/arm/mach-exynos/common.h index f76967b..0c31b34 100644
> --- a/arch/arm/mach-exynos/common.h
> +++ b/arch/arm/mach-exynos/common.h
> @@ -22,7 +22,6 @@ void exynos_init_io(void);
>  void exynos4_restart(enum reboot_mode mode, const char *cmd);
>  void exynos5_restart(enum reboot_mode mode, const char *cmd);
>  void exynos_cpuidle_init(void);
> -void exynos_cpufreq_init(void);
>  void exynos_init_late(void);
>  
>  void exynos_firmware_init(void);
> diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c
> b/arch/arm/mach-exynos/mach-exynos4-dt.c index d3e54b7..9a25320 100644
> --- a/arch/arm/mach-exynos/mach-exynos4-dt.c
> +++ b/arch/arm/mach-exynos/mach-exynos4-dt.c
> @@ -22,8 +22,8 @@
>  static void __init exynos4_dt_machine_init(void)
>  {
>  	exynos_cpuidle_init();
> -	exynos_cpufreq_init();
>  
> +	platform_device_register_simple("cpufreq-cpu0", -1, NULL, 0);
>  	of_platform_populate(NULL, of_default_bus_match_table, NULL,
> NULL); }
>  
> diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c
> b/arch/arm/mach-exynos/mach-exynos5-dt.c index 37ea261..9dc3710 100644
> --- a/arch/arm/mach-exynos/mach-exynos5-dt.c
> +++ b/arch/arm/mach-exynos/mach-exynos5-dt.c
> @@ -44,8 +44,8 @@ static void __init exynos5_dt_machine_init(void)
>  	}
>  
>  	exynos_cpuidle_init();
> -	exynos_cpufreq_init();
>  
> +	platform_device_register_simple("cpufreq-cpu0", -1, NULL, 0);
>  	of_platform_populate(NULL, of_default_bus_match_table, NULL,
> NULL); }
>  

Reviewed-by: Lukasz Majewski <l.majewski@samsung.com>

-- 
Best regards,

Lukasz Majewski

Samsung R&D Institute Poland (SRPOL) | Linux Platform Group

^ permalink raw reply

* [PATCH] dmaengine: sirf: Add device_slave_caps interface
From: Vinod Koul @ 2014-01-20  7:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1387801161-3126-1-git-send-email-21cnbao@gmail.com>

On Mon, Dec 23, 2013 at 08:19:21PM +0800, Barry Song wrote:
> From: Rongjun Ying <rongjun.ying@csr.com>
> 
> this patch adds device_slave_caps() callback as SiRF SoC sound drivers
> depend on it.

Applied, thanks

--
~Vinod

^ permalink raw reply

* [PATCH v2 5/7] clk: exynos: use cpu-clock provider type to represent arm clock
From: Lukasz Majewski @ 2014-01-20  7:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390047057-2239-6-git-send-email-thomas.ab@samsung.com>

Hi Thomas,

> From: Thomas Abraham <thomas.ab@samsung.com>
> 
> With the addition of the new Samsung specific cpu-clock type, the
> arm clock can be represented as a cpu-clock type and the independent
> clock blocks that made up the arm clock can be removed.
> 
> Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
> ---
>  .../devicetree/bindings/clock/exynos5250-clock.txt |    1 +
>  drivers/clk/samsung/clk-exynos4.c                  |   11 +++++------
>  drivers/clk/samsung/clk-exynos5250.c               |    8 ++++----
>  include/dt-bindings/clock/exynos5250.h             |    1 +
>  4 files changed, 11 insertions(+), 10 deletions(-)
> 
> diff --git
> a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt
> b/Documentation/devicetree/bindings/clock/exynos5250-clock.txt index
> 99eae9c..acf867a 100644 ---
> a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt +++
> b/Documentation/devicetree/bindings/clock/exynos5250-clock.txt @@
> -38,6 +38,7 @@ clock which they consume. ---------------------------- 
>    fin_pll		1
> +  armclk		12
>  
>    [Clock Gate for Special Clocks]
>  
> diff --git a/drivers/clk/samsung/clk-exynos4.c
> b/drivers/clk/samsung/clk-exynos4.c index 010f071..efcf4a3 100644
> --- a/drivers/clk/samsung/clk-exynos4.c
> +++ b/drivers/clk/samsung/clk-exynos4.c
> @@ -437,8 +437,6 @@ static struct samsung_mux_clock
> exynos4x12_mux_clks[] __initdata = { 
>  /* list of divider clocks supported in all exynos4 soc's */
>  static struct samsung_div_clock exynos4_div_clks[] __initdata = {
> -	DIV(0, "div_core", "mout_core", DIV_CPU0, 0, 3),
> -	DIV(0, "div_core2", "div_core", DIV_CPU0, 28, 3),
>  	DIV(0, "div_fimc0", "mout_fimc0", DIV_CAM, 0, 4),
>  	DIV(0, "div_fimc1", "mout_fimc1", DIV_CAM, 4, 4),
>  	DIV(0, "div_fimc2", "mout_fimc2", DIV_CAM, 8, 4),
> @@ -484,8 +482,8 @@ static struct samsung_div_clock
> exynos4_div_clks[] __initdata = { DIV(0, "div_spi_pre2", "div_spi2",
> DIV_PERIL2, 8, 8), DIV(0, "div_audio1", "mout_audio1", DIV_PERIL4, 0,
> 4), DIV(0, "div_audio2", "mout_audio2", DIV_PERIL4, 16, 4),
> -	DIV(CLK_ARM_CLK, "arm_clk", "div_core2", DIV_CPU0, 28, 3),
> -	DIV(CLK_SCLK_APLL, "sclk_apll", "mout_apll", DIV_CPU0, 24,
> 3),
> +	DIV_F(CLK_SCLK_APLL, "sclk_apll", "mout_apll", DIV_CPU0, 24,
> 3,
> +			CLK_GET_RATE_NOCACHE, 0),
>  	DIV_F(0, "div_mipi_pre0", "div_mipi0", DIV_LCD0, 20, 4,
>  			CLK_SET_RATE_PARENT, 0),
>  	DIV_F(0, "div_mmc_pre0", "div_mmc0", DIV_FSYS1, 8, 8,
> @@ -870,7 +868,6 @@ static struct samsung_gate_clock
> exynos4x12_gate_clks[] __initdata = { 
>  static struct samsung_clock_alias exynos4_aliases[] __initdata = {
>  	ALIAS(CLK_MOUT_CORE, NULL, "moutcore"),
> -	ALIAS(CLK_ARM_CLK, NULL, "armclk"),
>  	ALIAS(CLK_SCLK_APLL, NULL, "mout_apll"),
>  };
>  
> @@ -1125,12 +1122,14 @@ static void __init exynos4_clk_init(struct
> device_node *np, samsung_clk_register_alias(exynos4_aliases,
>  			ARRAY_SIZE(exynos4_aliases));
>  
> +	samsung_register_arm_clock(np, CLK_ARM_CLK, "mout_apll",
> reg_base); +

I've got some doubts about allowing only the "mout_apll" clock to be the
only parent for armclk Samsung clock.

For the Exynos4412 it is also valid to have SCLK_MPLL_USER_C [*] as a
parent for this clock.

The problem is that you are reparenting the armclk to [*] with the
register modification - no CCF involved.

I just would like to know if this is yours design decision or
something, that we have overlooked in the v1 of this patch series.

>  	pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n"
>  		"\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk =
> %ld\n", exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12",
>  		_get_rate("sclk_apll"),
> _get_rate("sclk_mpll"), _get_rate("sclk_epll"),
> _get_rate("sclk_vpll"),
> -		_get_rate("arm_clk"));
> +		_get_rate("armclk"));
>  }
>  
>  
> diff --git a/drivers/clk/samsung/clk-exynos5250.c
> b/drivers/clk/samsung/clk-exynos5250.c index ff4beeb..487be36 100644
> --- a/drivers/clk/samsung/clk-exynos5250.c
> +++ b/drivers/clk/samsung/clk-exynos5250.c
> @@ -298,9 +298,8 @@ static struct samsung_div_clock
> exynos5250_div_clks[] __initdata = { /*
>  	 * CMU_CPU
>  	 */
> -	DIV(0, "div_arm", "mout_cpu", DIV_CPU0, 0, 3),
> -	DIV(0, "div_apll", "mout_apll", DIV_CPU0, 24, 3),
> -	DIV_A(0, "div_arm2", "div_arm", DIV_CPU0, 28, 3, "armclk"),
> +	DIV_F(0, "div_apll", "mout_apll", DIV_CPU0, 24, 3,
> +			CLK_GET_RATE_NOCACHE, 0),
>  
>  	/*
>  	 * CMU_TOP
> @@ -684,8 +683,9 @@ static void __init exynos5250_clk_init(struct
> device_node *np) ARRAY_SIZE(exynos5250_div_clks));
>  	samsung_clk_register_gate(exynos5250_gate_clks,
>  			ARRAY_SIZE(exynos5250_gate_clks));
> +	samsung_register_arm_clock(np, CLK_ARM_CLK, "mout_apll",
> reg_base); 
>  	pr_info("Exynos5250: clock setup completed, armclk=%ld\n",
> -			_get_rate("div_arm2"));
> +			_get_rate("armclk"));
>  }
>  CLK_OF_DECLARE(exynos5250_clk, "samsung,exynos5250-clock",
> exynos5250_clk_init); diff --git
> a/include/dt-bindings/clock/exynos5250.h
> b/include/dt-bindings/clock/exynos5250.h index 922f2dc..59a10fb
> 100644 --- a/include/dt-bindings/clock/exynos5250.h +++
> b/include/dt-bindings/clock/exynos5250.h @@ -21,6 +21,7 @@
>  #define CLK_FOUT_CPLL		6
>  #define CLK_FOUT_EPLL		7
>  #define CLK_FOUT_VPLL		8
> +#define CLK_ARM_CLK		12
>  
>  /* gate for special clocks (sclk) */
>  #define CLK_SCLK_CAM_BAYER	128



-- 
Best regards,

Lukasz Majewski

Samsung R&D Institute Poland (SRPOL) | Linux Platform Group

^ permalink raw reply

* [PATCH] clk: export __clk_get_hw for re-use in others
From: Mike Turquette @ 2014-01-20  7:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140119173712.GA26481@kroah.com>

On Sun, Jan 19, 2014 at 9:37 AM, Greg KH <gregkh@linuxfoundation.org> wrote:
> On Sun, Jan 19, 2014 at 02:55:07PM +0900, SeongJae Park wrote:
>> Following build comes while modprobe process:
>> > ERROR: "__clk_get_hw" [drivers/clk/clk-max77686.ko] undefined!
>> > make[2]: *** [__modpost] Error 1
>> > make[1]: *** [modules] Error 2
>>
>> Export the symbol to fix it and for other part's usecase.
>>
>> Signed-off-by: SeongJae Park <sj38.park@gmail.com>
>> ---
>>  drivers/clk/clk.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
>> index 2b38dc9..3883fba 100644
>> --- a/drivers/clk/clk.c
>> +++ b/drivers/clk/clk.c
>> @@ -575,6 +575,7 @@ struct clk_hw *__clk_get_hw(struct clk *clk)
>>  {
>>       return !clk ? NULL : clk->hw;
>>  }
>> +EXPORT_SYMBOL_GPL(__clk_get_hw);
>
> __ functions should usually only be for "internal" use, why does this
> get exported to modules?  Why not just put it in a .h file?

It was originally used only within the clock core but it is sensible
for hardware-specific clock drivers to use this as well. I plan to
audit all of the double-underscore functions in
include/linux/clk-provider.h for 3.15.

Regards,
Mike

>
> greg k-h

^ permalink raw reply

* [PATCH 0/3] ARM: OMAP: clk-next-omap emergency fixes
From: Mike Turquette @ 2014-01-20  7:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140118175020.GF7235@atomide.com>

On Sat, Jan 18, 2014 at 9:50 AM, Tony Lindgren <tony@atomide.com> wrote:
> * Mike Turquette <mturquette@linaro.org> [140117 13:39]:
>> Quoting Tero Kristo (2014-01-17 12:25:37)
>> > Hi,
>> >
>> > Quick emergency band-aid for the build breakages introduced in clk-next
>> > by Mike. I didn't have time to test this out (Nishanth will provide some
>> > logs) and I will leave the decision whether/how to use these patches or not
>> > to Tony + Mike.
>> >
>> > I also pushed a test branch based on top of clk-next here:
>> > tree: https://github.com/t-kristo/linux-pm.git
>> > branch: clk-next-omap-fixes
>>
>> Thanks Tero. I force updated the clk tree with the right branch, so
>> these should not be necessary now.
>
> Great, and just for reference if I did not do it yet for these:
>
> Acked-by: Tony Lindgren <tony@atomide.com>

I applied your Ack to entire series (these fixes, clock drivers and
arch/arm changes).

Regards,
Mike

^ permalink raw reply

* [PATCH] dma: imx-sdma: remove firmare not found warning
From: Vinod Koul @ 2014-01-20  7:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1389887186-6146-1-git-send-email-s.hauer@pengutronix.de>

On Thu, Jan 16, 2014 at 04:46:26PM +0100, Sascha Hauer wrote:
> When a firmware cannot be found for the SDMA engine then we can
> continue with the inernal ROM firmware.
typo		    ^^^^^^^

> The meaning of this message is frequently asked for and the usual
> answer is that this message is of no relevance, so just make it
> dev_dbg() and do not alienate the users anymore.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> Cc: Vinod Koul <vinod.koul@intel.com>
> ---
>  drivers/dma/imx-sdma.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
> index c75679d..fe57a42 100644
> --- a/drivers/dma/imx-sdma.c
> +++ b/drivers/dma/imx-sdma.c
> @@ -1259,7 +1259,10 @@ static void sdma_load_firmware(const struct firmware *fw, void *context)
>  	unsigned short *ram_code;
>  
>  	if (!fw) {
> -		dev_err(sdma->dev, "firmware not found\n");
> +		dev_dbg(sdma->dev, "firmware not found\n");
Shouldn't this be dev_info and would amke sense, external firmware not found
using internal one??

--
~Vinod
> +		/*
> +		 * In this case we just use the ROM firmware.
> +		 */
>  		return;
>  	}
>  
> -- 
> 1.8.5.2
> 

-- 

^ permalink raw reply

* [PATCHv10 2/2] dma: Add Freescale eDMA engine driver support
From: Vinod Koul @ 2014-01-20  7:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1389938684-29467-3-git-send-email-b35083@freescale.com>

On Fri, Jan 17, 2014 at 02:04:44PM +0800, Jingchang Lu wrote:
> Add Freescale enhanced direct memory(eDMA) controller support.
> This module can be found on Vybrid and LS-1 SoCs.
> 
> Signed-off-by: Alison Wang <b18965@freescale.com>
> Signed-off-by: Jingchang Lu <b35083@freescale.com>
> Acked-by: Arnd Bergmann <arnd@arndb.de>
> ---

> +struct fsl_edma_sw_tcd {
> +	dma_addr_t			ptcd;
> +	struct fsl_edma_hw_tcd		*vtcd;
> +};
> +
> +struct fsl_edma_slave_config {
> +	enum dma_transfer_direction	dir;
> +	enum dma_slave_buswidth		addr_width;
> +	u32				dev_addr;
u32 for device address doesnt look right, we should be using dma_addr_t?
> +	u32				burst;
> +	u32				attr;
Looking at this, all fields expect attr are in dma_slave_config! So why do we
need these here and what does the attr mean?

> +static int fsl_edma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
> +		unsigned long arg)
> +{
> +	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> +	struct dma_slave_config *cfg = (void *)arg;
> +	unsigned long flags;
> +	LIST_HEAD(head);
> +
> +	switch (cmd) {
> +	case DMA_TERMINATE_ALL:
> +		spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
> +		fsl_edma_disable_request(fsl_chan);
> +		fsl_chan->edesc = NULL;
> +		vchan_get_all_descriptors(&fsl_chan->vchan, &head);
> +		spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
> +		vchan_dma_desc_free_list(&fsl_chan->vchan, &head);
> +		return 0;
well what happens to the current ongoing transactions, i don't see those getting
terminated?

> +
> +	case DMA_SLAVE_CONFIG:
> +		fsl_chan->fsc.dir = cfg->direction;
> +		if (cfg->direction == DMA_DEV_TO_MEM) {
> +			fsl_chan->fsc.dev_addr = cfg->src_addr;
> +			fsl_chan->fsc.addr_width = cfg->src_addr_width;
> +			fsl_chan->fsc.burst = cfg->src_maxburst;
> +			fsl_chan->fsc.attr = fsl_edma_get_tcd_attr(cfg->src_addr_width);
> +		} else if (cfg->direction == DMA_MEM_TO_DEV) {
> +			fsl_chan->fsc.dev_addr = cfg->dst_addr;
> +			fsl_chan->fsc.addr_width = cfg->dst_addr_width;
> +			fsl_chan->fsc.burst = cfg->dst_maxburst;
> +			fsl_chan->fsc.attr = fsl_edma_get_tcd_attr(cfg->dst_addr_width);
okay atrr is address width, why not save this standard struct instead?

> +		} else {
> +			return -EINVAL;
> +		}
> +		return 0;
> +
> +	case DMA_PAUSE:
> +		spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
> +		if (fsl_chan->edesc) {
> +			fsl_edma_disable_request(fsl_chan);
> +			fsl_chan->status = DMA_PAUSED;
> +		}
> +		spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
> +		return 0;
> +
> +	case DMA_RESUME:
> +		spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
> +		if (fsl_chan->edesc) {
> +			fsl_edma_enable_request(fsl_chan);
> +			fsl_chan->status = DMA_IN_PROGRESS;
> +		}
> +		spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
> +		return 0;
> +
> +	default:
> +		return -ENXIO;
> +	}
> +}
> +

> +static struct fsl_edma_desc *fsl_edma_alloc_desc(struct fsl_edma_chan *fsl_chan,
> +		int sg_len)
> +{
> +	struct fsl_edma_desc *fsl_desc;
> +	int i;
> +
> +	fsl_desc = kzalloc(sizeof(*fsl_desc) + sizeof(struct fsl_edma_sw_tcd) * sg_len,
> +				GFP_NOWAIT);
> +	if (!fsl_desc)
> +		return NULL;
> +
> +	fsl_desc->echan = fsl_chan;
> +	fsl_desc->n_tcds = sg_len;
> +	for (i = 0; i < sg_len; i++) {
> +		fsl_desc->tcd[i].vtcd = dma_pool_alloc(fsl_chan->tcd_pool,
> +					GFP_NOWAIT, &fsl_desc->tcd[i].ptcd);
> +		if (!fsl_desc->tcd[i].vtcd)
> +			goto err;
> +	}
> +	return fsl_desc;
> +
> +err:
> +	while (--i >= 0)
> +		dma_pool_free(fsl_chan->tcd_pool, fsl_desc->tcd[i].vtcd,
> +				fsl_desc->tcd[i].ptcd);
> +	kfree(fsl_desc);
> +	return NULL;
> +}
> +
> +static struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic(
> +		struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len,
> +		size_t period_len, enum dma_transfer_direction direction,
> +		unsigned long flags, void *context)
> +{
you may want to implement the capablities api subsequently for audio usage.

> +	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> +	struct fsl_edma_desc *fsl_desc;
> +	dma_addr_t dma_buf_next;
> +	int sg_len, i;
> +	u32 src_addr, dst_addr, last_sg, nbytes;
> +	u16 soff, doff, iter;
> +
> +	if (!is_slave_direction(fsl_chan->fsc.dir))
> +		return NULL;
> +
> +	sg_len = buf_len / period_len;
> +	fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len);
> +	if (!fsl_desc)
> +		return NULL;
> +	fsl_desc->iscyclic = true;
> +
> +	dma_buf_next = dma_addr;
> +	nbytes = fsl_chan->fsc.addr_width * fsl_chan->fsc.burst;
> +	iter = period_len / nbytes;
empty line here pls

> +	for (i = 0; i < sg_len; i++) {
> +		if (dma_buf_next >= dma_addr + buf_len)
> +			dma_buf_next = dma_addr;
> +
> +		/* get next sg's physical address */
> +		last_sg = fsl_desc->tcd[(i + 1) % sg_len].ptcd;
> +
> +		if (fsl_chan->fsc.dir == DMA_MEM_TO_DEV) {
> +			src_addr = dma_buf_next;
> +			dst_addr = fsl_chan->fsc.dev_addr;
> +			soff = fsl_chan->fsc.addr_width;
> +			doff = 0;
> +		} else {
> +			src_addr = fsl_chan->fsc.dev_addr;
> +			dst_addr = dma_buf_next;
> +			soff = 0;
> +			doff = fsl_chan->fsc.addr_width;
> +		}
> +
> +		fill_tcd_params(fsl_chan->edma, fsl_desc->tcd[i].vtcd, src_addr,
> +				dst_addr, fsl_chan->fsc.attr, soff, nbytes, 0,
> +				iter, iter, doff, last_sg, true, false, true);
> +		dma_buf_next += period_len;
> +	}
> +
> +	return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags);
> +}

-- 
~Vinod

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox