* [PATCHv2] Add GPIO driver for Allwinner SoCs
From: Maxime Ripard @ 2013-01-23 9:34 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
This patch adds support for the GPIOs for the Allwinner SoCs supported so
far.
It comes on top of my previous pinctrl patchset, and has been tested on a
A13-Olinuxino from Olimex.
Thanks,
Maxime
Changes from v1:
- Merged the gpio driver with the pinctrl one
- Now using gpiochip_add_pin_range instead of pinctrl_add_gpio_range
- Removed the hairy range registration function, and register 1pin ranges
instead
Maxime Ripard (1):
ARM: sunxi: gpio: Add Allwinner SoCs GPIO drivers
drivers/pinctrl/pinctrl-sunxi.c | 138 ++++++++++++++++++++++++++++++++++++++-
drivers/pinctrl/pinctrl-sunxi.h | 23 ++++++-
2 files changed, 158 insertions(+), 3 deletions(-)
--
1.7.10.4
^ permalink raw reply
* [PATCH] ARM: sunxi: gpio: Add Allwinner SoCs GPIO drivers
From: Maxime Ripard @ 2013-01-23 9:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358933646-12681-1-git-send-email-maxime.ripard@free-electrons.com>
The IP responsible for the muxing on the Allwinner SoCs are also
handling the GPIOs on the system. This patch adds the needed driver that
relies on the pinctrl driver for most of its operations.
The number of pins available for GPIOs operations are already declared
in the pinctrl driver, we only need to probe a generic driver to handle
the banks available for each SoC.
This driver has been tested on a A13-Olinuxino.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
drivers/pinctrl/pinctrl-sunxi.c | 138 ++++++++++++++++++++++++++++++++++++++-
drivers/pinctrl/pinctrl-sunxi.h | 23 ++++++-
2 files changed, 158 insertions(+), 3 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-sunxi.c b/drivers/pinctrl/pinctrl-sunxi.c
index 6f02e34..bfca9e1 100644
--- a/drivers/pinctrl/pinctrl-sunxi.c
+++ b/drivers/pinctrl/pinctrl-sunxi.c
@@ -11,6 +11,7 @@
*/
#include <linux/io.h>
+#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
@@ -609,11 +610,57 @@ static int sunxi_pmx_enable(struct pinctrl_dev *pctldev,
return 0;
}
+static int
+sunxi_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned offset,
+ bool input)
+{
+ struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ struct sunxi_desc_function *desc;
+ char *func, *pin_name;
+ u8 bank, pin;
+ int ret;
+
+ bank = (offset) / PINS_PER_BANK;
+ pin = (offset) % PINS_PER_BANK;
+
+ pin_name = kzalloc(5, GFP_KERNEL);
+ if (!pin_name)
+ return -ENOMEM;
+
+ ret = sprintf(pin_name, "P%c%d", 'A' + bank, pin);
+ if (!ret)
+ goto error;
+
+ if (input)
+ func = "gpio_in";
+ else
+ func = "gpio_out";
+
+ desc = sunxi_pinctrl_desc_find_function_by_name(pctl,
+ pin_name,
+ func);
+ if (!desc) {
+ ret = -EINVAL;
+ goto error;
+ }
+
+ sunxi_pmx_set(pctldev, offset, desc->muxval);
+
+ ret = 0;
+
+error:
+ kfree(pin_name);
+ return ret;
+}
+
static struct pinmux_ops sunxi_pmx_ops = {
.get_functions_count = sunxi_pmx_get_funcs_cnt,
.get_function_name = sunxi_pmx_get_func_name,
.get_function_groups = sunxi_pmx_get_func_groups,
.enable = sunxi_pmx_enable,
+ .gpio_set_direction = sunxi_pmx_gpio_set_direction,
};
static struct pinctrl_desc sunxi_pctrl_desc = {
@@ -622,6 +669,60 @@ static struct pinctrl_desc sunxi_pctrl_desc = {
.pmxops = &sunxi_pmx_ops,
};
+static int sunxi_pinctrl_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ return pinctrl_request_gpio(chip->base + offset);
+}
+
+static void sunxi_pinctrl_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ pinctrl_free_gpio(chip->base + offset);
+}
+
+static int sunxi_pinctrl_gpio_direction_input(struct gpio_chip *chip,
+ unsigned offset)
+{
+ return pinctrl_gpio_direction_input(chip->base + offset);
+}
+
+static int sunxi_pinctrl_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
+
+ u32 reg = sunxi_data_reg(offset);
+ u8 index = sunxi_data_offset(offset);
+ u32 val = (readl(pctl->membase + reg) >> index) & DATA_PINS_MASK;
+
+ return val;
+}
+
+static int sunxi_pinctrl_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ return pinctrl_gpio_direction_output(chip->base + offset);
+}
+
+static void sunxi_pinctrl_gpio_set(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
+ u32 reg = sunxi_data_reg(offset);
+ u8 index = sunxi_data_offset(offset);
+
+ writel((value & DATA_PINS_MASK) << index, pctl->membase + reg);
+}
+
+static struct gpio_chip sunxi_pinctrl_gpio_chip __devinitconst = {
+ .owner = THIS_MODULE,
+ .request = sunxi_pinctrl_gpio_request,
+ .free = sunxi_pinctrl_gpio_free,
+ .direction_input = sunxi_pinctrl_gpio_direction_input,
+ .direction_output = sunxi_pinctrl_gpio_direction_output,
+ .get = sunxi_pinctrl_gpio_get,
+ .set = sunxi_pinctrl_gpio_set,
+ .can_sleep = 0,
+};
+
static struct of_device_id sunxi_pinctrl_match[] = {
{ .compatible = "allwinner,sun5i-a13-pinctrl", .data = (void *)&sun5i_a13_pinctrl_data },
{}
@@ -737,7 +838,7 @@ static int sunxi_pinctrl_probe(struct platform_device *pdev)
const struct of_device_id *device;
struct pinctrl_pin_desc *pins;
struct sunxi_pinctrl *pctl;
- int i, ret;
+ int i, ret, last_pin;
pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
if (!pctl)
@@ -781,9 +882,42 @@ static int sunxi_pinctrl_probe(struct platform_device *pdev)
return -EINVAL;
}
- dev_info(&pdev->dev, "initialized sunXi pin control driver\n");
+ pctl->chip = devm_kzalloc(&pdev->dev, sizeof(*pctl->chip), GFP_KERNEL);
+ if (!pctl->chip) {
+ ret = -ENOMEM;
+ goto pinctrl_error;
+ }
+
+ last_pin = pctl->desc->pins[pctl->desc->npins - 1].pin.number;
+ pctl->chip = &sunxi_pinctrl_gpio_chip;
+ pctl->chip->ngpio = round_up(last_pin, PINS_PER_BANK);
+ pctl->chip->label = dev_name(&pdev->dev);
+ pctl->chip->dev = &pdev->dev;
+ pctl->chip->base = 0;
+
+ ret = gpiochip_add(pctl->chip);
+ if (ret)
+ goto pinctrl_error;
+
+ for (i = 0; i < pctl->desc->npins; i++) {
+ const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
+
+ ret = gpiochip_add_pin_range(pctl->chip, dev_name(&pdev->dev),
+ pin->pin.number,
+ pin->pin.number, 1);
+ if (ret)
+ goto gpiochip_error;
+ }
+
+ dev_info(&pdev->dev, "initialized sunXi PIO driver\n");
return 0;
+
+gpiochip_error:
+ ret = gpiochip_remove(pctl->chip);
+pinctrl_error:
+ pinctrl_unregister(pctl->pctl_dev);
+ return ret;
}
static struct platform_driver sunxi_pinctrl_driver = {
diff --git a/drivers/pinctrl/pinctrl-sunxi.h b/drivers/pinctrl/pinctrl-sunxi.h
index 0dc3b9d..0416c36 100644
--- a/drivers/pinctrl/pinctrl-sunxi.h
+++ b/drivers/pinctrl/pinctrl-sunxi.h
@@ -256,6 +256,7 @@
#define BANK_MEM_SIZE 0x24
#define MUX_REGS_OFFSET 0x0
+#define DATA_REGS_OFFSET 0x10
#define DLEVEL_REGS_OFFSET 0x14
#define PULL_REGS_OFFSET 0x1c
@@ -263,6 +264,9 @@
#define MUX_PINS_PER_REG 8
#define MUX_PINS_BITS 4
#define MUX_PINS_MASK 0x0f
+#define DATA_PINS_PER_REG 32
+#define DATA_PINS_BITS 1
+#define DATA_PINS_MASK 0x01
#define DLEVEL_PINS_PER_REG 16
#define DLEVEL_PINS_BITS 2
#define DLEVEL_PINS_MASK 0x03
@@ -283,6 +287,8 @@ struct sunxi_desc_pin {
struct sunxi_pinctrl_desc {
const struct sunxi_desc_pin *pins;
int npins;
+ struct pinctrl_gpio_range *ranges;
+ int nranges;
};
struct sunxi_pinctrl_function {
@@ -299,6 +305,7 @@ struct sunxi_pinctrl_group {
struct sunxi_pinctrl {
void __iomem *membase;
+ struct gpio_chip *chip;
struct sunxi_pinctrl_desc *desc;
struct device *dev;
struct sunxi_pinctrl_function *functions;
@@ -321,7 +328,6 @@ struct sunxi_pinctrl {
.muxval = _val, \
}
-
/*
* The sunXi PIO registers are organized as is:
* 0x00 - 0x0c Muxing values.
@@ -354,6 +360,21 @@ static inline u32 sunxi_mux_offset(u16 pin)
return pin_num * MUX_PINS_BITS;
}
+static inline u32 sunxi_data_reg(u16 pin)
+{
+ u8 bank = pin / PINS_PER_BANK;
+ u32 offset = bank * BANK_MEM_SIZE;
+ offset += DATA_REGS_OFFSET;
+ offset += pin % PINS_PER_BANK / DATA_PINS_PER_REG * 0x04;
+ return round_down(offset, 4);
+}
+
+static inline u32 sunxi_data_offset(u16 pin)
+{
+ u32 pin_num = pin % DATA_PINS_PER_REG;
+ return pin_num * DATA_PINS_BITS;
+}
+
static inline u32 sunxi_dlevel_reg(u16 pin)
{
u8 bank = pin / PINS_PER_BANK;
--
1.7.10.4
^ permalink raw reply related
* [PATCH 3/3] ARM: ux500: Add Snowball pin configuration for user LED
From: Linus Walleij @ 2013-01-23 9:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1357725965-27342-3-git-send-email-lee.jones@linaro.org>
On Wed, Jan 9, 2013 at 11:06 AM, Lee Jones <lee.jones@linaro.org> wrote:
> Here we setup the GPIO pin responsible for illuminating the user
> LED on the Snowball low-cost development board.
>
> Signed-off-by: Lee Jones <lee.jones@linaro.org>
Patch applied to my ux500 tree, branch ux500-pinctrl.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH 1/4] drm/tilcdc: add TI LCD Controller DRM driver (v3)
From: Jean-Francois Moine @ 2013-01-23 9:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358894185-21617-2-git-send-email-robdclark@gmail.com>
Hi Rob,
As I wanted to re-use your nxp-tda998x driver for the Marvell Dove SoC,
I had a look at your IT LCD driver. Comments below.
On Tue, 22 Jan 2013 16:36:22 -0600
Rob Clark <robdclark@gmail.com> wrote:
> A simple DRM/KMS driver for the TI LCD Controller found in various
> smaller TI parts (AM33xx, OMAPL138, etc). This driver uses the
> CMA helpers. Currently only the TFP410 DVI encoder is supported
> (tested with beaglebone + DVI cape). There are also various LCD
> displays, for which support can be added (as I get hw to test on),
> and an external i2c HDMI encoder found on some boards.
>
> The display controller supports a single CRTC. And the encoder+
> connector are split out into sub-devices. Depending on which LCD
> or external encoder is actually present, the appropriate output
> module(s) will be loaded.
>
> v1: original
> v2: fix fb refcnting and few other cleanups
> v3: get +/- vsync/hsync from timings rather than panel-info, add
> option DT max-bandwidth field so driver doesn't attempt to
> pick a display mode with too high memory bandwidth, and other
> small cleanups
>
> Signed-off-by: Rob Clark <robdclark@gmail.com>
> ---
> drivers/gpu/drm/Kconfig | 2 +
> drivers/gpu/drm/Makefile | 1 +
> drivers/gpu/drm/tilcdc/Kconfig | 10 +
> drivers/gpu/drm/tilcdc/Makefile | 8 +
> drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 597 ++++++++++++++++++++++++++++++++
> drivers/gpu/drm/tilcdc/tilcdc_drv.c | 605 +++++++++++++++++++++++++++++++++
> drivers/gpu/drm/tilcdc/tilcdc_drv.h | 159 +++++++++
> drivers/gpu/drm/tilcdc/tilcdc_regs.h | 154 +++++++++
> drivers/gpu/drm/tilcdc/tilcdc_tfp410.c | 423 +++++++++++++++++++++++
> drivers/gpu/drm/tilcdc/tilcdc_tfp410.h | 26 ++
> 10 files changed, 1985 insertions(+)
> create mode 100644 drivers/gpu/drm/tilcdc/Kconfig
> create mode 100644 drivers/gpu/drm/tilcdc/Makefile
> create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_drv.c
> create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_drv.h
> create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_regs.h
> create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
> create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_tfp410.h
[snip]
> diff --git a/drivers/gpu/drm/tilcdc/Kconfig b/drivers/gpu/drm/tilcdc/Kconfig
> new file mode 100644
> index 0000000..ee9b592
> --- /dev/null
> +++ b/drivers/gpu/drm/tilcdc/Kconfig
> @@ -0,0 +1,10 @@
> +config DRM_TILCDC
> + tristate "DRM Support for TI LCDC Display Controller"
> + depends on DRM && OF
> + select DRM_KMS_HELPER
> + select DRM_KMS_CMA_HELPER
> + select DRM_GEM_CMA_HELPER
> + help
> + Choose this option if you have an TI SoC with LCDC display
> + controller, for example AM33xx in beagle-bone, DA8xx, or
> + OMAP-L1xx. This driver replaces the FB_DA8XX fbdev driver.
> diff --git a/drivers/gpu/drm/tilcdc/Makefile b/drivers/gpu/drm/tilcdc/Makefile
> new file mode 100644
> index 0000000..1359cc2
> --- /dev/null
> +++ b/drivers/gpu/drm/tilcdc/Makefile
> @@ -0,0 +1,8 @@
> +ccflags-y := -Iinclude/drm -Werror
> +
> +tilcdc-y := \
> + tilcdc_crtc.o \
> + tilcdc_tfp410.o \
> + tilcdc_drv.o
As I understand, this means that the 3 objects will go into the
resident kernel.
I though that the device tree was created for Linux distributors who
might generate generic ARM kernels, the choice of the drivers being
done according the local device tree.
>From this point of vue, it would be nicer to have 2 separate modules:
tilcdc and tfp410, tilcdc_crtc being included in one of these ones
(I did not look deep enough at the code to know which).
[snip]
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
> new file mode 100644
> index 0000000..cf1fddc
> --- /dev/null
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
> @@ -0,0 +1,605 @@
[snip]
> +static struct drm_driver tilcdc_driver = {
> + .driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET,
> + .load = tilcdc_load,
> + .unload = tilcdc_unload,
> + .preclose = tilcdc_preclose,
> + .lastclose = tilcdc_lastclose,
> + .irq_handler = tilcdc_irq,
> + .irq_preinstall = tilcdc_irq_preinstall,
> + .irq_postinstall = tilcdc_irq_postinstall,
> + .irq_uninstall = tilcdc_irq_uninstall,
> + .get_vblank_counter = drm_vblank_count,
> + .enable_vblank = tilcdc_enable_vblank,
> + .disable_vblank = tilcdc_disable_vblank,
> + .gem_free_object = drm_gem_cma_free_object,
> + .gem_vm_ops = &drm_gem_cma_vm_ops,
> + .dumb_create = drm_gem_cma_dumb_create,
> + .dumb_map_offset = drm_gem_cma_dumb_map_offset,
> + .dumb_destroy = drm_gem_cma_dumb_destroy,
> +#ifdef CONFIG_DEBUG_FS
> + .debugfs_init = tilcdc_debugfs_init,
> + .debugfs_cleanup = tilcdc_debugfs_cleanup,
> +#endif
> + .fops = &fops,
> + .name = "tilcdc",
> + .desc = "TI LCD Controller DRM",
> + .date = "20121205",
> + .major = 1,
> + .minor = 0,
> +};
> +
> +/*
> + * Power management:
> + */
> +
> +#if CONFIG_PM_SLEEP
Should be:
#ifdef CONFIG_PM_SLEEP
[snip]
> +static struct of_device_id tilcdc_of_match[] = {
> + { .compatible = "ti,am33xx-tilcdc", },
> + { },
> +};
> +MODULE_DEVICE_TABLE(of, tilcdc_of_match);
> +
> +static struct platform_driver tilcdc_platform_driver = {
> + .probe = tilcdc_pdev_probe,
> + .remove = tilcdc_pdev_remove,
> + .driver = {
> + .owner = THIS_MODULE,
> + .name = "tilcdc",
> + .pm = &tilcdc_pm_ops,
> + .of_match_table = tilcdc_of_match,
> + },
> +};
> +
> +static int __init tilcdc_drm_init(void)
> +{
> + DBG("init");
> + tilcdc_tfp410_init();
This function may be called twice if "tilcdc,tfp410" is in the DT.
> + return platform_driver_register(&tilcdc_platform_driver);
> +}
> +
> +static void __exit tilcdc_drm_fini(void)
> +{
> + DBG("fini");
> + tilcdc_tfp410_fini();
> + platform_driver_unregister(&tilcdc_platform_driver);
> +}
> +
> +module_init(tilcdc_drm_init);
> +module_exit(tilcdc_drm_fini);
> +
> +MODULE_AUTHOR("Rob Clark <robdclark@gmail.com");
> +MODULE_DESCRIPTION("TI LCD Controller DRM Driver");
> +MODULE_LICENSE("GPL");
--
Ken ar c'henta? | ** Breizh ha Linux atav! **
Jef | http://moinejf.free.fr/
^ permalink raw reply
* [PATCH 2/4] drm/i2c: nxp-tda998x (v2)
From: Jean-Francois Moine @ 2013-01-23 9:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358894185-21617-3-git-send-email-robdclark@gmail.com>
On Tue, 22 Jan 2013 16:36:23 -0600
Rob Clark <robdclark@gmail.com> wrote:
> Driver for the NXP TDA998X i2c hdmi encoder slave.
>
> v1: original
> v2: fix npix/nline programming
>
> Signed-off-by: Rob Clark <robdclark@gmail.com>
> ---
> drivers/gpu/drm/i2c/Makefile | 3 +
> drivers/gpu/drm/i2c/tda998x_drv.c | 908 ++++++++++++++++++++++++++++++++++++++
> 2 files changed, 911 insertions(+)
> create mode 100644 drivers/gpu/drm/i2c/tda998x_drv.c
[snip]
> diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
> new file mode 100644
> index 0000000..02054e8
> --- /dev/null
> +++ b/drivers/gpu/drm/i2c/tda998x_drv.c
> @@ -0,0 +1,908 @@
[snip]
> +static void __exit
> +tda998x_exit(void)
> +{
> + DBG("");
> + drm_i2c_encoder_unregister(&tda998x_driver);
> +}
> +
> +MODULE_DESCRIPTION("NXP Semiconductors TDA998X TMDS transmitter driver");
> +
> +MODULE_AUTHOR("Rob Clark <robdclark@gmail.com");
> +MODULE_DESCRIPTION("NXP Semiconductors TDA998X HDMI Encoder");
> +MODULE_LICENSE("GPL");
> +
> +module_init(tda998x_init);
> +module_exit(tda998x_exit);
There are 2 MODULE_DESCRIPTION().
--
Ken ar c'henta? | ** Breizh ha Linux atav! **
Jef | http://moinejf.free.fr/
^ permalink raw reply
* [PATCH 1/2] usb: host: tegra: don't touch EMC clock
From: Lucas Stach @ 2013-01-23 9:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <D958900912E20642BCBC71664EFECE3E6E1B13B855@BGMAIL02.nvidia.com>
Am Mittwoch, den 23.01.2013, 12:25 +0530 schrieb Venu Byravarasu:
> > -----Original Message-----
> > From: linux-tegra-owner at vger.kernel.org [mailto:linux-tegra-
> > owner at vger.kernel.org] On Behalf Of Stephen Warren
> > Sent: Wednesday, January 23, 2013 5:58 AM
> > To: Alan Stern; Greg Kroah-Hartman; Stephen Warren
> > Cc: Venu Byravarasu; linux-tegra at vger.kernel.org; linux-arm-
> > kernel at lists.infradead.org; linux-usb at vger.kernel.org; Stephen Warren
> > Subject: [PATCH 1/2] usb: host: tegra: don't touch EMC clock
> >
> > From: Stephen Warren <swarren@nvidia.com>
> >
> > Clock "emc" is for the External Memory Controller. The USB driver has no
> > business touching this clock directly. Remove the code that does so.
>
> Stephen,
> This was primarily done to make sure that EMC is set to a minimum
> frequency, below which data errors may occur during USB transfers.
> If we plan to remove this, how should we make sure that the EMC
> is programmed for the required frequency during USB transfers?
>
You could use something like the API I added in "ARM: tegra: add EMC
clock scaling API". This needs some rework and I looked into integrating
this with the DEVFREQ framework, but I don't think it fits too well.
Bandwidth requirements should always be communicated to the EMC driver
and not described by clock rates.
Regards,
Lucas
^ permalink raw reply
* [PATCH 2/4] mtd: devices: elm: Low power transition support
From: Philip Avinash @ 2013-01-23 9:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358933176-12409-1-git-send-email-avinashphilip@ti.com>
In low power modes of AM335X platforms, peripherals power is cut off.
This patch supports low power sleep transition support for ELM driver.
Signed-off-by: Philip Avinash <avinashphilip@ti.com>
---
drivers/mtd/devices/elm.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/drivers/mtd/devices/elm.c b/drivers/mtd/devices/elm.c
index f78f43f..4793cb0 100644
--- a/drivers/mtd/devices/elm.c
+++ b/drivers/mtd/devices/elm.c
@@ -20,6 +20,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/of.h>
+#include <linux/sched.h>
#include <linux/pm_runtime.h>
#include <linux/platform_data/elm.h>
@@ -62,6 +63,7 @@ struct elm_info {
struct completion elm_completion;
struct list_head list;
enum bch_ecc bch_type;
+ bool idle;
};
static LIST_HEAD(elm_devices);
@@ -86,9 +88,11 @@ void elm_config(struct device *dev, enum bch_ecc bch_type)
u32 reg_val;
struct elm_info *info = dev_get_drvdata(dev);
+ info->idle = true;
reg_val = (bch_type & ECC_BCH_LEVEL_MASK) | (ELM_ECC_SIZE << 16);
elm_write_reg(info, ELM_LOCATION_CONFIG, reg_val);
info->bch_type = bch_type;
+ info->idle = false;
}
EXPORT_SYMBOL(elm_config);
@@ -280,6 +284,7 @@ void elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc,
struct elm_info *info = dev_get_drvdata(dev);
u32 reg_val;
+ info->idle = true;
/* Enable page mode interrupt */
reg_val = elm_read_reg(info, ELM_IRQSTATUS);
elm_write_reg(info, ELM_IRQSTATUS, reg_val & INTR_STATUS_PAGE_VALID);
@@ -298,6 +303,7 @@ void elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc,
reg_val = elm_read_reg(info, ELM_IRQENABLE);
elm_write_reg(info, ELM_IRQENABLE, reg_val & ~INTR_EN_PAGE_MASK);
elm_error_correction(info, err_vec);
+ info->idle = false;
}
EXPORT_SYMBOL(elm_decode_bch_error_page);
@@ -368,6 +374,7 @@ static int elm_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&info->list);
list_add(&info->list, &elm_devices);
platform_set_drvdata(pdev, info);
+ info->idle = false;
return ret;
}
@@ -379,6 +386,38 @@ static int elm_remove(struct platform_device *pdev)
return 0;
}
+static int elm_suspend(struct device *dev)
+{
+ struct elm_info *info = dev_get_drvdata(dev);
+ wait_queue_head_t wq;
+ DECLARE_WAITQUEUE(wait, current);
+
+ init_waitqueue_head(&wq);
+ while (1) {
+ /* Make sure that ELM not running */
+ if (info->idle) {
+ add_wait_queue(&wq, &wait);
+ schedule();
+ remove_wait_queue(&wq, &wait);
+ } else {
+ break;
+ }
+ }
+ pm_runtime_put_sync(dev);
+ return 0;
+}
+
+static int elm_resume(struct device *dev)
+{
+ struct elm_info *info = dev_get_drvdata(dev);
+
+ pm_runtime_get_sync(dev);
+ elm_config(dev, info->bch_type);
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(elm_pm_ops, elm_suspend, elm_resume);
+
#ifdef CONFIG_OF
static const struct of_device_id elm_of_match[] = {
{ .compatible = "ti,am33xx-elm" },
@@ -392,6 +431,7 @@ static struct platform_driver elm_driver = {
.name = "elm",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(elm_of_match),
+ .pm = &elm_pm_ops,
},
.probe = elm_probe,
.remove = elm_remove,
--
1.7.9.5
^ permalink raw reply related
* [PATCH 3/4] arm: gpmc: Low power transition support
From: Philip Avinash @ 2013-01-23 9:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358933176-12409-1-git-send-email-avinashphilip@ti.com>
With GPMC converted to platform driver recently, adds low power
transition support in driver itself.
Signed-off-by: Philip Avinash <avinashphilip@ti.com>
---
arch/arm/mach-omap2/gpmc.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index aed958a..af10617 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1357,9 +1357,29 @@ static __devexit int gpmc_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM
+static int gpmc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ omap3_gpmc_save_context();
+ clk_disable_unprepare(gpmc_l3_clk);
+ return 0;
+}
+
+static int gpmc_resume(struct platform_device *pdev)
+{
+ clk_prepare_enable(gpmc_l3_clk);
+ omap3_gpmc_restore_context();
+ return 0;
+}
+#endif
+
static struct platform_driver gpmc_driver = {
.probe = gpmc_probe,
.remove = __devexit_p(gpmc_remove),
+#ifdef CONFIG_PM
+ .suspend = gpmc_suspend,
+ .resume = gpmc_resume,
+#endif
.driver = {
.name = DEVICE_NAME,
.owner = THIS_MODULE,
--
1.7.9.5
^ permalink raw reply related
* [PATCH 4/4] mtd: nand: omap2: Low power transition support
From: Philip Avinash @ 2013-01-23 9:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358933176-12409-1-git-send-email-avinashphilip@ti.com>
Add support for Low power transition support in nand driver. Also
ensures the current transaction finishes before going to low power mode
with _suspend support in mtd layer.
Signed-off-by: Philip Avinash <avinashphilip@ti.com>
---
drivers/mtd/nand/omap2.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 8e820dd..790215b 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -2103,9 +2103,28 @@ static int omap_nand_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM
+static int omap_nand_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct mtd_info *mtd = platform_get_drvdata(pdev);
+
+ mtd->_suspend(mtd);
+ return 0;
+}
+
+static int omap_nand_resume(struct platform_device *pdev)
+{
+ return 0;
+}
+#endif
+
static struct platform_driver omap_nand_driver = {
.probe = omap_nand_probe,
.remove = omap_nand_remove,
+#ifdef CONFIG_PM
+ .suspend = omap_nand_suspend,
+ .resume = omap_nand_resume,
+#endif
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
--
1.7.9.5
^ permalink raw reply related
* [PATCH 1/1] ARM: ux500: Enable Snowball's GPIO controlled Ethernet regulator in DT
From: Linus Walleij @ 2013-01-23 9:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358775323-8155-1-git-send-email-lee.jones@linaro.org>
On Mon, Jan 21, 2013 at 2:35 PM, Lee Jones <lee.jones@linaro.org> wrote:
> The Snowball Board's Ethernet chip is configured in a slightly
> non-standard way. Its SoC has an address space usually reserved
> for a NOR-flash device. However, on the Snowball, that external
> bus is populated by the SMSC9115 Ethernet chip. So, to power on
> the Ethernet chip, we have to enable the GPIO controlled
> regulator which usually controls the NOR-flash. In this patch
> we inform the Snowball's Device Tree which GPIO is used to
> operate it.
>
> Signed-off-by: Lee Jones <lee.jones@linaro.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
I guess you will funnel this to ARM SoC with other DT patches?
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH 0/9 v2] at91: some fixes for 3.8-rc5
From: Nicolas Ferre @ 2013-01-23 9:48 UTC (permalink / raw)
To: linux-arm-kernel
Hi all,
A v2 of this patch series just to make sure that the patches hit the
mailing-list once...
I plan to send a pull-request later today (my time) so if you have something to
add, well, tell me by now.
Thanks for your help, bye,
Boris BREZILLON (1):
ARM: at91/dts: add macb mii pinctrl config for kizbox
Douglas Gilbert (1):
ARM: at91/dts: correct comment in at91sam9x5.dtsi for mii
Jean-Christophe PLAGNIOL-VILLARD (1):
ARM: at91: rm9200: remake the BGA as default version
Joachim Eastwood (1):
ARM: at91: fix gpios on i2c-gpio for RM9200 DT
Nicolas Ferre (2):
ARM: at91/at91_dt_defconfig: remove memory specification to cmdline
ARM: at91/at91_dt_defconfig: add at91sam9n12 SoC to DT defconfig
Richard Genoud (3):
ARM: at91/at91-pinctrl documentation: fix typo and add some details
ARM: at91/at91sam9x5 DTS: correct wrong PIO BANK values on u(s)arts
ARM: at91/at91sam9x5 DTS: add SCK USART pins
.../bindings/pinctrl/atmel,at91-pinctrl.txt | 5 +-
arch/arm/boot/dts/at91rm9200.dtsi | 4 +-
arch/arm/boot/dts/at91sam9x5.dtsi | 60 ++++++++++++++--------
arch/arm/boot/dts/kizbox.dts | 2 +
arch/arm/configs/at91_dt_defconfig | 3 +-
arch/arm/mach-at91/setup.c | 2 +
6 files changed, 51 insertions(+), 25 deletions(-)
--
1.8.0
^ permalink raw reply
* [PATCH 1/9] ARM: at91/at91-pinctrl documentation: fix typo and add some details
From: Nicolas Ferre @ 2013-01-23 9:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1358934163.git.nicolas.ferre@atmel.com>
From: Richard Genoud <richard.genoud@gmail.com>
The relation between PIN_BANK numbers and pio letters wasn't made very
clear.
Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt
index 3a26812..bc50899 100644
--- a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt
@@ -81,7 +81,8 @@ PA31 TXD4
Required properties for pin configuration node:
- atmel,pins: 4 integers array, represents a group of pins mux and config
setting. The format is atmel,pins = <PIN_BANK PIN_BANK_NUM PERIPH CONFIG>.
- The PERIPH 0 means gpio.
+ The PERIPH 0 means gpio, PERIPH 1 is periph A, PERIPH 2 is periph B...
+ PIN_BANK 0 is pioA, PIN_BANK 1 is pioB...
Bits used for CONFIG:
PULL_UP (1 << 0): indicate this pin need a pull up.
@@ -126,7 +127,7 @@ pinctrl@fffff400 {
pinctrl_dbgu: dbgu-0 {
atmel,pins =
<1 14 0x1 0x0 /* PB14 periph A */
- 1 15 0x1 0x1>; /* PB15 periph with pullup */
+ 1 15 0x1 0x1>; /* PB15 periph A with pullup */
};
};
};
--
1.8.0
^ permalink raw reply related
* [PATCH 2/9] ARM: at91/at91sam9x5 DTS: correct wrong PIO BANK values on u(s)arts
From: Nicolas Ferre @ 2013-01-23 9:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1358934163.git.nicolas.ferre@atmel.com>
From: Richard Genoud <richard.genoud@gmail.com>
The PIN_BANK 3 is for PDxx pins, not PCxx pins.
And PIN_BANK 1 is for PBxx, not PIN_BANK 0.
Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
arch/arm/boot/dts/at91sam9x5.dtsi | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
index 3a47cf9..e9c4290 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -154,12 +154,12 @@
pinctrl_usart1_rts: usart1_rts-0 {
atmel,pins =
- <3 27 0x3 0x0>; /* PC27 periph C */
+ <2 27 0x3 0x0>; /* PC27 periph C */
};
pinctrl_usart1_cts: usart1_cts-0 {
atmel,pins =
- <3 28 0x3 0x0>; /* PC28 periph C */
+ <2 28 0x3 0x0>; /* PC28 periph C */
};
};
@@ -172,46 +172,46 @@
pinctrl_uart2_rts: uart2_rts-0 {
atmel,pins =
- <0 0 0x2 0x0>; /* PB0 periph B */
+ <1 0 0x2 0x0>; /* PB0 periph B */
};
pinctrl_uart2_cts: uart2_cts-0 {
atmel,pins =
- <0 1 0x2 0x0>; /* PB1 periph B */
+ <1 1 0x2 0x0>; /* PB1 periph B */
};
};
usart3 {
pinctrl_uart3: usart3-0 {
atmel,pins =
- <3 23 0x2 0x1 /* PC22 periph B with pullup */
- 3 23 0x2 0x0>; /* PC23 periph B */
+ <2 23 0x2 0x1 /* PC22 periph B with pullup */
+ 2 23 0x2 0x0>; /* PC23 periph B */
};
pinctrl_usart3_rts: usart3_rts-0 {
atmel,pins =
- <3 24 0x2 0x0>; /* PC24 periph B */
+ <2 24 0x2 0x0>; /* PC24 periph B */
};
pinctrl_usart3_cts: usart3_cts-0 {
atmel,pins =
- <3 25 0x2 0x0>; /* PC25 periph B */
+ <2 25 0x2 0x0>; /* PC25 periph B */
};
};
uart0 {
pinctrl_uart0: uart0-0 {
atmel,pins =
- <3 8 0x3 0x0 /* PC8 periph C */
- 3 9 0x3 0x1>; /* PC9 periph C with pullup */
+ <2 8 0x3 0x0 /* PC8 periph C */
+ 2 9 0x3 0x1>; /* PC9 periph C with pullup */
};
};
uart1 {
pinctrl_uart1: uart1-0 {
atmel,pins =
- <3 16 0x3 0x0 /* PC16 periph C */
- 3 17 0x3 0x1>; /* PC17 periph C with pullup */
+ <2 16 0x3 0x0 /* PC16 periph C */
+ 2 17 0x3 0x1>; /* PC17 periph C with pullup */
};
};
--
1.8.0
^ permalink raw reply related
* [PATCH 3/9] ARM: at91/at91sam9x5 DTS: add SCK USART pins
From: Nicolas Ferre @ 2013-01-23 9:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1358934163.git.nicolas.ferre@atmel.com>
From: Richard Genoud <richard.genoud@gmail.com>
The SCK pins where missing in usarts pinctrl.
Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
arch/arm/boot/dts/at91sam9x5.dtsi | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
index e9c4290..cb711a5 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -143,6 +143,11 @@
atmel,pins =
<0 3 0x1 0x0>; /* PA3 periph A */
};
+
+ pinctrl_usart0_sck: usart0_sck-0 {
+ atmel,pins =
+ <0 4 0x1 0x0>; /* PA4 periph A */
+ };
};
usart1 {
@@ -161,6 +166,11 @@
atmel,pins =
<2 28 0x3 0x0>; /* PC28 periph C */
};
+
+ pinctrl_usart1_sck: usart1_sck-0 {
+ atmel,pins =
+ <2 28 0x3 0x0>; /* PC29 periph C */
+ };
};
usart2 {
@@ -179,6 +189,11 @@
atmel,pins =
<1 1 0x2 0x0>; /* PB1 periph B */
};
+
+ pinctrl_usart2_sck: usart2_sck-0 {
+ atmel,pins =
+ <1 2 0x2 0x0>; /* PB2 periph B */
+ };
};
usart3 {
@@ -197,6 +212,11 @@
atmel,pins =
<2 25 0x2 0x0>; /* PC25 periph B */
};
+
+ pinctrl_usart3_sck: usart3_sck-0 {
+ atmel,pins =
+ <2 26 0x2 0x0>; /* PC26 periph B */
+ };
};
uart0 {
--
1.8.0
^ permalink raw reply related
* [PATCH 4/9] ARM: at91: fix gpios on i2c-gpio for RM9200 DT
From: Nicolas Ferre @ 2013-01-23 9:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1358934163.git.nicolas.ferre@atmel.com>
From: Joachim Eastwood <manabian@gmail.com>
Signed-off-by: Joachim Eastwood <manabian@gmail.com>
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
arch/arm/boot/dts/at91rm9200.dtsi | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/at91rm9200.dtsi b/arch/arm/boot/dts/at91rm9200.dtsi
index e154f24..222047f 100644
--- a/arch/arm/boot/dts/at91rm9200.dtsi
+++ b/arch/arm/boot/dts/at91rm9200.dtsi
@@ -336,8 +336,8 @@
i2c at 0 {
compatible = "i2c-gpio";
- gpios = <&pioA 23 0 /* sda */
- &pioA 24 0 /* scl */
+ gpios = <&pioA 25 0 /* sda */
+ &pioA 26 0 /* scl */
>;
i2c-gpio,sda-open-drain;
i2c-gpio,scl-open-drain;
--
1.8.0
^ permalink raw reply related
* [PATCH 5/9] ARM: at91: rm9200: remake the BGA as default version
From: Nicolas Ferre @ 2013-01-23 9:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1358934163.git.nicolas.ferre@atmel.com>
From: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Make BGA as the default version as we are supposed to just have
to specify when we use the PQFP version.
Issue was existing since commit:
3e90772 (ARM: at91: fix at91rm9200 soc subtype handling).
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: stable <stable@vger.kernel.org> [v3.3]
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
arch/arm/mach-at91/setup.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
index 9ee866c..4b67847 100644
--- a/arch/arm/mach-at91/setup.c
+++ b/arch/arm/mach-at91/setup.c
@@ -105,6 +105,8 @@ static void __init soc_detect(u32 dbgu_base)
switch (socid) {
case ARCH_ID_AT91RM9200:
at91_soc_initdata.type = AT91_SOC_RM9200;
+ if (at91_soc_initdata.subtype == AT91_SOC_SUBTYPE_NONE)
+ at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA;
at91_boot_soc = at91rm9200_soc;
break;
--
1.8.0
^ permalink raw reply related
* [PATCH 6/9] ARM: at91/dts: add macb mii pinctrl config for kizbox
From: Nicolas Ferre @ 2013-01-23 9:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1358934163.git.nicolas.ferre@atmel.com>
From: Boris BREZILLON <linux-arm@overkiz.com>
This patch overrides default macb pinctrl config defined in
at91sam9260.dtsi (pinctrl_macb_rmii) with kizbox board config
(pinctrl_macb_rmii + pinctrl_macb_rmii_mii_alt).
Signed-off-by: Boris BREZILLON <linux-arm@overkiz.com>
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
arch/arm/boot/dts/kizbox.dts | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/boot/dts/kizbox.dts b/arch/arm/boot/dts/kizbox.dts
index e8814fe..b4dc3ed 100644
--- a/arch/arm/boot/dts/kizbox.dts
+++ b/arch/arm/boot/dts/kizbox.dts
@@ -48,6 +48,8 @@
macb0: ethernet at fffc4000 {
phy-mode = "mii";
+ pinctrl-0 = <&pinctrl_macb_rmii
+ &pinctrl_macb_rmii_mii_alt>;
status = "okay";
};
--
1.8.0
^ permalink raw reply related
* [PATCH 7/9] ARM: at91/at91_dt_defconfig: remove memory specification to cmdline
From: Nicolas Ferre @ 2013-01-23 9:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1358934163.git.nicolas.ferre@atmel.com>
No need for this cmdline option as we are using DT.
Moreover this defconfig is targeted to multiple SoC/boards: this option
was nonsense.
Reported-by: Josh Wu <josh.wu@atmel.com>
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
arch/arm/configs/at91_dt_defconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/configs/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig
index b175577..a353ff6 100644
--- a/arch/arm/configs/at91_dt_defconfig
+++ b/arch/arm/configs/at91_dt_defconfig
@@ -31,7 +31,7 @@ CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_ARM_APPENDED_DTB=y
CONFIG_ARM_ATAG_DTB_COMPAT=y
-CONFIG_CMDLINE="mem=128M console=ttyS0,115200 initrd=0x21100000,25165824 root=/dev/ram0 rw"
+CONFIG_CMDLINE="console=ttyS0,115200 initrd=0x21100000,25165824 root=/dev/ram0 rw"
CONFIG_KEXEC=y
CONFIG_AUTO_ZRELADDR=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
--
1.8.0
^ permalink raw reply related
* [PATCH 8/9] ARM: at91/at91_dt_defconfig: add at91sam9n12 SoC to DT defconfig
From: Nicolas Ferre @ 2013-01-23 9:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1358934163.git.nicolas.ferre@atmel.com>
Reported-by: Josh Wu <josh.wu@atmel.com>
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
arch/arm/configs/at91_dt_defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/configs/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig
index a353ff6..1ea9590 100644
--- a/arch/arm/configs/at91_dt_defconfig
+++ b/arch/arm/configs/at91_dt_defconfig
@@ -19,6 +19,7 @@ CONFIG_SOC_AT91SAM9260=y
CONFIG_SOC_AT91SAM9263=y
CONFIG_SOC_AT91SAM9G45=y
CONFIG_SOC_AT91SAM9X5=y
+CONFIG_SOC_AT91SAM9N12=y
CONFIG_MACH_AT91SAM_DT=y
CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
CONFIG_AT91_TIMER_HZ=128
--
1.8.0
^ permalink raw reply related
* [PATCH 9/9] ARM: at91/dts: correct comment in at91sam9x5.dtsi for mii
From: Nicolas Ferre @ 2013-01-23 9:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1358934163.git.nicolas.ferre@atmel.com>
From: Douglas Gilbert <dgilbert@interlog.com>
Concerning pinctrl_macb0_rmii_mii, values were okay, but not comments.
Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
arch/arm/boot/dts/at91sam9x5.dtsi | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
index cb711a5..8ecca69 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -260,14 +260,14 @@
pinctrl_macb0_rmii_mii: macb0_rmii_mii-0 {
atmel,pins =
- <1 8 0x1 0x0 /* PA8 periph A */
- 1 11 0x1 0x0 /* PA11 periph A */
- 1 12 0x1 0x0 /* PA12 periph A */
- 1 13 0x1 0x0 /* PA13 periph A */
- 1 14 0x1 0x0 /* PA14 periph A */
- 1 15 0x1 0x0 /* PA15 periph A */
- 1 16 0x1 0x0 /* PA16 periph A */
- 1 17 0x1 0x0>; /* PA17 periph A */
+ <1 8 0x1 0x0 /* PB8 periph A */
+ 1 11 0x1 0x0 /* PB11 periph A */
+ 1 12 0x1 0x0 /* PB12 periph A */
+ 1 13 0x1 0x0 /* PB13 periph A */
+ 1 14 0x1 0x0 /* PB14 periph A */
+ 1 15 0x1 0x0 /* PB15 periph A */
+ 1 16 0x1 0x0 /* PB16 periph A */
+ 1 17 0x1 0x0>; /* PB17 periph A */
};
};
--
1.8.0
^ permalink raw reply related
* [PATCH] Implements DMA on mmci driver for LPC3250 plateform
From: Gabriele Mondada @ 2013-01-23 9:52 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Gabriele Mondada <gabriele@precidata.com>
---
UPDATE2: sent in raw mode, sorry
UPDATE1: Here is the patch cleaned up and validated with scripts/checkpatch.pl. I also add a check to prevent crashing when DMA is disabled.
ORIGINAL POST:
Hi,
Currently, LPC32xx plateform do not enable DMA on the mmci driver. This makes the driver useless because getting out data from a 64 bytes FIFO by interrupt is not fast enough (at standard SD-card data rate).
DMA is not enabled because LPC32xx has a bug that prevent DMA to work properly with the MMC controller (silicon bug, I guess). NXP did a patch to workaround this, but it has not been commited on the main branch. The patch is for linux 2.6.39.2 and does not use dmaengine.
So, I reworked this patch to make it compatible with the last kernel (3.7). Here it is. Have I any chance to see this patch be commited on the main branch?
Thanks a lot,
Gabriele
drivers/dma/amba-pl08x.c | 20 ++++++
drivers/mmc/host/mmci.c | 159 +++++++++++++++++++++++++++++++++++++++++-----
drivers/mmc/host/mmci.h | 12 +++-
3 files changed, 174 insertions(+), 17 deletions(-)
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index d1cc579..728f65f 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -1758,6 +1758,26 @@ static void pl08x_free_virtual_channels(struct dma_device *dmadev)
}
}
+#ifdef CONFIG_ARCH_LPC32XX
+/*
+ * This exported function is used by mmci driver to workaround a bug in the
+ * LPC32xx chip, where the last DMA request is missed and must be simulated by
+ * software.
+ */
+void pl08x_force_dma_burst(struct dma_chan *chan)
+{
+ struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
+ struct pl08x_driver_data *pl08x = plchan->host;
+
+ dev_dbg(&pl08x->adev->dev,
+ "force burst signal=%d chan=%p plchan=%p\n",
+ plchan->signal, chan, plchan);
+ if (plchan->signal >= 0)
+ writel(1 << plchan->signal, pl08x->base + PL080_SOFT_BREQ);
+}
+EXPORT_SYMBOL_GPL(pl08x_force_dma_burst);
+#endif
+
#ifdef CONFIG_DEBUG_FS
static const char *pl08x_state_str(enum pl08x_dma_chan_state state)
{
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 1507723..546445b 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
* Copyright (C) 2010 ST-Ericsson SA
+ * Copyright (C) 2012 Precidata Sarl, Gabriele Mondada
*
* 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
@@ -43,6 +44,16 @@
#define DRIVER_NAME "mmci-pl18x"
+#define COOKIE_PREP 0x00000001
+#define COOKIE_SINGLE 0x00000002
+#define COOKIE_ID_MASK 0xFF000000
+#define COOKIE_ID_SHIFT 24
+#define COOKIE_ID(n) (COOKIE_ID_MASK & ((n) << COOKIE_ID_SHIFT))
+
+#ifdef CONFIG_ARCH_LPC32XX
+#define DMA_TX_SIZE SZ_64K
+#endif
+
static unsigned int fmax = 515633;
/**
@@ -133,6 +144,10 @@ static struct variant_data variant_ux500v2 = {
.signal_direction = true,
};
+#ifdef CONFIG_ARCH_LPC32XX
+void pl08x_force_dma_burst(struct dma_chan *chan);
+#endif
+
/*
* This must be called with host->lock held
*/
@@ -267,14 +282,39 @@ static void mmci_dma_setup(struct mmci_host *host)
struct mmci_platform_data *plat = host->plat;
const char *rxname, *txname;
dma_cap_mask_t mask;
+#ifdef CONFIG_ARCH_LPC32XX
+ int i;
+#endif
if (!plat || !plat->dma_filter) {
dev_info(mmc_dev(host->mmc), "no DMA platform data\n");
return;
}
- /* initialize pre request cookie */
- host->next_data.cookie = 1;
+#ifdef CONFIG_ARCH_LPC32XX
+ /*
+ * The LPC32XX do not support sg on TX DMA. So
+ * a temporary bounce buffer is used if more than 1 sg segment
+ * is passed in the data request. The bounce buffer will get a
+ * contiguous copy of the TX data and it will be used instead.
+ */
+ for (i = 0; i < 2; i++) {
+ host->dma_v_tx[i] = dma_alloc_coherent(mmc_dev(host->mmc),
+ DMA_TX_SIZE, &host->dma_p_tx[i], GFP_KERNEL);
+ if (host->dma_v_tx[i] == NULL) {
+ dev_err(mmc_dev(host->mmc),
+ "error getting DMA region\n");
+ return;
+ }
+ dev_info(mmc_dev(host->mmc), "DMA buffer: phy:%p, virt:%p\n",
+ (void *)host->dma_p_tx[i], host->dma_v_tx[i]);
+ }
+
+ host->dma_v_tx_current = host->dma_v_tx[0];
+ host->dma_p_tx_current = host->dma_p_tx[0];
+ host->next_data.dma_v_tx = host->dma_v_tx[1];
+ host->next_data.dma_p_tx = host->dma_p_tx[1];
+#endif
/* Try to acquire a generic DMA engine slave channel */
dma_cap_zero(mask);
@@ -344,12 +384,26 @@ static void mmci_dma_setup(struct mmci_host *host)
static inline void mmci_dma_release(struct mmci_host *host)
{
struct mmci_platform_data *plat = host->plat;
+#ifdef CONFIG_ARCH_LPC32XX
+ int i;
+#endif
if (host->dma_rx_channel)
dma_release_channel(host->dma_rx_channel);
if (host->dma_tx_channel && plat->dma_tx_param)
dma_release_channel(host->dma_tx_channel);
host->dma_rx_channel = host->dma_tx_channel = NULL;
+
+#ifdef CONFIG_ARCH_LPC32XX
+ for (i = 0; i < 2; i++) {
+ if (host->dma_v_tx[i] == NULL)
+ continue;
+ dma_free_coherent(mmc_dev(host->mmc), DMA_TX_SIZE,
+ host->dma_v_tx[i], host->dma_p_tx[i]);
+ host->dma_v_tx[i] = NULL;
+ host->dma_p_tx[i] = 0;
+ }
+#endif
}
static void mmci_dma_unmap(struct mmci_host *host, struct mmc_data *data)
@@ -385,8 +439,9 @@ static void mmci_dma_unmap(struct mmci_host *host, struct mmc_data *data)
dir = DMA_FROM_DEVICE;
}
- if (!data->host_cookie)
+ if (data->host_cookie && !(data->host_cookie & COOKIE_SINGLE))
dma_unmap_sg(chan->device->dev, data->sg, data->sg_len, dir);
+ /* TODO: no data->host_cookie=0 here ? */
/*
* Use of DMA with scatter-gather is impossible.
@@ -422,6 +477,7 @@ static int mmci_dma_prep_data(struct mmci_host *host, struct mmc_data *data,
struct dma_async_tx_descriptor *desc;
enum dma_data_direction buffer_dirn;
int nr_sg;
+ bool single = false;
/* Check if next job is already prepared */
if (data->host_cookie && !next &&
@@ -441,6 +497,9 @@ static int mmci_dma_prep_data(struct mmci_host *host, struct mmc_data *data,
conf.direction = DMA_MEM_TO_DEV;
buffer_dirn = DMA_TO_DEVICE;
chan = host->dma_tx_channel;
+#ifdef CONFIG_ARCH_LPC32XX
+ conf.device_fc = true;
+#endif
}
/* If there's no DMA channel, fall back to PIO */
@@ -452,13 +511,49 @@ static int mmci_dma_prep_data(struct mmci_host *host, struct mmc_data *data,
return -EINVAL;
device = chan->device;
- nr_sg = dma_map_sg(device->dev, data->sg, data->sg_len, buffer_dirn);
- if (nr_sg == 0)
- return -EINVAL;
-
dmaengine_slave_config(chan, &conf);
- desc = dmaengine_prep_slave_sg(chan, data->sg, nr_sg,
- conf.direction, DMA_CTRL_ACK);
+
+#ifdef CONFIG_ARCH_LPC32XX
+ if ((data->flags & MMC_DATA_WRITE) && (data->sg_len > 1))
+ single = true;
+#endif
+
+ if (single) {
+ int i;
+ unsigned char *dst = next ? next->dma_v_tx
+ : host->dma_v_tx_current;
+ size_t len = 0;
+
+ dev_dbg(mmc_dev(host->mmc), "use bounce buffer\n");
+ /* Move data to contiguous buffer first, then transfer it */
+ for (i = 0; i < data->sg_len; i++) {
+ unsigned long flags;
+ struct scatterlist *sg = &data->sg[i];
+ void *src;
+
+ /* Map the current scatter buffer, copy data, unmap */
+ local_irq_save(flags);
+ src = (unsigned char *)kmap_atomic(sg_page(sg)) +
+ sg->offset;
+ memcpy(dst + len, src, sg->length);
+ len += sg->length;
+ kunmap_atomic(src);
+ local_irq_restore(flags);
+ }
+
+ desc = dmaengine_prep_slave_single(chan,
+ next ? next->dma_p_tx : host->dma_p_tx_current,
+ len, buffer_dirn, DMA_CTRL_ACK);
+ } else {
+ nr_sg = dma_map_sg(device->dev, data->sg, data->sg_len,
+ buffer_dirn);
+ if (nr_sg == 0)
+ return -EINVAL;
+
+ desc = dmaengine_prep_slave_sg(chan, data->sg, nr_sg,
+ conf.direction, DMA_CTRL_ACK);
+ }
+
if (!desc)
goto unmap_exit;
@@ -470,12 +565,20 @@ static int mmci_dma_prep_data(struct mmci_host *host, struct mmc_data *data,
host->dma_desc_current = desc;
}
+ data->host_cookie = COOKIE_PREP;
+ if (single)
+ data->host_cookie |= COOKIE_SINGLE;
+ if (next)
+ data->host_cookie |= COOKIE_ID(++next->cookie_cnt);
+
return 0;
unmap_exit:
if (!next)
dmaengine_terminate_all(chan);
- dma_unmap_sg(device->dev, data->sg, data->sg_len, buffer_dirn);
+ if (!single)
+ dma_unmap_sg(device->dev, data->sg, data->sg_len, buffer_dirn);
+ data->host_cookie = 0;
return -ENOMEM;
}
@@ -513,11 +616,16 @@ static int mmci_dma_start_data(struct mmci_host *host, unsigned int datactrl)
static void mmci_get_next_data(struct mmci_host *host, struct mmc_data *data)
{
struct mmci_host_next *next = &host->next_data;
+#ifdef CONFIG_ARCH_LPC32XX
+ void *tmp_v;
+ dma_addr_t tmp_p;
+#endif
- if (data->host_cookie && data->host_cookie != next->cookie) {
- pr_warning("[%s] invalid cookie: data->host_cookie %d"
- " host->next_data.cookie %d\n",
- __func__, data->host_cookie, host->next_data.cookie);
+ if (data->host_cookie && ((data->host_cookie & COOKIE_ID_MASK) !=
+ COOKIE_ID(next->cookie_cnt))) {
+ pr_warn("[%s] invalid cookie: data->host_cookie=0x%08x host->next_data.cookie_cnt=0x%08x\n",
+ __func__, data->host_cookie,
+ host->next_data.cookie_cnt);
data->host_cookie = 0;
}
@@ -529,6 +637,15 @@ static void mmci_get_next_data(struct mmci_host *host, struct mmc_data *data)
next->dma_desc = NULL;
next->dma_chan = NULL;
+
+#ifdef CONFIG_ARCH_LPC32XX
+ tmp_v = host->next_data.dma_v_tx;
+ host->next_data.dma_v_tx = host->dma_v_tx_current;
+ host->dma_v_tx_current = tmp_v;
+ tmp_p = host->next_data.dma_p_tx;
+ host->next_data.dma_p_tx = host->dma_p_tx_current;
+ host->dma_p_tx_current = tmp_p;
+#endif
}
static void mmci_pre_request(struct mmc_host *mmc, struct mmc_request *mrq,
@@ -552,7 +669,8 @@ static void mmci_pre_request(struct mmc_host *mmc, struct mmc_request *mrq,
if (mmci_dma_prep_data(host, data, nd))
data->host_cookie = 0;
else
- data->host_cookie = ++nd->cookie < 0 ? 1 : nd->cookie;
+ data->host_cookie = COOKIE_ID(++nd->cookie_cnt) |
+ COOKIE_PREP;
}
}
@@ -580,7 +698,7 @@ static void mmci_post_request(struct mmc_host *mmc, struct mmc_request *mrq,
if (chan) {
if (err)
dmaengine_terminate_all(chan);
- if (data->host_cookie)
+ if (data->host_cookie && !(data->host_cookie & COOKIE_SINGLE))
dma_unmap_sg(mmc_dev(host->mmc), data->sg,
data->sg_len, dir);
mrq->data->host_cookie = 0;
@@ -790,6 +908,15 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
dev_err(mmc_dev(host->mmc), "stray MCI_DATABLOCKEND interrupt\n");
if (status & MCI_DATAEND || data->error) {
+#ifdef CONFIG_ARCH_LPC32XX
+ /*
+ * On LPC32XX, there is a problem with the DMA flow control and
+ * the last burst transfer is not performed. So we force the
+ * transfer programmatically here.
+ */
+ if ((data->flags & MMC_DATA_READ) && host->dma_rx_channel)
+ pl08x_force_dma_burst(host->dma_rx_channel);
+#endif
if (dma_inprogress(host))
mmci_dma_unmap(host, data);
mmci_stop_data(host);
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index d34d8c0..f2a781b 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -159,7 +159,11 @@ struct dma_chan;
struct mmci_host_next {
struct dma_async_tx_descriptor *dma_desc;
struct dma_chan *dma_chan;
- s32 cookie;
+ s32 cookie_cnt;
+#ifdef CONFIG_ARCH_LPC32XX
+ void *dma_v_tx;
+ dma_addr_t dma_p_tx;
+#endif
};
struct mmci_host {
@@ -206,6 +210,12 @@ struct mmci_host {
struct dma_chan *dma_tx_channel;
struct dma_async_tx_descriptor *dma_desc_current;
struct mmci_host_next next_data;
+#ifdef CONFIG_ARCH_LPC32XX
+ void *dma_v_tx[2];
+ dma_addr_t dma_p_tx[2];
+ void *dma_v_tx_current;
+ dma_addr_t dma_p_tx_current;
+#endif
#define dma_inprogress(host) ((host)->dma_current)
#else
--
1.7.10.4
^ permalink raw reply related
* [PATCH 1/2] i2c: sirf: register i2c_client from dt child-nodes in probe entry
From: Wolfram Sang @ 2013-01-23 9:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1356489017-17737-1-git-send-email-Barry.Song@csr.com>
On Wed, Dec 26, 2012 at 10:30:16AM +0800, Barry Song wrote:
> From: Barry Song <Baohua.Song@csr.com>
>
> in probe() entry of i2c_driver, set the of node of adapter and
> call of_i2c_register_devices to register all i2c_client from
> dt child-nodes
>
> Signed-off-by: Barry Song <Baohua.Song@csr.com>
Thanks, applied to for-current.
^ permalink raw reply
* [PATCH] clk: Add axi-clkgen driver
From: Lars-Peter Clausen @ 2013-01-23 9:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130122180822.GA2371@kryptos>
On 01/22/2013 07:08 PM, Josh Cartwright wrote:
> On Wed, Jan 09, 2013 at 07:12:00PM +0100, Lars-Peter Clausen wrote:
>> This driver adds support for the AXI clkgen pcore to the common clock framework.
>> The AXI clkgen pcore is a AXI front-end to the MMCM_ADV frequency synthesizer
>> commonly found in Xilinx FPGAs.
>>
>> The AXI clkgen pcore is used in Analog Devices' reference designs targeting
>> Xilinx FPGAs.
>>
>> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
>> ---
>> .../devicetree/bindings/clock/axi-clkgen.txt | 22 ++
>> drivers/clk/Kconfig | 8 +
>> drivers/clk/Makefile | 1 +
>> drivers/clk/clk-axi-clkgen.c | 326 +++++++++++++++++++++
>> 4 files changed, 357 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/clock/axi-clkgen.txt
>> create mode 100644 drivers/clk/clk-axi-clkgen.c
>>
> [..]
>> diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c
>> new file mode 100644
>> index 0000000..e9db225
>> --- /dev/null
>> +++ b/drivers/clk/clk-axi-clkgen.c
>> @@ -0,0 +1,326 @@
>> +/*
>> + * AXI clkgen driver
>> + *
>> + * Copyright 2012-2013 Analog Device Inc.
>> + * Author: Lars-Peter Clausen <lars@metafoo.de>
>> + *
>> + * Licensed under the GPL-2.
>> + *
>> + */
>> +
>> +#include <linux/platform_device.h>
>> +#include <linux/clk-provider.h>
>> +#include <linux/clk.h>
>> +#include <linux/slab.h>
>> +#include <linux/io.h>
>> +#include <linux/of.h>
>> +#include <linux/module.h>
>> +#include <linux/err.h>
>> +
>> +#define AXI_CLKGEN_REG_UPDATE_ENABLE 0x04
>> +#define AXI_CLKGEN_REG_CLK_OUT1 0x08
>> +#define AXI_CLKGEN_REG_CLK_OUT2 0x0c
>> +#define AXI_CLKGEN_REG_CLK_DIV 0x10
>> +#define AXI_CLKGEN_REG_CLK_FB1 0x14
>> +#define AXI_CLKGEN_REG_CLK_FB2 0x18
>> +#define AXI_CLKGEN_REG_LOCK1 0x1c
>> +#define AXI_CLKGEN_REG_LOCK2 0x20
>> +#define AXI_CLKGEN_REG_LOCK3 0x24
>> +#define AXI_CLKGEN_REG_FILTER1 0x28
>> +#define AXI_CLKGEN_REG_FILTER2 0x2c
>> +
>> +struct axi_clkgen {
>> + void __iomem *base;
>> + struct clk_hw clk_hw;
>> +};
>> +
>> +static uint32_t axi_clkgen_lookup_filter(unsigned int m)
>> +{
>> + switch (m) {
>> + case 0:
>> + return 0x01001990;
>> + case 1:
>> + return 0x01001190;
>> + case 2:
>> + return 0x01009890;
>> + case 3:
>> + return 0x01001890;
>> + case 4:
>> + return 0x01008890;
>> + case 5 ... 8:
>> + return 0x01009090;
>> + case 9 ... 11:
>> + return 0x0100890;
>
> Just checking to ensure this ^ entry is correct, since it looks
> different then the others (it may very well be).
Nice catch, it's wrong indeed.
Thanks
- Lars
^ permalink raw reply
* [PATCH REBASE 0/6] i2c: omap: misc changes
From: Wolfram Sang @ 2013-01-23 9:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130114191628.GB9402@arwen.pp.htv.fi>
On Mon, Jan 14, 2013 at 09:16:28PM +0200, Felipe Balbi wrote:
> Hi,
>
> On Fri, Dec 14, 2012 at 06:34:03PM +0200, Felipe Balbi wrote:
> > this is just a rebase of the previous series adding support
> > for amount of bytes transferred upon NACK.
> >
> > Well, actually the patches implementing transferred bytes
> > reporting aren't here because we need to discuss how to move
> > forward.
> >
> > This series is just a preparation for that, but it also
> > contains a at least one bugfix.
> >
> > Each and every patch has been tested with pandaboard, it
> > would be nice to get Tested-bys from other folks on other
> > platforms before pushing this for v3.9 (there's more than
> > enough time for that).
> >
> > Note that we're also dropping b_hw flag since that becomes
> > useless since we'll never set STT and STP together anymore.
> >
> > Give it a good round of test, please.
>
> Wolfram, I have these patches rebased on top of v3.8-rc3 if you wish.
> Let me know if I should resend them (again).
Yes, please rebase on top of Aaro's patches (probably in v3.8-rc5).
Patches look mostly good, have to think more about what Patch 5 is
wanting to achieve at the end of the day.
^ permalink raw reply
* [PATCH] clk: Add axi-clkgen driver
From: Lars-Peter Clausen @ 2013-01-23 10:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130122175552.24671.27893@quantum>
On 01/22/2013 06:55 PM, Mike Turquette wrote:
> Quoting Lars-Peter Clausen (2013-01-09 10:12:00)
> <snip>
>> +static void axi_clkgen_write(struct axi_clkgen *axi_clkgen,
>> + unsigned int reg, unsigned int val)
>> +{
>> + iowrite32(val, axi_clkgen->base + reg);
>
> Silly question: any reason to use this over readl()? This is more for
> my understanding than a real criticism.
I think I read somewhere at some point that ioread{8,16,32} is preferred
over write{b,h,l} in new code.
>
>> +}
>> +
>> +static void axi_clkgen_read(struct axi_clkgen *axi_clkgen,
>> + unsigned int reg, unsigned int *val)
>> +{
>> + *val = ioread32(axi_clkgen->base + reg);
>
> Same as above, any reason to use this over writel?
Same answer.
>
> <snip>
>> +static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw,
>> + unsigned long parent_rate)
>> +{
>> + struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
>> + unsigned int d, m, dout;
>> + unsigned int reg;
>> +
>> + axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_OUT1, ®);
>> + dout = (reg & 0x3f) + ((reg >> 6) & 0x3f);
>> + axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_DIV, ®);
>> + d = (reg & 0x3f) + ((reg >> 6) & 0x3f);
>> + axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_FB1, ®);
>> + m = (reg & 0x3f) + ((reg >> 6) & 0x3f);
>> +
>> + if (d == 0 || dout == 0)
>> + return 0;
>> +
>> + return parent_rate / d * m / dout;
>
> Any chance of overflow here? Maybe do_div should be used?
Not if all the parameters are within spec. But since this is on a slowpath I
guess it does not hurt to use do_div.
Will send a v2.
Thanks for the review,
- Lars
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox