Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 1/4] ARM: dts: omap5: Update GPIO with address space and interrupts
From: Sebastien Guiriec @ 2012-10-24  7:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351062434-22514-1-git-send-email-s-guiriec@ti.com>

Add base address and interrupt line inside Device Tree data for
OMAP5

Signed-off-by: Sebastien Guiriec <s-guiriec@ti.com>
---
 arch/arm/boot/dts/omap5.dtsi |   24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
index 42c78be..737a536 100644
--- a/arch/arm/boot/dts/omap5.dtsi
+++ b/arch/arm/boot/dts/omap5.dtsi
@@ -104,6 +104,9 @@
 
 		gpio1: gpio at 4ae10000 {
 			compatible = "ti,omap4-gpio";
+			reg = <0x4ae10000 0x200>;
+			interrupts = <0 29 0x4>;
+			interrupt-parent = <&gic>;
 			ti,hwmods = "gpio1";
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -113,6 +116,9 @@
 
 		gpio2: gpio at 48055000 {
 			compatible = "ti,omap4-gpio";
+			reg = <0x48055000 0x200>;
+			interrupts = <0 30 0x4>;
+			interrupt-parent = <&gic>;
 			ti,hwmods = "gpio2";
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -122,6 +128,9 @@
 
 		gpio3: gpio at 48057000 {
 			compatible = "ti,omap4-gpio";
+			reg = <0x48057000 0x200>;
+			interrupts = <0 31 0x4>;
+			interrupt-parent = <&gic>;
 			ti,hwmods = "gpio3";
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -131,6 +140,9 @@
 
 		gpio4: gpio at 48059000 {
 			compatible = "ti,omap4-gpio";
+			reg = <0x48059000 0x200>;
+			interrupts = <0 32 0x4>;
+			interrupt-parent = <&gic>;
 			ti,hwmods = "gpio4";
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -140,6 +152,9 @@
 
 		gpio5: gpio at 4805b000 {
 			compatible = "ti,omap4-gpio";
+			reg = <0x4805b000 0x200>;
+			interrupts = <0 33 0x4>;
+			interrupt-parent = <&gic>;
 			ti,hwmods = "gpio5";
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -149,6 +164,9 @@
 
 		gpio6: gpio at 4805d000 {
 			compatible = "ti,omap4-gpio";
+			reg = <0x4805d000 0x200>;
+			interrupts = <0 34 0x4>;
+			interrupt-parent = <&gic>;
 			ti,hwmods = "gpio6";
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -158,6 +176,9 @@
 
 		gpio7: gpio at 48051000 {
 			compatible = "ti,omap4-gpio";
+			reg = <0x48051000 0x200>;
+			interrupts = <0 35 0x4>;
+			interrupt-parent = <&gic>;
 			ti,hwmods = "gpio7";
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -167,6 +188,9 @@
 
 		gpio8: gpio at 48053000 {
 			compatible = "ti,omap4-gpio";
+			reg = <0x48053000 0x200>;
+			interrupts = <0 121 0x4>;
+			interrupt-parent = <&gic>;
 			ti,hwmods = "gpio8";
 			gpio-controller;
 			#gpio-cells = <2>;
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH v3 0/4] ARM: dts: Update OMAP5 with address space and interrupts
From: Sebastien Guiriec @ 2012-10-24  7:07 UTC (permalink / raw)
  To: linux-arm-kernel

Since kernel 3.7 the DTS data are not overwriten by hwmod data we can add the address space
and interrupt line description inside dtsi file for OMAP5. This serie is updating the
current OMAP5 IP with missing entry.

It has been tested on OMAP5 with 3.7-audio-display feature tree.
- MMC is probing and functional
- TWL6041 probing (GPIO/I2C)
- booting (UART)

Update since v1:
- Add Ack and review
- Fix up commit messages.

Update since v2:
- Add interrupt-parent.

Sebastien Guiriec (4):
  ARM: dts: omap5: Update GPIO with address space and interrupts
  ARM: dts: omap5: Update I2C with address space and interrupts
  ARM: dts: omap5: Update UART with address space and interrupts
  ARM: dts: omap5: Update MMC with address space and interrupts

 arch/arm/boot/dts/omap5.dtsi |   80 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 76 insertions(+), 4 deletions(-)

-- 
1.7.10.4

^ permalink raw reply

* [PATCH] GPIO: clps711x: Fix return value for gpio_clps711x_get
From: Alexander Shiyan @ 2012-10-24  6:58 UTC (permalink / raw)
  To: linux-arm-kernel


Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
---
 drivers/gpio/gpio-clps711x.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpio/gpio-clps711x.c b/drivers/gpio/gpio-clps711x.c
index ea21822..0753b3a 100644
--- a/drivers/gpio/gpio-clps711x.c
+++ b/drivers/gpio/gpio-clps711x.c
@@ -47,7 +47,7 @@ static void __iomem *clps711x_pdirs[] = {
 
 static int gpio_clps711x_get(struct gpio_chip *chip, unsigned offset)
 {
-	return !!readb(clps711x_port(chip)) & (1 << offset);
+	return !!(readb(clps711x_port(chip)) & (1 << offset));
 }
 
 static void gpio_clps711x_set(struct gpio_chip *chip, unsigned offset,
-- 
1.7.3.4

^ permalink raw reply related

* [PATCHv4] Input: keypad: Add smsc ece1099 keypad driver
From: Dmitry Torokhov @ 2012-10-24  6:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1349421986-12467-1-git-send-email-sourav.poddar@ti.com>

Hi Sourav,

On Fri, Oct 05, 2012 at 12:56:26PM +0530, Sourav Poddar wrote:
> From: G, Manjunath Kondaiah <manjugk@ti.com>
> 
> SMSC ECE1099 is a keyboard scan or GPIO expansion device.The device
> supports a keypad scan matrix of 23*8.This driver uses this
> device as a keypad driver.
> 
> Tested on omap5430 evm with 3.6-rc6 custom kernel.
> 
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Felipe Balbi <balbi@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Signed-off-by: G, Manjunath Kondaiah <manjugk@ti.com>
> Signed-off-by: Sourav Poddar <sourav.poddar@ti.com>
> Acked-by: Felipe Balbi <balbi@ti.com>
> ---
> This patch was posted as a series initially
> http://www.spinics.net/lists/linux-omap/msg78772.html
> 
> But the parent mfd driver has beeen already picked by mfd maintainer.
> So this patch can now posted as an standalone patch.
> 
> v3->v4:
> Fix Dmitry's comments:
>  - Error patch(input_free_device/input_unregister_device).
>  - Few cleanups.
>  - Included INPUT_MATRIXKMAP
>  drivers/input/keyboard/Kconfig               |   12 +
>  drivers/input/keyboard/Makefile              |    1 +
>  drivers/input/keyboard/smsc-ece1099-keypad.c |  303 ++++++++++++++++++++++++++
>  3 files changed, 316 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/input/keyboard/smsc-ece1099-keypad.c
> 
> diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
> index c50fa75..e370b03 100644
> --- a/drivers/input/keyboard/Kconfig
> +++ b/drivers/input/keyboard/Kconfig
> @@ -593,6 +593,18 @@ config KEYBOARD_TWL4030
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called twl4030_keypad.
>  
> +config KEYBOARD_SMSC
> +       tristate "SMSC ECE1099 keypad support"
> +       depends on I2C
> +       select INPUT_MATRIXKMAP

While I do not see hard dependencies in the driver itself, should we
also depend on MFD_SMSC?

> +       help
> +         Say Y here if your board use the smsc keypad controller
> +         for omap5 defconfig. It's safe to say enable this
> +         even on boards that don't use the keypad controller.
> +
> +         To compile this driver as a module, choose M here: the
> +         module will be called smsc-ece1099-keypad.
> +
>  config KEYBOARD_XTKBD
>  	tristate "XT keyboard"
>  	select SERIO
> diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
> index 44e7600..0f2aa26 100644
> --- a/drivers/input/keyboard/Makefile
> +++ b/drivers/input/keyboard/Makefile
> @@ -52,5 +52,6 @@ obj-$(CONFIG_KEYBOARD_TC3589X)		+= tc3589x-keypad.o
>  obj-$(CONFIG_KEYBOARD_TEGRA)		+= tegra-kbc.o
>  obj-$(CONFIG_KEYBOARD_TNETV107X)	+= tnetv107x-keypad.o
>  obj-$(CONFIG_KEYBOARD_TWL4030)		+= twl4030_keypad.o
> +obj-$(CONFIG_KEYBOARD_SMSC)            += smsc-ece1099-keypad.o
>  obj-$(CONFIG_KEYBOARD_XTKBD)		+= xtkbd.o
>  obj-$(CONFIG_KEYBOARD_W90P910)		+= w90p910_keypad.o
> diff --git a/drivers/input/keyboard/smsc-ece1099-keypad.c b/drivers/input/keyboard/smsc-ece1099-keypad.c
> new file mode 100644
> index 0000000..a4a0dfe
> --- /dev/null
> +++ b/drivers/input/keyboard/smsc-ece1099-keypad.c
> @@ -0,0 +1,303 @@
> +/*
> + * SMSC_ECE1099 Keypad driver
> + *
> + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/i2c.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/input.h>
> +#include <linux/gpio.h>
> +#include <linux/slab.h>
> +#include <linux/jiffies.h>
> +#include <linux/input/matrix_keypad.h>
> +#include <linux/delay.h>
> +#include <linux/mfd/core.h>
> +#include <linux/mfd/smsc.h>
> +#include <linux/of_gpio.h>
> +#include <linux/of.h>
> +
> +#define KEYPRESS_TIME          200
> +
> +struct smsc_keypad {
> +	struct smsc *smsc;

I do not see this being actually used.

> +	struct matrix_keymap_data *keymap_data;

Does not seem to be used.

> +	unsigned int last_key_state[16];
> +	unsigned int last_col;
> +	unsigned int last_key_ms[16];
> +	unsigned short *keymap;
> +	struct i2c_client *client;
> +	struct input_dev *input;
> +	int rows, cols;
> +	int row_shift;
> +	bool no_autorepeat;
> +	unsigned        irq;

I do not think you need to store irq if you are using managed resources.

> +	struct device *dev;
> +};
> +
> +static void smsc_kp_scan(struct smsc_keypad *kp)
> +{
> +	struct input_dev *input = kp->input;
> +	int i, j;
> +	int row, col;
> +	int temp, code;
> +	unsigned int new_state[16];
> +	unsigned int bits_changed;
> +	int this_ms;
> +
> +	smsc_write(kp->dev, SMSC_KP_INT_MASK, 0x00);
> +	smsc_write(kp->dev, SMSC_KP_INT_STAT, 0xFF);
> +
> +	/* Scan for row and column */
> +	for (i = 0; i < kp->cols; i++) {
> +		smsc_write(kp->dev, SMSC_KP_OUT, SMSC_KSO_EVAL + i);
> +		/* Read Row Status */
> +		smsc_read(kp->dev, SMSC_KP_IN, &temp);
> +		if (temp == 0xFF)
> +			continue;
> +
> +		col = i;
> +		for (j = 0; j < kp->rows; j++) {
> +			if ((temp & 0x01) != 0x00) {
> +				temp = temp >> 1;
> +				continue;
> +			}
> +
> +			row = j;
> +			new_state[col] =  (1 << row);
> +			bits_changed = kp->last_key_state[col] ^ new_state[col];
> +			this_ms = jiffies_to_msecs(jiffies);
> +			if (bits_changed != 0 || (!bits_changed &&
> +					((this_ms - kp->last_key_ms[col]) >= KEYPRESS_TIME))) {
> +				code = MATRIX_SCAN_CODE(row, col, kp->row_shift);
> +				input_event(input, EV_MSC, MSC_SCAN, code);
> +				input_report_key(input, kp->keymap[code], 1);
> +				input_report_key(input, kp->keymap[code], 0);
> +				kp->last_key_state[col] = new_state[col];
> +				if (kp->last_col != col)
> +					kp->last_key_state[kp->last_col] = 0;
> +				kp->last_key_ms[col] = this_ms;
> +			}
> +			temp = temp >> 1;
> +		}


Maybe split inner loop into separate function?

> +	}
> +	input_sync(input);
> +
> +	smsc_write(kp->dev, SMSC_KP_INT_MASK, 0xFF);
> +
> +	/* Set up Low Power Mode (Wake-up) (0xFB) */
> +	smsc_write(kp->dev, SMSC_WKUP_CTRL, SMSC_KP_SET_LOW_PWR);
> +
> +	/*Enable Keypad Scan (generate interrupt on key press) (0x40)*/
> +	smsc_write(kp->dev, SMSC_KP_OUT, SMSC_KSO_ALL_LOW);
> +}
> +
> +static irqreturn_t do_kp_irq(int irq, void *_kp)
> +{
> +	struct smsc_keypad *kp = _kp;
> +	int int_status;
> +
> +	smsc_read(kp->dev, SMSC_KP_INT_STAT, &int_status);
> +	if (int_status)
> +		smsc_kp_scan(kp);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +#ifdef CONFIG_OF
> +static int __devinit smsc_keypad_parse_dt(struct device *dev,
> +				struct smsc_keypad *kp)
> +{
> +	struct device_node *np = dev->of_node;
> +
> +	if (!np) {
> +		dev_err(dev, "missing DT data");
> +		return -EINVAL;
> +	}
> +
> +	of_property_read_u32(np, "keypad,num-rows", &kp->rows);
> +	of_property_read_u32(np, "keypad,num-columns", &kp->cols);
> +	if (!kp->rows || !kp->cols) {
> +		dev_err(dev, "number of keypad rows/columns not specified\n");
> +		return -EINVAL;
> +	}
> +
> +	if (of_property_read_bool(np, "linux,input-no-autorepeat"))
> +		kp->no_autorepeat = true;
> +
> +	return 0;
> +}
> +#else
> +static inline int smsc_keypad_parse_dt(struct device *dev,
> +				struct smsc_keypad *kp)
> +{
> +	return -ENOSYS;
> +}
> +#endif
> +
> +static int __devinit
> +smsc_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct smsc *smsc = dev_get_drvdata(pdev->dev.parent);
> +	struct input_dev *input;
> +	struct smsc_keypad *kp;
> +	int ret = 0;
> +	int i, max_keys, row_shift;
> +	int irq;
> +	int addr;
> +
> +	kp = devm_kzalloc(dev, sizeof(*kp), GFP_KERNEL);
> +
> +	input = input_allocate_device();
> +	if (!kp || !input) {
> +		ret = -ENOMEM;
> +		goto err1;
> +	}
> +
> +	ret = smsc_keypad_parse_dt(&pdev->dev, kp);
> +	if (ret)
> +		goto err1;

So this is pure-DT driver. Please add Kconfig dependency on OF, drop
#ifdef guards and the stub.

> +
> +	/* Get the debug Device */
> +	kp->input = input;
> +	kp->smsc = smsc;
> +	kp->irq = platform_get_irq(pdev, 0);
> +	kp->dev = dev;
> +
> +	/* setup input device */
> +	 __set_bit(EV_KEY, input->evbit);
> +
> +	/* Enable auto repeat feature of Linux input subsystem */
> +	if (!kp->no_autorepeat)
> +		__set_bit(EV_REP, input->evbit);
> +
> +	input_set_capability(input, EV_MSC, MSC_SCAN);
> +	input->name             = "SMSC Keypad";
> +	input->phys             = "smsc_keypad/input0";
> +	input->dev.parent       = &pdev->dev;
> +	input->id.bustype       = BUS_HOST;
> +	input->id.vendor        = 0x0001;
> +	input->id.product       = 0x0001;
> +	input->id.version       = 0x0003;
> +
> +	/* Mask all GPIO interrupts (0x37-0x3B) */
> +	for (addr = SMSC_GPIO_INT_MASK_START;
> +			addr < SMSC_GPIO_INT_MASK_START + 4; addr++)
> +		smsc_write(dev, addr, 0);
> +
> +	/* Set all outputs high (0x05-0x09) */
> +	for (addr = SMSC_GPIO_DATA_OUT_START;
> +			addr < SMSC_GPIO_DATA_OUT_START + 4; addr++)
> +		smsc_write(dev, addr, 0xff);
> +
> +	/* Clear all GPIO interrupts (0x32-0x36) */
> +	for (addr = SMSC_GPIO_INT_STAT_START;
> +			addr < SMSC_GPIO_INT_STAT_START + 4; addr++)
> +		smsc_write(dev, addr, 0xff);

You use lowercase hex digits here but also uppercase in other parts of
the driver. Can we use lowercase throughout please?

> +
> +	/* Configure the smsc pins as Keyboard scan Input */
> +	for (i = 0; i <= kp->rows; i++) {

You sure you don't want < instead of <= ?

> +		addr = 0x12 + i;
> +		smsc_write(dev, addr, SMSC_KP_KSI);
> +	}
> +
> +	/* Configure the smsc pins as Keyboard scan output */
> +	for (i = 0; i <= kp->cols; i++) {
> +		addr = 0x1A + i;
> +		smsc_write(dev, addr, SMSC_KP_KSO);
> +	}
> +
> +	smsc_write(dev, SMSC_KP_INT_STAT, SMSC_KP_SET_HIGH);
> +	smsc_write(dev, SMSC_WKUP_CTRL, SMSC_KP_SET_LOW_PWR);
> +	smsc_write(dev, SMSC_KP_OUT, SMSC_KSO_ALL_LOW);
> +
> +	row_shift = get_count_order(kp->cols);
> +	max_keys = kp->rows << row_shift;
> +
> +	kp->row_shift = row_shift;
> +	kp->keymap = devm_kzalloc(dev, max_keys * sizeof(kp->keymap[0]),
> +					GFP_KERNEL);
> +	if (!kp->keymap) {
> +		dev_err(&pdev->dev, "Not enough memory for keymap\n");
> +		ret = -ENOMEM;
> +	}
> +
> +	ret = matrix_keypad_build_keymap(NULL, NULL, kp->rows,
> +			kp->cols, kp->keymap, input);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to build keymap\n");
> +		goto err1;
> +	}
> +
> +	/*
> +	* This ISR will always execute in kernel thread context because of
> +	* the need to access the SMSC over the I2C bus.
> +	*/
> +	ret = devm_request_threaded_irq(dev, kp->irq, NULL, do_kp_irq,
> +			IRQF_TRIGGER_FALLING | IRQF_ONESHOT, pdev->name, kp);
> +	if (ret) {
> +		dev_dbg(&pdev->dev, "request_irq failed for irq no=%d\n",
> +			irq);
> +		goto err1;
> +	}
> +
> +	/* Enable smsc keypad interrupts */
> +	ret = smsc_write(dev, SMSC_KP_INT_MASK, 0xff);
> +	if (ret < 0)
> +		goto err2;

Consider implementing ->open() and ->close() and putting the above
there.

> +
> +	ret = input_register_device(input);
> +	if (ret) {
> +		dev_err(kp->dev,
> +			"Unable to register twl4030 keypad device\n");
> +		goto err2;
> +	}
> +
> +	return 0;
> +
> +err2:
> +	free_irq(kp->irq, kp);

If you allocate IRQ with devm_request_threaded_irq then you should free
it with devm_free_irq().

> +err1:
> +	input_free_device(input);
> +	return ret;
> +}
> +
> +static int __devexit smsc_remove(struct platform_device *pdev)
> +{
> +	struct smsc_keypad *kp = platform_get_drvdata(pdev);
> +	input_unregister_device(kp->input);

This is wrong: input device is gone but IRQs are still active. You need
to disable or free IRQ first.

However I just posted a patch adding support for managed input devices:

	http://www.spinics.net/lists/linux-input/msg23077.html

so please either switch over, or go with unmanaged resources
throughout.

> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_OF

Since we require DT this ifdef is not needed.

> +static const struct of_device_id smsc_keypad_dt_match[] = {
> +	{ .compatible = "smsc,keypad" },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, smsc_keypad_dt_match);
> +#endif
> +
> +static struct platform_driver smsc_driver = {
> +	.driver = {
> +		.name	= "smsc-keypad",
> +		.of_match_table = of_match_ptr(smsc_keypad_dt_match),
> +		.owner  = THIS_MODULE,
> +	},
> +	.probe		= smsc_probe,
> +	.remove		= __devexit_p(smsc_remove),
> +};
> +
> +module_platform_driver(smsc_driver);
> +
> +MODULE_AUTHOR("G Kondaiah Manjunath <manjugk@ti.com>");
> +MODULE_DESCRIPTION("SMSC ECE1099 Keypad driver");
> +MODULE_LICENSE("GPL v2");
> -- 
> 1.7.1
> 

Thanks.

-- 
Dmitry

^ permalink raw reply

* [PATCH 2/2] cpufreq: governors: remove redundant code
From: Viresh Kumar @ 2012-10-24  6:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAKohpo=Jsy9az4PgJ-mkq_U49EOpHGES+-DaROanCOTn-L2s3Q@mail.gmail.com>

On 22 October 2012 14:16, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> On 20 October 2012 01:42, Viresh Kumar <viresh.kumar@linaro.org> wrote:
>> Initially ondemand governor was written and then using its code conservative
>> governor is written. It used a lot of code from ondemand governor, but copy of
>> code was created instead of using the same routines from both governors. Which
>> increased code redundancy, which is difficult to manage.
>>
>> This patch is an attempt to move common part of both the governors to
>> cpufreq_governor.c file to come over above mentioned issues.
>>
>> This shouldn't change anything from functionality point of view.
>>
>> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>

For everybody else, this patch is already pushed by Rafael in his linux-next
branch.

--
viresh

^ permalink raw reply

* [PATCH] ARM: mach-shmobile: Use DT_MACHINE for mackerel
From: Nobuhiro Iwamatsu @ 2012-10-24  5:48 UTC (permalink / raw)
  To: linux-arm-kernel

Use DT_MACHINE_START() on the sh7372 based mackerel board.

Also include a tiny DTS file to describe the board and update the
Kconfig dependencies to select CONFIG_USE_OF.

Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
---
 arch/arm/boot/dts/Makefile              |    3 ++-
 arch/arm/boot/dts/sh7372-mackerel.dts   |   22 ++++++++++++++++++++++
 arch/arm/mach-shmobile/Kconfig          |    1 +
 arch/arm/mach-shmobile/board-mackerel.c |    8 +++++++-
 4 files changed, 32 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/boot/dts/sh7372-mackerel.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index f37cf9f..a9d8a10 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -77,7 +77,8 @@ dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
 dtb-$(CONFIG_ARCH_U8500) += snowball.dtb
 dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \
 	r8a7740-armadillo800eva.dtb \
-	sh73a0-kzm9g.dtb
+	sh73a0-kzm9g.dtb \
+	sh7372-mackerel.dtb
 dtb-$(CONFIG_ARCH_SPEAR13XX) += spear1310-evb.dtb \
 	spear1340-evb.dtb
 dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \
diff --git a/arch/arm/boot/dts/sh7372-mackerel.dts b/arch/arm/boot/dts/sh7372-mackerel.dts
new file mode 100644
index 0000000..286f0ca
--- /dev/null
+++ b/arch/arm/boot/dts/sh7372-mackerel.dts
@@ -0,0 +1,22 @@
+/*
+ * Device Tree Source for the mackerel board
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+	model = "Mackerel (AP4 EVM 2nd)";
+	compatible = "renesas,mackerel";
+
+	memory {
+		device_type = "memory";
+		reg = <0x40000000 0x10000000>;
+	};
+};
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 8ae100c..0750d9c 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -95,6 +95,7 @@ config MACH_MACKEREL
 	select ARCH_REQUIRE_GPIOLIB
 	select REGULATOR_FIXED_VOLTAGE if REGULATOR
 	select SND_SOC_AK4642 if SND_SIMPLE_CARD
+	select USE_OF
 
 config MACH_KOTA2
 	bool "KOTA2 board"
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 0c27c81..39b8f2e 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -1651,7 +1651,12 @@ static void __init mackerel_init(void)
 	pm_clk_add(&hdmi_lcdc_device.dev, "hdmi");
 }
 
-MACHINE_START(MACKEREL, "mackerel")
+static const char *mackerel_boards_compat_dt[] __initdata = {
+	"renesas,mackerel",
+	NULL,
+};
+
+DT_MACHINE_START(MACKEREL_DT, "mackerel")
 	.map_io		= sh7372_map_io,
 	.init_early	= sh7372_add_early_devices,
 	.init_irq	= sh7372_init_irq,
@@ -1659,4 +1664,5 @@ MACHINE_START(MACKEREL, "mackerel")
 	.init_machine	= mackerel_init,
 	.init_late	= sh7372_pm_init_late,
 	.timer		= &shmobile_timer,
+	.dt_compat  = mackerel_boards_compat_dt,
 MACHINE_END
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 03/10] tty: pxa: configure pin
From: Linus Walleij @ 2012-10-24  5:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121023115806.GX4477@opensource.wolfsonmicro.com>

On Tue, Oct 23, 2012 at 1:58 PM, Mark Brown
<broonie@opensource.wolfsonmicro.com> wrote:

> One problem
> is that we don't have a home for the SoC integration so we're trying to
> shove it all into the drivers which just leads to a stack of pointless
> boilerplate when the driver isn't actually doing anything beyond the
> basic pattern of turning everything off when it goes idle and turning it
> on again when it needs to do something.  Having to open code that stuff
> in the drivers and then deal with the stubbing and error handling so the
> error handling in the drivers is painful.  There's also another axis
> where things aren't part of a SoC but are separate devices so you want
> to carry things along with the driver rather than have a separate bit of
> code which is required to glue things into the platform.

I agree. I'm thinking about the approach of adding helpers into the
PM runtime layer so state handling is centralized, while only the
event trigger goes into the driver. Basically it's just the implicit
triggers from pm_runtime_[get|put][[_sync] that is causing
problems.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH v3] pwm: vt8500: Update vt8500 PWM driver support
From: Thierry Reding @ 2012-10-24  5:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351050418-23981-1-git-send-email-linux@prisktech.co.nz>

On Wed, Oct 24, 2012 at 04:46:58PM +1300, Tony Prisk wrote:
> This patch updates pwm-vt8500.c to support devicetree probing and
> make use of the common clock subsystem.
> 
> A binding document describing the PWM controller found on
> arch-vt8500 is also included.
> 
> Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
> ---
> v2/v3:
> Fix errors/coding style as pointed out by Thierry Reding.
> 
>  .../devicetree/bindings/pwm/vt8500-pwm.txt         |   17 ++++
>  drivers/pwm/pwm-vt8500.c                           |   86 ++++++++++++++------
>  2 files changed, 80 insertions(+), 23 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/pwm/vt8500-pwm.txt

Looking real good now. One last comment though and I think I'm ready to
take this...

> +	err = clk_enable(vt8500->clk);
> +	if (err < 0)
> +		dev_err(chip->dev, "failed to enable clock\n");
> +		return -EBUSY;
> +	};

Why do you return EBUSY instead of err?

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121024/b14ec1cd/attachment.sig>

^ permalink raw reply

* [PATCH] gpio: mvebu: correctly set the value in direction_output()
From: Linus Walleij @ 2012-10-24  5:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350980225-6546-1-git-send-email-thomas.petazzoni@free-electrons.com>

On Tue, Oct 23, 2012 at 10:17 AM, Thomas Petazzoni
<thomas.petazzoni@free-electrons.com> wrote:

> The ->direction_output() operation of gpio_chip is supposed to set the
> direction to output but also to set the GPIO to an initial
> value. Unfortunately, this last part was not done until now, causing
> for example the LEDs to not be properly set to their default initial
> value. This patch fixes this by calling the mvebu_gpio_set() function
> from mvebu_gpio_direction_output() before configuring the GPIO as an
> output GPIO.
>
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
>
> ---
> As this is a fix, it should most likely go into 3.7.

Yes, thanks. Applied to my "fixes" branch.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH v5 5/5] ARM: EXYNOS: Add arm-pmu DT binding for exynos421x
From: Chanho Park @ 2012-10-24  5:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351056894-5790-1-git-send-email-chanho61.park@samsung.com>

This patch adds a arm-pmu node to bind device tree for exynos4210.
The exynos4210 and 4212 have two cpus which includes a pmu. In contrast, the
exynos4412 has 4 cpus and pmus. We need to define two more pmus for this type
board. However, supporting arm-pmu for the exynos4412 will handle it later
because there is no dts support for 4412 based board.

Signed-off-by: Chanho Park <chanho61.park@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/boot/dts/exynos4210.dtsi |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index 214c557..90f9aed 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -42,6 +42,12 @@
 			     <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>;
 	};
 
+	pmu {
+		compatible = "arm,cortex-a9-pmu";
+		interrupt-parent = <&combiner>;
+		interrupts = <2 2>, <3 2>;
+	};
+
 	pinctrl_0: pinctrl at 11400000 {
 		compatible = "samsung,pinctrl-exynos4210";
 		reg = <0x11400000 0x1000>;
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v5 4/5] ARM: EXYNOS: Add arm-pmu DT binding for exynos5250
From: Chanho Park @ 2012-10-24  5:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351056894-5790-1-git-send-email-chanho61.park@samsung.com>

This patch enables arm-pmu to bind device tree for exynos5250. The exynos5250
has two pmus which have combiner irq type.

Reviewed-by: Thomas Abraham <thomas.abraham@linaro.org>
Signed-off-by: Chanho Park <chanho61.park@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/boot/dts/exynos5250.dtsi |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index dddfd6e..fab3eae 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -56,6 +56,12 @@
 			     <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
 	};
 
+	pmu {
+		compatible = "arm,cortex-a15-pmu";
+		interrupt-parent = <&combiner>;
+		interrupts = <1 2>, <22 4>;
+	};
+
 	watchdog {
 		compatible = "samsung,s3c2410-wdt";
 		reg = <0x101D0000 0x100>;
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v5 3/5] ARM: EXYNOS: Enable PMUs for exynos4
From: Chanho Park @ 2012-10-24  5:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351056894-5790-1-git-send-email-chanho61.park@samsung.com>

This patch defines irq numbers of ARM performance monitoring unit for exynos4.
Firs of all, we need to fix IRQ_PMU correctly and to split pmu initialization
of exynos from plat-samsung for easily defining it.

The number of CPU cores and PMU irq numbers are vary according to soc types.
So, we need to identify each soc type using soc_is_xxx function and to define
the pmu irqs dynamically. For example, the exynos4412 has 4 cpu cores and pmus.

Signed-off-by: Chanho Park <chanho61.park@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-exynos/common.c            |   28 ++++++++++++++++++++++++++++
 arch/arm/mach-exynos/include/mach/irqs.h |    8 ++++++--
 arch/arm/plat-samsung/devs.c             |    2 +-
 3 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index 19a5460..071b0a6 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -35,6 +35,7 @@
 #include <mach/regs-pmu.h>
 #include <mach/regs-gpio.h>
 #include <mach/pmu.h>
+#include <mach/irqs.h>
 
 #include <plat/cpu.h>
 #include <plat/clock.h>
@@ -1087,3 +1088,30 @@ static int __init exynos_init_irq_eint(void)
 	return 0;
 }
 arch_initcall(exynos_init_irq_eint);
+
+static struct resource exynos4_pmu_resource[] = {
+	DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU),
+	DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU_CPU1),
+#if defined(CONFIG_SOC_EXYNOS4412)
+	DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU_CPU2),
+	DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU_CPU3),
+#endif
+};
+
+static struct platform_device exynos4_device_pmu = {
+	.name		= "arm-pmu",
+	.num_resources	= ARRAY_SIZE(exynos4_pmu_resource),
+	.resource	= exynos4_pmu_resource,
+};
+
+static int __init exynos_armpmu_init(void)
+{
+	if (!of_have_populated_dt()) {
+		if (soc_is_exynos4210() || soc_is_exynos4212())
+			exynos4_device_pmu.num_resources = 2;
+		platform_device_register(&exynos4_device_pmu);
+	}
+
+	return 0;
+}
+arch_initcall(exynos_armpmu_init);
diff --git a/arch/arm/mach-exynos/include/mach/irqs.h b/arch/arm/mach-exynos/include/mach/irqs.h
index e740a6f..0b75835 100644
--- a/arch/arm/mach-exynos/include/mach/irqs.h
+++ b/arch/arm/mach-exynos/include/mach/irqs.h
@@ -128,7 +128,7 @@
 #define EXYNOS4_IRQ_ADC1		IRQ_SPI(107)
 #define EXYNOS4_IRQ_PEN1		IRQ_SPI(108)
 #define EXYNOS4_IRQ_KEYPAD		IRQ_SPI(109)
-#define EXYNOS4_IRQ_PMU			IRQ_SPI(110)
+#define EXYNOS4_IRQ_POWER_PMU		IRQ_SPI(110)
 #define EXYNOS4_IRQ_GPS			IRQ_SPI(111)
 #define EXYNOS4_IRQ_INTFEEDCTRL_SSS	IRQ_SPI(112)
 #define EXYNOS4_IRQ_SLIMBUS		IRQ_SPI(113)
@@ -136,6 +136,11 @@
 #define EXYNOS4_IRQ_TSI			IRQ_SPI(115)
 #define EXYNOS4_IRQ_SATA		IRQ_SPI(116)
 
+#define EXYNOS4_IRQ_PMU			COMBINER_IRQ(2, 2)
+#define EXYNOS4_IRQ_PMU_CPU1		COMBINER_IRQ(3, 2)
+#define EXYNOS4_IRQ_PMU_CPU2		COMBINER_IRQ(18, 2)
+#define EXYNOS4_IRQ_PMU_CPU3		COMBINER_IRQ(19, 2)
+
 #define EXYNOS4_IRQ_SYSMMU_MDMA0_0	COMBINER_IRQ(4, 0)
 #define EXYNOS4_IRQ_SYSMMU_SSS_0	COMBINER_IRQ(4, 1)
 #define EXYNOS4_IRQ_SYSMMU_FIMC0_0	COMBINER_IRQ(4, 2)
@@ -233,7 +238,6 @@
 #define IRQ_TC				EXYNOS4_IRQ_PEN0
 
 #define IRQ_KEYPAD			EXYNOS4_IRQ_KEYPAD
-#define IRQ_PMU				EXYNOS4_IRQ_PMU
 
 #define IRQ_FIMD0_FIFO			EXYNOS4_IRQ_FIMD0_FIFO
 #define IRQ_FIMD0_VSYNC			EXYNOS4_IRQ_FIMD0_VSYNC
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index 03f654d..ace76b4 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -1125,7 +1125,7 @@ struct platform_device s5p_device_onenand = {
 
 /* PMU */
 
-#ifdef CONFIG_PLAT_S5P
+#if defined(CONFIG_PLAT_S5P) && !defined(CONFIG_ARCH_EXYNOS)
 static struct resource s5p_pmu_resource[] = {
 	DEFINE_RES_IRQ(IRQ_PMU)
 };
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v5 2/5] ARM: EXYNOS: Correct combined IRQs for exynos4
From: Chanho Park @ 2012-10-24  5:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351056894-5790-1-git-send-email-chanho61.park@samsung.com>

This patch corrects combined IRQs for exynos4 series platform. The exynos4412
has four extra combined irq group and the exynos4212 has two more combined irqs
than exynos4210. Each irq is mapped to IRQ_SPI(xx). Unfortunately, extra 4
combined IRQs isn't sequential. So, we need to map the irqs manually.

Signed-off-by: Chanho Park <chanho61.park@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-exynos/common.c            |   50 ++++++++++++++++++++++--------
 arch/arm/mach-exynos/include/mach/irqs.h |    5 ++-
 2 files changed, 41 insertions(+), 14 deletions(-)

diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index 709245e..19a5460 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -486,16 +486,22 @@ static struct irq_chip combiner_chip = {
 #endif
 };
 
-static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq)
+static unsigned int max_combiner_nr(void)
 {
-	unsigned int max_nr;
-
 	if (soc_is_exynos5250())
-		max_nr = EXYNOS5_MAX_COMBINER_NR;
+		return EXYNOS5_MAX_COMBINER_NR;
+	else if (soc_is_exynos4412())
+		return EXYNOS4412_MAX_COMBINER_NR;
+	else if (soc_is_exynos4212())
+		return EXYNOS4212_MAX_COMBINER_NR;
 	else
-		max_nr = EXYNOS4_MAX_COMBINER_NR;
+		return EXYNOS4210_MAX_COMBINER_NR;
+}
 
-	if (combiner_nr >= max_nr)
+static void __init combiner_cascade_irq(unsigned int combiner_nr,
+					unsigned int irq)
+{
+	if (combiner_nr >= max_combiner_nr())
 		BUG();
 	if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0)
 		BUG();
@@ -560,23 +566,38 @@ static struct irq_domain_ops combiner_irq_domain_ops = {
 	.map	= combiner_irq_domain_map,
 };
 
+static unsigned int exynos4x12_combiner_extra_irq(int group)
+{
+	switch (group) {
+	case 16:
+		return IRQ_SPI(107);
+	case 17:
+		return IRQ_SPI(108);
+	case 18:
+		return IRQ_SPI(48);
+	case 19:
+		return IRQ_SPI(42);
+	default:
+		return 0;
+	}
+}
+
 static void __init combiner_init(void __iomem *combiner_base,
 				 struct device_node *np)
 {
 	int i, irq, irq_base;
 	unsigned int max_nr, nr_irq;
 
+	max_nr = max_combiner_nr();
+
 	if (np) {
 		if (of_property_read_u32(np, "samsung,combiner-nr", &max_nr)) {
-			pr_warning("%s: number of combiners not specified, "
+			pr_info("%s: number of combiners not specified, "
 				"setting default as %d.\n",
-				__func__, EXYNOS4_MAX_COMBINER_NR);
-			max_nr = EXYNOS4_MAX_COMBINER_NR;
+				__func__, max_nr);
 		}
-	} else {
-		max_nr = soc_is_exynos5250() ? EXYNOS5_MAX_COMBINER_NR :
-						EXYNOS4_MAX_COMBINER_NR;
 	}
+
 	nr_irq = max_nr * MAX_IRQ_IN_COMBINER;
 
 	irq_base = irq_alloc_descs(COMBINER_IRQ(0, 0), 1, nr_irq, 0);
@@ -593,7 +614,10 @@ static void __init combiner_init(void __iomem *combiner_base,
 	}
 
 	for (i = 0; i < max_nr; i++) {
-		irq = IRQ_SPI(i);
+		if (i < EXYNOS4210_MAX_COMBINER_NR || soc_is_exynos5250())
+			irq = IRQ_SPI(i);
+		else
+			irq = exynos4x12_combiner_extra_irq(i);
 #ifdef CONFIG_OF
 		if (np)
 			irq = irq_of_parse_and_map(np, i);
diff --git a/arch/arm/mach-exynos/include/mach/irqs.h b/arch/arm/mach-exynos/include/mach/irqs.h
index 35bced6..e740a6f 100644
--- a/arch/arm/mach-exynos/include/mach/irqs.h
+++ b/arch/arm/mach-exynos/include/mach/irqs.h
@@ -165,7 +165,10 @@
 #define EXYNOS4_IRQ_FIMD0_VSYNC		COMBINER_IRQ(11, 1)
 #define EXYNOS4_IRQ_FIMD0_SYSTEM	COMBINER_IRQ(11, 2)
 
-#define EXYNOS4_MAX_COMBINER_NR		16
+#define EXYNOS4210_MAX_COMBINER_NR	16
+#define EXYNOS4212_MAX_COMBINER_NR	18
+#define EXYNOS4412_MAX_COMBINER_NR	20
+#define EXYNOS4_MAX_COMBINER_NR		EXYNOS4412_MAX_COMBINER_NR
 
 #define EXYNOS4_IRQ_GPIO1_NR_GROUPS	16
 #define EXYNOS4_IRQ_GPIO2_NR_GROUPS	9
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v5 1/5] ARM: EXYNOS: Add set_irq_affinity function for combiner_irq
From: Chanho Park @ 2012-10-24  5:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351056894-5790-1-git-send-email-chanho61.park@samsung.com>

This patch adds set_irq_affinity function for combiner_irq. We need this
function to enable a arm-pmu because the pmu of exynos has combined type irqs.

Reviewed-by: Thomas Abraham <thomas.abraham@linaro.org>
Signed-off-by: Chanho Park <chanho61.park@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-exynos/common.c |   30 +++++++++++++++++++++++++-----
 1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index 715b690..709245e 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -405,6 +405,7 @@ struct combiner_chip_data {
 	unsigned int irq_offset;
 	unsigned int irq_mask;
 	void __iomem *base;
+	unsigned int parent_irq;
 };
 
 static struct irq_domain *combiner_irq_domain;
@@ -461,10 +462,28 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
 	chained_irq_exit(chip, desc);
 }
 
+#ifdef CONFIG_SMP
+static int combiner_set_affinity(struct irq_data *d,
+				 const struct cpumask *mask_val, bool force)
+{
+	struct combiner_chip_data *chip_data = irq_data_get_irq_chip_data(d);
+	struct irq_chip *chip = irq_get_chip(chip_data->parent_irq);
+	struct irq_data *data = irq_get_irq_data(chip_data->parent_irq);
+
+	if (chip && chip->irq_set_affinity)
+		return chip->irq_set_affinity(data, mask_val, force);
+	else
+		return -EINVAL;
+}
+#endif
+
 static struct irq_chip combiner_chip = {
-	.name		= "COMBINER",
-	.irq_mask	= combiner_mask_irq,
-	.irq_unmask	= combiner_unmask_irq,
+	.name			= "COMBINER",
+	.irq_mask		= combiner_mask_irq,
+	.irq_unmask		= combiner_unmask_irq,
+#ifdef CONFIG_SMP
+	.irq_set_affinity	= combiner_set_affinity,
+#endif
 };
 
 static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq)
@@ -484,12 +503,13 @@ static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int i
 }
 
 static void __init combiner_init_one(unsigned int combiner_nr,
-				     void __iomem *base)
+				     void __iomem *base, unsigned int irq)
 {
 	combiner_data[combiner_nr].base = base;
 	combiner_data[combiner_nr].irq_offset = irq_find_mapping(
 		combiner_irq_domain, combiner_nr * MAX_IRQ_IN_COMBINER);
 	combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3);
+	combiner_data[combiner_nr].parent_irq = irq;
 
 	/* Disable all interrupts */
 	__raw_writel(combiner_data[combiner_nr].irq_mask,
@@ -573,12 +593,12 @@ static void __init combiner_init(void __iomem *combiner_base,
 	}
 
 	for (i = 0; i < max_nr; i++) {
-		combiner_init_one(i, combiner_base + (i >> 2) * 0x10);
 		irq = IRQ_SPI(i);
 #ifdef CONFIG_OF
 		if (np)
 			irq = irq_of_parse_and_map(np, i);
 #endif
+		combiner_init_one(i, combiner_base + (i >> 2) * 0x10, irq);
 		combiner_cascade_irq(i, irq);
 	}
 }
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v5 0/5] Add support to enable ARM PMU for EXYNOS
From: Chanho Park @ 2012-10-24  5:34 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset fixes irq numbers of ARM Performance Monitoring unit and enable
it for Perf(Performance Counter) on the exynos 4 and 5. The exynos4 and 5 have 2
more cpu cores which has its own pmu.

The exynos uses combiner-irq type for arm-pmu. Especially, the exynos4412 has 4
extra combined irq groups. So, we need to change a max combiner number and to
retreive it according to each soc types.

To enable perf, we need also to implement a set_irq_affinity function for the
combiner-irq. After applying this patch, we can use the perf for the exynos
machine.

Changes from v4:
 - Use max_combiner_nr() in combiner_cascade_irq
 - Add EXYNOS4412_MAX_COMBINER_NR to clarify a meaning
 - Change combiner_extra_irq to exynos4x12_combiner_extra_irq

Changes from v3:
 - Define max_combiner_nr according to soc types
 - Add armpmu dt binding for exynos4210
 - Clean up soc types comparison from v2

Changes from v2:
 - Convert to dt binding of exynos5250

Changes from v1:
 - Split arm-pmu init of exynos from plat-samsung
 - Correct combined irqs of exynos4412
 - Use soc_is_xxx function instead of CONFIG_XXX to identify dynamically

Chanho Park (5):
  ARM: EXYNOS: Add set_irq_affinity function for combiner_irq
  ARM: EXYNOS: Correct combined IRQs for exynos4
  ARM: EXYNOS: Enable PMUs for exynos4
  ARM: EXYNOS: Add arm-pmu DT binding for exynos5250
  ARM: EXYNOS: Add arm-pmu DT binding for exynos421x

 arch/arm/boot/dts/exynos4210.dtsi        |    6 ++
 arch/arm/boot/dts/exynos5250.dtsi        |    6 ++
 arch/arm/mach-exynos/common.c            |  108 +++++++++++++++++++++++++-----
 arch/arm/mach-exynos/include/mach/irqs.h |   13 +++-
 arch/arm/plat-samsung/devs.c             |    2 +-
 5 files changed, 113 insertions(+), 22 deletions(-)

-- 
1.7.9.5

^ permalink raw reply

* [PATCH] ARM: dma-mapping: fix build warning in __dma_alloc()
From: Jingoo Han @ 2012-10-24  5:09 UTC (permalink / raw)
  To: linux-arm-kernel

Fix build warning in __dma_alloc() as below:

arch/arm/mm/dma-mapping.c: In function '__dma_alloc':
arch/arm/mm/dma-mapping.c:653:29: warning: 'page' may be used uninitialized in this function [-Wuninitialized]

Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
 arch/arm/mm/dma-mapping.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 477a2d2..58bc3e4 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -610,7 +610,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
 			 gfp_t gfp, pgprot_t prot, bool is_coherent, const void *caller)
 {
 	u64 mask = get_coherent_dma_mask(dev);
-	struct page *page;
+	struct page *page = NULL;
 	void *addr;
 
 #ifdef CONFIG_DMA_API_DEBUG
-- 
1.7.1

^ permalink raw reply related

* Fwd: [PATCH 2/5] ARM: OMAP3+: hwmod: Add AM33XX HWMOD data for davinci_mdio
From: Richard Cochran @ 2012-10-24  5:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <79CD15C6BA57404B839C016229A409A83EB48592@DBDE01.ent.ti.com>

On Tue, Oct 23, 2012 at 10:12:29AM +0000, Hiremath, Vaibhav wrote:
> 
> I understand, and as you mentioned we are not fully there at v3.7-rc1 with 
> all the drivers/module support, due to all known reasons. Its good that with 
> v3.7-rc2, Beaglebone boots up out of box from mainline. 

Can you say whether we have working Ethernet on the beaglebone in v3.7?

Thanks,
Richard

^ permalink raw reply

* [PATCH v3] pwm: vt8500: Update vt8500 PWM driver support
From: Tony Prisk @ 2012-10-24  3:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121023221419.GA8501@avionic-0098.mockup.avionic-design.de>

On Wed, 2012-10-24 at 00:14 +0200, Thierry Reding wrote:
> On Tue, Oct 23, 2012 at 07:10:24AM +1300, Tony Prisk wrote:
> [...]
> > @@ -87,6 +98,11 @@ static int vt8500_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
> >  {
> >  	struct vt8500_chip *vt8500 = to_vt8500_chip(chip);
> >  
> > +	if (!clk_enable(vt8500->clk)) {
> > +		dev_err(chip->dev, "failed to enable clock\n");
> > +		return -EBUSY;
> > +	};
> > +
> 
> I don't think that works. The clock API returns 0 on success and a
> negative error code on failure. So this should rather be something like:
> 
> 	err = clk_enable(vt8500->clk);
> 	if (err < 0) {
> 		dev_err(chip->dev, "failed to enable clock: %d\n", err);
> 		return err;
> 	}
> 
> > @@ -123,6 +153,12 @@ static int __devinit pwm_probe(struct platform_device *pdev)
> >  	chip->chip.ops = &vt8500_pwm_ops;
> >  	chip->chip.base = -1;
> >  	chip->chip.npwm = VT8500_NR_PWMS;
> > +	chip->clk = devm_clk_get(&pdev->dev, NULL);
> > +
> 
> The blank line should go above the call to devm_clk_get().
> 
> > +	if (IS_ERR_OR_NULL(chip->clk)) {
> > +		dev_err(&pdev->dev, "clock source not specified\n");
> > +		return PTR_ERR(chip->clk);
> > +	}
> [...]
> > +	if (!clk_prepare(chip->clk)) {
> > +		dev_err(&pdev->dev, "failed to prepare clock\n");
> > +		return -EBUSY;
> > +	}
> > +
> 
> Same comment here. I wonder how this code can work, since if the clock
> is properly prepared, then it will return 0, and the above will return
> -EBUSY.
> 
> >  	ret = pwmchip_add(&chip->chip);
> > -	if (ret < 0)
> > +	if (ret < 0) {
> > +		dev_err(&pdev->dev, "failed to add pwmchip\n");
> 
> Error messages can be considered prose, so this should be: "failed to
> add PWM chip".
> 
> Thierry

I don't know why none of this caused a failure when boot tested. The
clock should have been disabled 'automagically' at bootup, and never
reenabled. *shrug* Fixed in new patch v3 (didn't notice there was
already a v3).

Regards
Tony P

^ permalink raw reply

* [PATCH v3] pwm: vt8500: Update vt8500 PWM driver support
From: Tony Prisk @ 2012-10-24  3:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121023221419.GA8501@avionic-0098.mockup.avionic-design.de>

This patch updates pwm-vt8500.c to support devicetree probing and
make use of the common clock subsystem.

A binding document describing the PWM controller found on
arch-vt8500 is also included.

Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
---
v2/v3:
Fix errors/coding style as pointed out by Thierry Reding.

 .../devicetree/bindings/pwm/vt8500-pwm.txt         |   17 ++++
 drivers/pwm/pwm-vt8500.c                           |   86 ++++++++++++++------
 2 files changed, 80 insertions(+), 23 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pwm/vt8500-pwm.txt

diff --git a/Documentation/devicetree/bindings/pwm/vt8500-pwm.txt b/Documentation/devicetree/bindings/pwm/vt8500-pwm.txt
new file mode 100644
index 0000000..bcc6367
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/vt8500-pwm.txt
@@ -0,0 +1,17 @@
+VIA/Wondermedia VT8500/WM8xxx series SoC PWM controller
+
+Required properties:
+- compatible: should be "via,vt8500-pwm"
+- reg: physical base address and length of the controller's registers
+- #pwm-cells: should be 2.  The first cell specifies the per-chip index
+  of the PWM to use and the second cell is the period in nanoseconds.
+- clocks: phandle to the PWM source clock
+
+Example:
+
+pwm1: pwm at d8220000 {
+	#pwm-cells = <2>;
+	compatible = "via,vt8500-pwm";
+	reg = <0xd8220000 0x1000>;
+	clocks = <&clkpwm>;
+};
diff --git a/drivers/pwm/pwm-vt8500.c b/drivers/pwm/pwm-vt8500.c
index ad14389..2ecd70f 100644
--- a/drivers/pwm/pwm-vt8500.c
+++ b/drivers/pwm/pwm-vt8500.c
@@ -1,7 +1,8 @@
 /*
  * drivers/pwm/pwm-vt8500.c
  *
- *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -21,14 +22,24 @@
 #include <linux/io.h>
 #include <linux/pwm.h>
 #include <linux/delay.h>
+#include <linux/clk.h>
 
 #include <asm/div64.h>
 
-#define VT8500_NR_PWMS 4
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+
+/*
+ * SoC architecture allocates register space for 4 PWMs but only
+ * 2 are currently implemented.
+ */
+#define VT8500_NR_PWMS	2
 
 struct vt8500_chip {
 	struct pwm_chip chip;
 	void __iomem *base;
+	struct clk *clk;
 };
 
 #define to_vt8500_chip(chip)	container_of(chip, struct vt8500_chip, chip)
@@ -52,7 +63,7 @@ static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	unsigned long long c;
 	unsigned long period_cycles, prescale, pv, dc;
 
-	c = 25000000/2; /* wild guess --- need to implement clocks */
+	c = clk_get_rate(vt8500->clk);
 	c = c * period_ns;
 	do_div(c, 1000000000);
 	period_cycles = c;
@@ -85,8 +96,15 @@ static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 
 static int vt8500_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
+	int err;
 	struct vt8500_chip *vt8500 = to_vt8500_chip(chip);
 
+	err = clk_enable(vt8500->clk);
+	if (err < 0)
+		dev_err(chip->dev, "failed to enable clock\n");
+		return -EBUSY;
+	};
+
 	pwm_busy_wait(vt8500->base + 0x40 + pwm->hwpwm, (1 << 0));
 	writel(5, vt8500->base + (pwm->hwpwm << 4));
 	return 0;
@@ -98,6 +116,8 @@ static void vt8500_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 
 	pwm_busy_wait(vt8500->base + 0x40 + pwm->hwpwm, (1 << 0));
 	writel(0, vt8500->base + (pwm->hwpwm << 4));
+
+	clk_disable(vt8500->clk);
 }
 
 static struct pwm_ops vt8500_pwm_ops = {
@@ -107,12 +127,24 @@ static struct pwm_ops vt8500_pwm_ops = {
 	.owner = THIS_MODULE,
 };
 
-static int __devinit pwm_probe(struct platform_device *pdev)
+static const struct of_device_id vt8500_pwm_dt_ids[] = {
+	{ .compatible = "via,vt8500-pwm", },
+	{ /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, vt8500_pwm_dt_ids);
+
+static int vt8500_pwm_probe(struct platform_device *pdev)
 {
 	struct vt8500_chip *chip;
 	struct resource *r;
+	struct device_node *np = pdev->dev.of_node;
 	int ret;
 
+	if (!np) {
+		dev_err(&pdev->dev, "invalid devicetree node\n");
+		return -EINVAL;
+	}
+
 	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL) {
 		dev_err(&pdev->dev, "failed to allocate memory\n");
@@ -124,6 +156,12 @@ static int __devinit pwm_probe(struct platform_device *pdev)
 	chip->chip.base = -1;
 	chip->chip.npwm = VT8500_NR_PWMS;
 
+	chip->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR_OR_NULL(chip->clk)) {
+		dev_err(&pdev->dev, "clock source not specified\n");
+		return PTR_ERR(chip->clk);
+	}
+
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (r == NULL) {
 		dev_err(&pdev->dev, "no memory resource defined\n");
@@ -131,18 +169,26 @@ static int __devinit pwm_probe(struct platform_device *pdev)
 	}
 
 	chip->base = devm_request_and_ioremap(&pdev->dev, r);
-	if (chip->base == NULL)
+	if (!chip->base)
 		return -EADDRNOTAVAIL;
 
+	ret = clk_prepare(chip->clk);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to prepare clock\n");
+		return ret;
+	}
+
 	ret = pwmchip_add(&chip->chip);
-	if (ret < 0)
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to add PWM chip\n");
 		return ret;
+	}
 
 	platform_set_drvdata(pdev, chip);
 	return ret;
 }
 
-static int __devexit pwm_remove(struct platform_device *pdev)
+static int vt8500_pwm_remove(struct platform_device *pdev)
 {
 	struct vt8500_chip *chip;
 
@@ -150,28 +196,22 @@ static int __devexit pwm_remove(struct platform_device *pdev)
 	if (chip == NULL)
 		return -ENODEV;
 
+	clk_unprepare(chip->clk);
+
 	return pwmchip_remove(&chip->chip);
 }
 
-static struct platform_driver pwm_driver = {
+static struct platform_driver vt8500_pwm_driver = {
+	.probe		= vt8500_pwm_probe,
+	.remove		= vt8500_pwm_remove,
 	.driver		= {
 		.name	= "vt8500-pwm",
 		.owner	= THIS_MODULE,
+		.of_match_table = vt8500_pwm_dt_ids,
 	},
-	.probe		= pwm_probe,
-	.remove		= __devexit_p(pwm_remove),
 };
+module_platform_driver(vt8500_pwm_driver);
 
-static int __init pwm_init(void)
-{
-	return platform_driver_register(&pwm_driver);
-}
-arch_initcall(pwm_init);
-
-static void __exit pwm_exit(void)
-{
-	platform_driver_unregister(&pwm_driver);
-}
-module_exit(pwm_exit);
-
-MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("VT8500 PWM Driver");
+MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>");
+MODULE_LICENSE("GPL v2");
-- 
1.7.9.5

^ permalink raw reply related

* pxa:spitz_pm.c: commit b6eede11 breaks spitz resume under certain conditions.
From: Eric Miao @ 2012-10-24  3:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAHod+GfMArh3BrnOTV4VWNWDONLwdyr6V69tTV-Fk53kpXu0Pg@mail.gmail.com>

On Tue, Oct 23, 2012 at 8:53 PM, Marko Kati? <dromede@gmail.com> wrote:
> On Tue, Oct 23, 2012 at 5:10 AM, Eric Miao <eric.y.miao@gmail.com> wrote:
>> On Fri, Oct 19, 2012 at 7:37 PM, Marko Kati? <dromede@gmail.com> wrote:
>>> On Thu, Oct 18, 2012 at 11:28 AM, Marko Kati? <dromede@gmail.com> wrote:
>>>>> Almost there, but I guess we could do this better and less confusing by having
>>>>> another array, e.g. tosa_gpio18_config[], which is tosa specific, and only
>>>>> initialize that MFP setting in the tosa path.
>>>>>
>>>>>>
>>>>>> I also looked at the original sharp kernel sources.
>>>>>> Only tosa used the RDY signal for it's tc6393tx chip, other machines simply
>>>>>> configured gpio18 as output in their suspend routines.
>>>>
>>>>
>>>> Actually, tosa doesn't use sharpsl_pm. Tosa uses the pda-power framework.
>>>> I said that only tosa uses the RDY signal to point out that we
>>>> probably don't need
>>>> the mfp-config line in postsuspend. That being said, i still think
>>>> that the array ordering
>>>> fix is adequate. Maybe later we may remove the mfp-config line from
>>>> postsuspend when
>>>> we're absolutely sure it isn't necessary for devices that use spitz_pm.c.
>>>
>>> So Eric what do you think, is the simple gpio array reordering patch
>>> an adequate fix for this bug?
>>
>> Sorry for late reply. That simple reordering still looks a bit confusing
>> to me, i.e. the same pin firstly configured as GPIO then RDY. Do we
>> have a less confusing way to fix this?
>
> well, we could also remove the mfp-config line in postsuspend. I
> suspect that it's only there because tosa was supposed to use
> sharpsl_pm and it currently doesn't (and certainly never will). And as
> i said, the original sharp kernels never did configure gpio 18 as RDY,
> except for tosa.

OK, please submit the patch for review.

^ permalink raw reply

* [PATCH 2/5] ARM: tegra: dts: add slink controller dt entry
From: Vinod Koul @ 2012-10-24  3:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50817820.6010301@wwwdotorg.org>

On Fri, 2012-10-19 at 09:56 -0600, Stephen Warren wrote:
> On 10/19/2012 03:10 AM, Laxman Dewangan wrote:
> > On Friday 19 October 2012 04:11 AM, Stephen Warren wrote:
> >> On 10/18/2012 04:56 AM, Laxman Dewangan wrote:
> >>> Add slink controller details in the dts file of
> >>> Tegra20 and Tegra30.
> >>> diff --git a/arch/arm/boot/dts/tegra20.dtsi
> >>> b/arch/arm/boot/dts/tegra20.dtsi
> >>> +    slink at 7000d400 {
> >>> +        compatible = "nvidia,tegra20-slink";
> >>> +        reg =<0x7000d400 0x200>;
> >>> +        interrupts =<0 59 0x04>;
> >>> +        nvidia,dma-req-sel =<15>;
> >
> 
> (Oh, you need a space before and after the = in all the lines above)
> 
> >> I thought the common DT DMA bindings were going to be in 3.7, and hence
> >> we could just use them here rather than inventing another custom
> >> property for this purpose?
> >
> > Adding Vinod here.
> > 
> > I looked the dma devicetree bingind document and did not found the
> > generic binding name. Howvere, for arm-pl330.txt, it is explained as ...
> 
> That's not the generic bindings. I guess they didn't get merged then. I
> guess we can continue with custom bindings until they are.
Yes they are in topic topic/dmaengine_dt in my tree. Will be merged once
we sort out slave apis.


-- 
Vinod Koul
Intel Corp.

^ permalink raw reply

* [PATCH v2 7/7] crypto: omap_sham: Remove usage of private DMA API
From: Mark A. Greer @ 2012-10-24  2:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351046167-4882-1-git-send-email-mgreer@animalcreek.com>

From: "Mark A. Greer" <mgreer@animalcreek.com>

Remove usage of the private OMAP DMA API.
The dmaengine API will be used instead.

CC: Russell King <rmk+kernel@arm.linux.org.uk>
CC: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 drivers/crypto/omap-sham.c | 117 ---------------------------------------------
 1 file changed, 117 deletions(-)

diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index c782f60..627f75e 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -13,8 +13,6 @@
  * Some ideas are from old omap-sha1-md5.c driver.
  */
 
-#define OMAP_SHAM_DMA_PRIVATE
-
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
 #include <linux/err.h>
@@ -29,10 +27,8 @@
 #include <linux/platform_device.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
-#ifndef OMAP_SHAM_DMA_PRIVATE
 #include <linux/dmaengine.h>
 #include <linux/omap-dma.h>
-#endif
 #include <linux/pm_runtime.h>
 #include <linux/delay.h>
 #include <linux/crypto.h>
@@ -43,12 +39,6 @@
 #include <crypto/hash.h>
 #include <crypto/internal/hash.h>
 
-#ifdef OMAP_SHAM_DMA_PRIVATE
-#include <plat/cpu.h>
-#include <plat/dma.h>
-#include <mach/irqs.h>
-#endif
-
 #define SHA_REG_DIGEST(x)		(0x00 + ((x) * 0x04))
 #define SHA_REG_DIN(x)			(0x1C + ((x) * 0x04))
 
@@ -120,9 +110,7 @@ struct omap_sham_reqctx {
 
 	/* walk state */
 	struct scatterlist	*sg;
-#ifndef OMAP_SHAM_DMA_PRIVATE
 	struct scatterlist	sgl;
-#endif
 	unsigned int		offset;	/* offset in current sg */
 	unsigned int		total;	/* total request */
 
@@ -156,12 +144,7 @@ struct omap_sham_dev {
 	int			irq;
 	spinlock_t		lock;
 	int			err;
-#ifdef OMAP_SHAM_DMA_PRIVATE
-	int			dma;
-	int			dma_lch;
-#else
 	struct dma_chan		*dma_lch;
-#endif
 	struct tasklet_struct	done_task;
 
 	unsigned long		flags;
@@ -329,7 +312,6 @@ static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, const u8 *buf,
 	return -EINPROGRESS;
 }
 
-#ifndef OMAP_SHAM_DMA_PRIVATE
 static void omap_sham_dma_callback(void *param)
 {
 	struct omap_sham_dev *dd = param;
@@ -337,34 +319,18 @@ static void omap_sham_dma_callback(void *param)
 	set_bit(FLAGS_DMA_READY, &dd->flags);
 	tasklet_schedule(&dd->done_task);
 }
-#endif
 
 static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr,
 			      size_t length, int final, int is_sg)
 {
 	struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
-#ifdef OMAP_SHAM_DMA_PRIVATE
-	int len32;
-#else
 	struct dma_async_tx_descriptor *tx;
 	struct dma_slave_config cfg;
 	int ret;
-#endif
 
 	dev_dbg(dd->dev, "xmit_dma: digcnt: %d, length: %d, final: %d\n",
 						ctx->digcnt, length, final);
 
-#ifdef OMAP_SHAM_DMA_PRIVATE
-	len32 = DIV_ROUND_UP(length, sizeof(u32));
-
-	omap_set_dma_transfer_params(dd->dma_lch, OMAP_DMA_DATA_TYPE_S32, len32,
-			1, OMAP_DMA_SYNC_PACKET, dd->dma,
-				OMAP_DMA_DST_SYNC_PREFETCH);
-
-	omap_set_dma_src_params(dd->dma_lch, 0, OMAP_DMA_AMODE_POST_INC,
-				dma_addr, 0, 0);
-
-#else
 	memset(&cfg, 0, sizeof(cfg));
 
 	cfg.dst_addr = dd->phys_base + SHA_REG_DIN(0);
@@ -404,7 +370,6 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr,
 
 	tx->callback = omap_sham_dma_callback;
 	tx->callback_param = dd;
-#endif
 
 	omap_sham_write_ctrl(dd, length, final, 1);
 
@@ -415,12 +380,8 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr,
 
 	set_bit(FLAGS_DMA_ACTIVE, &dd->flags);
 
-#ifdef OMAP_SHAM_DMA_PRIVATE
-	omap_start_dma(dd->dma_lch);
-#else
 	dmaengine_submit(tx);
 	dma_async_issue_pending(dd->dma_lch);
-#endif
 
 	return -EINPROGRESS;
 }
@@ -526,7 +487,6 @@ static int omap_sham_update_dma_start(struct omap_sham_dev *dd)
 	if (ctx->bufcnt || ctx->offset)
 		return omap_sham_update_dma_slow(dd);
 
-#ifndef OMAP_SHAM_DMA_PRIVATE
 	/*
 	 * Don't use the sg interface when the transfer size is less
 	 * than the number of elements in a DMA frame.  Otherwise,
@@ -535,7 +495,6 @@ static int omap_sham_update_dma_start(struct omap_sham_dev *dd)
 	 */
 	if (ctx->total < (DST_MAXBURST * sizeof(u32)))
 		return omap_sham_update_dma_slow(dd);
-#endif
 
 	dev_dbg(dd->dev, "fast: digcnt: %d, bufcnt: %u, total: %u\n",
 			ctx->digcnt, ctx->bufcnt, ctx->total);
@@ -597,11 +556,7 @@ static int omap_sham_update_dma_stop(struct omap_sham_dev *dd)
 {
 	struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
 
-#ifdef OMAP_SHAM_DMA_PRIVATE
-	omap_stop_dma(dd->dma_lch);
-#else
 	dmaengine_terminate_all(dd->dma_lch);
-#endif
 
 	if (ctx->flags & BIT(FLAGS_SG)) {
 		dma_unmap_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE);
@@ -803,18 +758,6 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd,
 	if (err)
 		goto err1;
 
-#ifdef OMAP_SHAM_DMA_PRIVATE
-	omap_set_dma_dest_params(dd->dma_lch, 0,
-			OMAP_DMA_AMODE_CONSTANT,
-			dd->phys_base + SHA_REG_DIN(0), 0, 16);
-
-	omap_set_dma_dest_burst_mode(dd->dma_lch,
-			OMAP_DMA_DATA_BURST_16);
-
-	omap_set_dma_src_burst_mode(dd->dma_lch,
-			OMAP_DMA_DATA_BURST_4);
-#endif
-
 	if (ctx->digcnt)
 		/* request has changed - restore hash */
 		omap_sham_copy_hash(req, 0);
@@ -1205,55 +1148,13 @@ static irqreturn_t omap_sham_irq(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-#ifdef OMAP_SHAM_DMA_PRIVATE
-static void omap_sham_dma_callback(int lch, u16 ch_status, void *data)
-{
-	struct omap_sham_dev *dd = data;
-
-	if (ch_status != OMAP_DMA_BLOCK_IRQ) {
-		pr_err("omap-sham DMA error status: 0x%hx\n", ch_status);
-		dd->err = -EIO;
-		clear_bit(FLAGS_INIT, &dd->flags);/* request to re-initialize */
-	}
-
-	set_bit(FLAGS_DMA_READY, &dd->flags);
-	tasklet_schedule(&dd->done_task);
-}
-
-static int omap_sham_dma_init(struct omap_sham_dev *dd)
-{
-	int err;
-
-	dd->dma_lch = -1;
-
-	err = omap_request_dma(dd->dma, dev_name(dd->dev),
-			omap_sham_dma_callback, dd, &dd->dma_lch);
-	if (err) {
-		dev_err(dd->dev, "Unable to request DMA channel\n");
-		return err;
-	}
-
-	return 0;
-}
-
-static void omap_sham_dma_cleanup(struct omap_sham_dev *dd)
-{
-	if (dd->dma_lch >= 0) {
-		omap_free_dma(dd->dma_lch);
-		dd->dma_lch = -1;
-	}
-}
-#endif
-
 static int __devinit omap_sham_probe(struct platform_device *pdev)
 {
 	struct omap_sham_dev *dd;
 	struct device *dev = &pdev->dev;
 	struct resource *res;
-#ifndef OMAP_SHAM_DMA_PRIVATE
 	dma_cap_mask_t mask;
 	unsigned dma_chan;
-#endif
 	int err, i, j;
 
 	dd = kzalloc(sizeof(struct omap_sham_dev), GFP_KERNEL);
@@ -1288,11 +1189,7 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
 		err = -ENODEV;
 		goto res_err;
 	}
-#ifdef OMAP_SHAM_DMA_PRIVATE
-	dd->dma = res->start;
-#else
 	dma_chan = res->start;
-#endif
 
 	/* Get the IRQ */
 	dd->irq = platform_get_irq(pdev,  0);
@@ -1309,11 +1206,6 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
 		goto res_err;
 	}
 
-#ifdef OMAP_SHAM_DMA_PRIVATE
-	err = omap_sham_dma_init(dd);
-	if (err)
-		goto dma_err;
-#else
 	dma_cap_zero(mask);
 	dma_cap_set(DMA_SLAVE, mask);
 
@@ -1324,7 +1216,6 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
 		err = -ENXIO;
 		goto dma_err;
 	}
-#endif
 
 	dd->io_base = ioremap(dd->phys_base, SZ_4K);
 	if (!dd->io_base) {
@@ -1358,11 +1249,7 @@ err_algs:
 	iounmap(dd->io_base);
 	pm_runtime_disable(dev);
 io_err:
-#ifdef OMAP_SHAM_DMA_PRIVATE
-	omap_sham_dma_cleanup(dd);
-#else
 	dma_release_channel(dd->dma_lch);
-#endif
 dma_err:
 	if (dd->irq >= 0)
 		free_irq(dd->irq, dd);
@@ -1392,11 +1279,7 @@ static int __devexit omap_sham_remove(struct platform_device *pdev)
 	iounmap(dd->io_base);
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
-#ifdef OMAP_SHAM_DMA_PRIVATE
-	omap_sham_dma_cleanup(dd);
-#else
 	dma_release_channel(dd->dma_lch);
-#endif
 	if (dd->irq >= 0)
 		free_irq(dd->irq, dd);
 	kfree(dd);
-- 
1.7.12

^ permalink raw reply related

* [PATCH v2 6/7] crypto: omap-sham: Add code to use dmaengine API
From: Mark A. Greer @ 2012-10-24  2:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351046167-4882-1-git-send-email-mgreer@animalcreek.com>

From: "Mark A. Greer" <mgreer@animalcreek.com>

Add code to use the new dmaengine API alongside
the existing DMA code that uses the private
OMAP DMA API.  The API to use is chosen by
defining or undefining 'OMAP_SHAM_DMA_PRIVATE'.

CC: Russell King <rmk+kernel@arm.linux.org.uk>
CC: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 drivers/crypto/omap-sham.c | 150 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 145 insertions(+), 5 deletions(-)

diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index acb85df..c782f60 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -13,6 +13,8 @@
  * Some ideas are from old omap-sha1-md5.c driver.
  */
 
+#define OMAP_SHAM_DMA_PRIVATE
+
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
 #include <linux/err.h>
@@ -27,6 +29,10 @@
 #include <linux/platform_device.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
+#ifndef OMAP_SHAM_DMA_PRIVATE
+#include <linux/dmaengine.h>
+#include <linux/omap-dma.h>
+#endif
 #include <linux/pm_runtime.h>
 #include <linux/delay.h>
 #include <linux/crypto.h>
@@ -37,9 +43,11 @@
 #include <crypto/hash.h>
 #include <crypto/internal/hash.h>
 
+#ifdef OMAP_SHAM_DMA_PRIVATE
 #include <plat/cpu.h>
 #include <plat/dma.h>
 #include <mach/irqs.h>
+#endif
 
 #define SHA_REG_DIGEST(x)		(0x00 + ((x) * 0x04))
 #define SHA_REG_DIN(x)			(0x1C + ((x) * 0x04))
@@ -47,6 +55,8 @@
 #define SHA1_MD5_BLOCK_SIZE		SHA1_BLOCK_SIZE
 #define MD5_DIGEST_SIZE			16
 
+#define	DST_MAXBURST			16 /* Really element number (en) */
+
 #define SHA_REG_DIGCNT			0x14
 
 #define SHA_REG_CTRL			0x18
@@ -110,6 +120,9 @@ struct omap_sham_reqctx {
 
 	/* walk state */
 	struct scatterlist	*sg;
+#ifndef OMAP_SHAM_DMA_PRIVATE
+	struct scatterlist	sgl;
+#endif
 	unsigned int		offset;	/* offset in current sg */
 	unsigned int		total;	/* total request */
 
@@ -143,8 +156,12 @@ struct omap_sham_dev {
 	int			irq;
 	spinlock_t		lock;
 	int			err;
+#ifdef OMAP_SHAM_DMA_PRIVATE
 	int			dma;
 	int			dma_lch;
+#else
+	struct dma_chan		*dma_lch;
+#endif
 	struct tasklet_struct	done_task;
 
 	unsigned long		flags;
@@ -312,15 +329,32 @@ static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, const u8 *buf,
 	return -EINPROGRESS;
 }
 
+#ifndef OMAP_SHAM_DMA_PRIVATE
+static void omap_sham_dma_callback(void *param)
+{
+	struct omap_sham_dev *dd = param;
+
+	set_bit(FLAGS_DMA_READY, &dd->flags);
+	tasklet_schedule(&dd->done_task);
+}
+#endif
+
 static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr,
-			      size_t length, int final)
+			      size_t length, int final, int is_sg)
 {
 	struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
+#ifdef OMAP_SHAM_DMA_PRIVATE
 	int len32;
+#else
+	struct dma_async_tx_descriptor *tx;
+	struct dma_slave_config cfg;
+	int ret;
+#endif
 
 	dev_dbg(dd->dev, "xmit_dma: digcnt: %d, length: %d, final: %d\n",
 						ctx->digcnt, length, final);
 
+#ifdef OMAP_SHAM_DMA_PRIVATE
 	len32 = DIV_ROUND_UP(length, sizeof(u32));
 
 	omap_set_dma_transfer_params(dd->dma_lch, OMAP_DMA_DATA_TYPE_S32, len32,
@@ -330,6 +364,48 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr,
 	omap_set_dma_src_params(dd->dma_lch, 0, OMAP_DMA_AMODE_POST_INC,
 				dma_addr, 0, 0);
 
+#else
+	memset(&cfg, 0, sizeof(cfg));
+
+	cfg.dst_addr = dd->phys_base + SHA_REG_DIN(0);
+	cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	cfg.dst_maxburst = DST_MAXBURST;
+
+	ret = dmaengine_slave_config(dd->dma_lch, &cfg);
+	if (ret) {
+		pr_err("omap-sham: can't configure dmaengine slave: %d\n", ret);
+		return ret;
+	}
+
+	if (is_sg) {
+		/*
+		 * The SG entry passed in may not have the 'length' member
+		 * set correctly so use a local SG entry (sgl) with the
+		 * proper value for 'length' instead.  If this is not done,
+		 * the dmaengine may try to DMA the incorrect amount of data.
+		 */
+		sg_init_table(&ctx->sgl, 1);
+		ctx->sgl.page_link = ctx->sg->page_link;
+		ctx->sgl.offset = ctx->sg->offset;
+		sg_dma_len(&ctx->sgl) = length;
+		sg_dma_address(&ctx->sgl) = sg_dma_address(ctx->sg);
+
+		tx = dmaengine_prep_slave_sg(dd->dma_lch, &ctx->sgl, 1,
+			DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	} else {
+		tx = dmaengine_prep_slave_single(dd->dma_lch, dma_addr, length,
+			DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	}
+
+	if (!tx) {
+		dev_err(dd->dev, "prep_slave_sg/single() failed\n");
+		return -EINVAL;
+	}
+
+	tx->callback = omap_sham_dma_callback;
+	tx->callback_param = dd;
+#endif
+
 	omap_sham_write_ctrl(dd, length, final, 1);
 
 	ctx->digcnt += length;
@@ -339,7 +415,12 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr,
 
 	set_bit(FLAGS_DMA_ACTIVE, &dd->flags);
 
+#ifdef OMAP_SHAM_DMA_PRIVATE
 	omap_start_dma(dd->dma_lch);
+#else
+	dmaengine_submit(tx);
+	dma_async_issue_pending(dd->dma_lch);
+#endif
 
 	return -EINPROGRESS;
 }
@@ -386,6 +467,8 @@ static int omap_sham_xmit_dma_map(struct omap_sham_dev *dd,
 					struct omap_sham_reqctx *ctx,
 					size_t length, int final)
 {
+	int ret;
+
 	ctx->dma_addr = dma_map_single(dd->dev, ctx->buffer, ctx->buflen,
 				       DMA_TO_DEVICE);
 	if (dma_mapping_error(dd->dev, ctx->dma_addr)) {
@@ -395,8 +478,12 @@ static int omap_sham_xmit_dma_map(struct omap_sham_dev *dd,
 
 	ctx->flags &= ~BIT(FLAGS_SG);
 
-	/* next call does not fail... so no unmap in the case of error */
-	return omap_sham_xmit_dma(dd, ctx->dma_addr, length, final);
+	ret = omap_sham_xmit_dma(dd, ctx->dma_addr, length, final, 0);
+	if (ret)
+		dma_unmap_single(dd->dev, ctx->dma_addr, ctx->buflen,
+				 DMA_TO_DEVICE);
+
+	return ret;
 }
 
 static int omap_sham_update_dma_slow(struct omap_sham_dev *dd)
@@ -431,6 +518,7 @@ static int omap_sham_update_dma_start(struct omap_sham_dev *dd)
 	struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
 	unsigned int length, final, tail;
 	struct scatterlist *sg;
+	int ret;
 
 	if (!ctx->total)
 		return 0;
@@ -438,6 +526,17 @@ static int omap_sham_update_dma_start(struct omap_sham_dev *dd)
 	if (ctx->bufcnt || ctx->offset)
 		return omap_sham_update_dma_slow(dd);
 
+#ifndef OMAP_SHAM_DMA_PRIVATE
+	/*
+	 * Don't use the sg interface when the transfer size is less
+	 * than the number of elements in a DMA frame.  Otherwise,
+	 * the dmaengine infrastructure will calculate that it needs
+	 * to transfer 0 frames which ultimately fails.
+	 */
+	if (ctx->total < (DST_MAXBURST * sizeof(u32)))
+		return omap_sham_update_dma_slow(dd);
+#endif
+
 	dev_dbg(dd->dev, "fast: digcnt: %d, bufcnt: %u, total: %u\n",
 			ctx->digcnt, ctx->bufcnt, ctx->total);
 
@@ -475,8 +574,11 @@ static int omap_sham_update_dma_start(struct omap_sham_dev *dd)
 
 	final = (ctx->flags & BIT(FLAGS_FINUP)) && !ctx->total;
 
-	/* next call does not fail... so no unmap in the case of error */
-	return omap_sham_xmit_dma(dd, sg_dma_address(ctx->sg), length, final);
+	ret = omap_sham_xmit_dma(dd, sg_dma_address(ctx->sg), length, final, 1);
+	if (ret)
+		dma_unmap_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE);
+
+	return ret;
 }
 
 static int omap_sham_update_cpu(struct omap_sham_dev *dd)
@@ -495,7 +597,12 @@ static int omap_sham_update_dma_stop(struct omap_sham_dev *dd)
 {
 	struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
 
+#ifdef OMAP_SHAM_DMA_PRIVATE
 	omap_stop_dma(dd->dma_lch);
+#else
+	dmaengine_terminate_all(dd->dma_lch);
+#endif
+
 	if (ctx->flags & BIT(FLAGS_SG)) {
 		dma_unmap_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE);
 		if (ctx->sg->length == ctx->offset) {
@@ -696,6 +803,7 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd,
 	if (err)
 		goto err1;
 
+#ifdef OMAP_SHAM_DMA_PRIVATE
 	omap_set_dma_dest_params(dd->dma_lch, 0,
 			OMAP_DMA_AMODE_CONSTANT,
 			dd->phys_base + SHA_REG_DIN(0), 0, 16);
@@ -705,6 +813,7 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd,
 
 	omap_set_dma_src_burst_mode(dd->dma_lch,
 			OMAP_DMA_DATA_BURST_4);
+#endif
 
 	if (ctx->digcnt)
 		/* request has changed - restore hash */
@@ -1096,6 +1205,7 @@ static irqreturn_t omap_sham_irq(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+#ifdef OMAP_SHAM_DMA_PRIVATE
 static void omap_sham_dma_callback(int lch, u16 ch_status, void *data)
 {
 	struct omap_sham_dev *dd = data;
@@ -1133,12 +1243,17 @@ static void omap_sham_dma_cleanup(struct omap_sham_dev *dd)
 		dd->dma_lch = -1;
 	}
 }
+#endif
 
 static int __devinit omap_sham_probe(struct platform_device *pdev)
 {
 	struct omap_sham_dev *dd;
 	struct device *dev = &pdev->dev;
 	struct resource *res;
+#ifndef OMAP_SHAM_DMA_PRIVATE
+	dma_cap_mask_t mask;
+	unsigned dma_chan;
+#endif
 	int err, i, j;
 
 	dd = kzalloc(sizeof(struct omap_sham_dev), GFP_KERNEL);
@@ -1173,7 +1288,11 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
 		err = -ENODEV;
 		goto res_err;
 	}
+#ifdef OMAP_SHAM_DMA_PRIVATE
 	dd->dma = res->start;
+#else
+	dma_chan = res->start;
+#endif
 
 	/* Get the IRQ */
 	dd->irq = platform_get_irq(pdev,  0);
@@ -1190,9 +1309,22 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
 		goto res_err;
 	}
 
+#ifdef OMAP_SHAM_DMA_PRIVATE
 	err = omap_sham_dma_init(dd);
 	if (err)
 		goto dma_err;
+#else
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+
+	dd->dma_lch = dma_request_channel(mask, omap_dma_filter_fn, &dma_chan);
+	if (!dd->dma_lch) {
+		dev_err(dev, "unable to obtain RX DMA engine channel %u\n",
+			dma_chan);
+		err = -ENXIO;
+		goto dma_err;
+	}
+#endif
 
 	dd->io_base = ioremap(dd->phys_base, SZ_4K);
 	if (!dd->io_base) {
@@ -1226,7 +1358,11 @@ err_algs:
 	iounmap(dd->io_base);
 	pm_runtime_disable(dev);
 io_err:
+#ifdef OMAP_SHAM_DMA_PRIVATE
 	omap_sham_dma_cleanup(dd);
+#else
+	dma_release_channel(dd->dma_lch);
+#endif
 dma_err:
 	if (dd->irq >= 0)
 		free_irq(dd->irq, dd);
@@ -1256,7 +1392,11 @@ static int __devexit omap_sham_remove(struct platform_device *pdev)
 	iounmap(dd->io_base);
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
+#ifdef OMAP_SHAM_DMA_PRIVATE
 	omap_sham_dma_cleanup(dd);
+#else
+	dma_release_channel(dd->dma_lch);
+#endif
 	if (dd->irq >= 0)
 		free_irq(dd->irq, dd);
 	kfree(dd);
-- 
1.7.12

^ permalink raw reply related

* [PATCH v2 5/7] crypto: omap-sham: Convert to use pm_runtime API
From: Mark A. Greer @ 2012-10-24  2:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351046167-4882-1-git-send-email-mgreer@animalcreek.com>

From: "Mark A. Greer" <mgreer@animalcreek.com>

Convert the omap-sham crypto driver to use the
pm_runtime API instead of the clk API.

CC: Kevin Hilman <khilman@deeprootsystems.com>
CC: Paul Walmsley <paul@pwsan.com>
CC: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 drivers/crypto/omap-sham.c | 25 +++++++------------------
 1 file changed, 7 insertions(+), 18 deletions(-)

diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index a3fd6fc..acb85df 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -22,12 +22,12 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
-#include <linux/clk.h>
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
+#include <linux/pm_runtime.h>
 #include <linux/delay.h>
 #include <linux/crypto.h>
 #include <linux/cryptohash.h>
@@ -141,7 +141,6 @@ struct omap_sham_dev {
 	struct device		*dev;
 	void __iomem		*io_base;
 	int			irq;
-	struct clk		*iclk;
 	spinlock_t		lock;
 	int			err;
 	int			dma;
@@ -238,8 +237,6 @@ static void omap_sham_copy_ready_hash(struct ahash_request *req)
 
 static int omap_sham_hw_init(struct omap_sham_dev *dd)
 {
-	clk_enable(dd->iclk);
-
 	if (!test_bit(FLAGS_INIT, &dd->flags)) {
 		omap_sham_write_mask(dd, SHA_REG_MASK,
 			SHA_REG_MASK_SOFTRESET, SHA_REG_MASK_SOFTRESET);
@@ -653,7 +650,6 @@ static void omap_sham_finish_req(struct ahash_request *req, int err)
 	/* atomic operation is not needed here */
 	dd->flags &= ~(BIT(FLAGS_BUSY) | BIT(FLAGS_FINAL) | BIT(FLAGS_CPU) |
 			BIT(FLAGS_DMA_READY) | BIT(FLAGS_OUTPUT_READY));
-	clk_disable(dd->iclk);
 
 	if (req->base.complete)
 		req->base.complete(&req->base, err);
@@ -1198,14 +1194,6 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
 	if (err)
 		goto dma_err;
 
-	/* Initializing the clock */
-	dd->iclk = clk_get(dev, "ick");
-	if (IS_ERR(dd->iclk)) {
-		dev_err(dev, "clock intialization failed.\n");
-		err = PTR_ERR(dd->iclk);
-		goto clk_err;
-	}
-
 	dd->io_base = ioremap(dd->phys_base, SZ_4K);
 	if (!dd->io_base) {
 		dev_err(dev, "can't ioremap\n");
@@ -1213,11 +1201,12 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
 		goto io_err;
 	}
 
-	clk_enable(dd->iclk);
+	pm_runtime_enable(dev);
+	pm_runtime_get_sync(dev);
+
 	dev_info(dev, "hw accel on OMAP rev %u.%u\n",
 		(omap_sham_read(dd, SHA_REG_REV) & SHA_REG_REV_MAJOR) >> 4,
 		omap_sham_read(dd, SHA_REG_REV) & SHA_REG_REV_MINOR);
-	clk_disable(dd->iclk);
 
 	spin_lock(&sham.lock);
 	list_add_tail(&dd->list, &sham.dev_list);
@@ -1235,9 +1224,8 @@ err_algs:
 	for (j = 0; j < i; j++)
 		crypto_unregister_ahash(&algs[j]);
 	iounmap(dd->io_base);
+	pm_runtime_disable(dev);
 io_err:
-	clk_put(dd->iclk);
-clk_err:
 	omap_sham_dma_cleanup(dd);
 dma_err:
 	if (dd->irq >= 0)
@@ -1266,7 +1254,8 @@ static int __devexit omap_sham_remove(struct platform_device *pdev)
 		crypto_unregister_ahash(&algs[i]);
 	tasklet_kill(&dd->done_task);
 	iounmap(dd->io_base);
-	clk_put(dd->iclk);
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
 	omap_sham_dma_cleanup(dd);
 	if (dd->irq >= 0)
 		free_irq(dd->irq, dd);
-- 
1.7.12

^ permalink raw reply related

* [PATCH v2 4/7] ARM: OMAP2+: Remove unnecessary message when no SHA IP is present
From: Mark A. Greer @ 2012-10-24  2:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351046167-4882-1-git-send-email-mgreer@animalcreek.com>

From: "Mark A. Greer" <mgreer@animalcreek.com>

Remove the error message that prints when there is no SHA IP
present to make it consistent with all the other IPs.

CC: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/devices.c | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index f38ac9d..f41c793 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -456,20 +456,15 @@ static void omap_init_rng(void)
 
 static void __init omap_init_sham(void)
 {
-	if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
-		struct omap_hwmod *oh;
-		struct platform_device *pdev;
+	struct omap_hwmod *oh;
+	struct platform_device *pdev;
 
-		oh = omap_hwmod_lookup("sham");
-		if (!oh)
-			return;
+	oh = omap_hwmod_lookup("sham");
+	if (!oh)
+		return;
 
-		pdev = omap_device_build("omap-sham", -1, oh, NULL, 0, NULL,
-					 0, 0);
-		WARN(IS_ERR(pdev), "Can't build omap_device for omap-sham\n");
-	} else {
-		pr_err("%s: platform not supported\n", __func__);
-	}
+	pdev = omap_device_build("omap-sham", -1, oh, NULL, 0, NULL, 0, 0);
+	WARN(IS_ERR(pdev), "Can't build omap_device for omap-sham\n");
 }
 
 #if defined(CONFIG_CRYPTO_DEV_OMAP_AES) || defined(CONFIG_CRYPTO_DEV_OMAP_AES_MODULE)
-- 
1.7.12

^ permalink raw reply related


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