* [PATCH] i2c: omap: Move the remove constraint
From: Jean Pihet @ 2012-11-14 11:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121114105734.GE5954@pengutronix.de>
Hi Wolfram, Shubhrajyoti,
On Wed, Nov 14, 2012 at 11:57 AM, Wolfram Sang <w.sang@pengutronix.de> wrote:
>
>> > Currently we just queue the transfer and release the
>> > qos constraints, however we donot wait for the transfer
>> > to complete to release the constraint. Move the remove
>> > constraint after the bus busy as we are sure that the
>> > transfers are completed by then.
>> >
>> > Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
>>
>> Good catch, the change definitely makes sense. Feel free to add:
>>
>> Acked-by: Jean Pihet <j-pihet@ti.com>
>
> Since I just reverted the QoS patch, I suppose this gets merged into the
> original patch when resent?
The best for now is to re-submit a new patch that moves the constraint
release in the original code. Later the PM QoS patch will be applied
on the new code base.
What do you think? I can provide a patch if needed.
Regards,
Jean
>
> --
> Pengutronix e.K. | Wolfram Sang |
> Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* [PATCH 1/2] arm/mm: L2CC shared mutex with ARM TZ
From: Etienne CARRIERE ST @ 2012-11-14 11:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121114105049.GI3290@n2100.arm.linux.org.uk>
> > Thanks for notifying. I will look at the recent release to see if our
> > architecture complies with Kernel code.
> >
> > Our mutex implementation is based on 0/1 lock/unlock value in target
> > mutex DDR cell.
>
> Right, so we have another bug here: it is incompatible with the current ARM
> spinlock implementation - and using it on the same memory location as a
> spinlock will corrupt the spinlock.
Right.
I see our architecture complies with kernels before v3.6-rc1.
Until then, it seems we can use our patch, but we must plan something else for the more recent kernels.
etienne
^ permalink raw reply
* [PATCH] Revert "ARM: OMAP: convert I2C driver to PM QoS for MPU latency constraints"
From: Jean Pihet @ 2012-11-14 11:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121114105102.GD5954@pengutronix.de>
Hi Wolfram,
On Wed, Nov 14, 2012 at 11:51 AM, Wolfram Sang <w.sang@pengutronix.de> wrote:
> On Tue, Nov 06, 2012 at 04:31:32PM +0000, Paul Walmsley wrote:
>>
>> This reverts commit 3db11feffc1ad2ab9dea27789e6b5b3032827adc.
>
> Here giving the patch name in parens would have really made sense.
> Will fix that.
The title is "ARM: OMAP: convert I2C driver to PM QoS for MPU latency
constraints".
>
>> This commit causes I2C timeouts to appear on several OMAP3430/3530-based
>> boards:
>>
>> http://marc.info/?l=linux-arm-kernel&m=135071372426971&w=2
>> http://marc.info/?l=linux-arm-kernel&m=135067558415214&w=2
>> http://marc.info/?l=linux-arm-kernel&m=135216013608196&w=2
There is no formal piecof evidence that the commit is the cause of it.
>>
>> and appears to have been sent for merging before one of its prerequisites
>> was merged:
However this is correct. My fault ;-|
>>
>> http://marc.info/?l=linux-arm-kernel&m=135219411617621&w=2
>
> Hmm, any ideas how to avoid such things in the future?
The only way is to figure out the dependencies with other features. In
this case I overlooked them and assumed some other features were
already merged in. Will take care next time.
>
>> Signed-off-by: Paul Walmsley <paul@pwsan.com>
>
> Applied to for-current, thanks!
Thanks!
Jean
>
> --
> Pengutronix e.K. | Wolfram Sang |
> Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* [PATCH] i2c: omap: Move the remove constraint
From: Wolfram Sang @ 2012-11-14 10:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAORVsuW_VAiemnauUs-yW+GcQpv+qpESP4kzyQm=Unmofa4k_Q@mail.gmail.com>
> > Currently we just queue the transfer and release the
> > qos constraints, however we donot wait for the transfer
> > to complete to release the constraint. Move the remove
> > constraint after the bus busy as we are sure that the
> > transfers are completed by then.
> >
> > Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
>
> Good catch, the change definitely makes sense. Feel free to add:
>
> Acked-by: Jean Pihet <j-pihet@ti.com>
Since I just reverted the QoS patch, I suppose this gets merged into the
original patch when resent?
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121114/8507c2cb/attachment-0001.sig>
^ permalink raw reply
* [PATCH] Revert "ARM: OMAP: convert I2C driver to PM QoS for MPU latency constraints"
From: Wolfram Sang @ 2012-11-14 10:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.DEB.2.00.1211061619461.20573@utopia.booyaka.com>
On Tue, Nov 06, 2012 at 04:31:32PM +0000, Paul Walmsley wrote:
>
> This reverts commit 3db11feffc1ad2ab9dea27789e6b5b3032827adc.
Here giving the patch name in parens would have really made sense.
Will fix that.
> This commit causes I2C timeouts to appear on several OMAP3430/3530-based
> boards:
>
> http://marc.info/?l=linux-arm-kernel&m=135071372426971&w=2
> http://marc.info/?l=linux-arm-kernel&m=135067558415214&w=2
> http://marc.info/?l=linux-arm-kernel&m=135216013608196&w=2
>
> and appears to have been sent for merging before one of its prerequisites
> was merged:
>
> http://marc.info/?l=linux-arm-kernel&m=135219411617621&w=2
Hmm, any ideas how to avoid such things in the future?
> Signed-off-by: Paul Walmsley <paul@pwsan.com>
Applied to for-current, thanks!
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121114/51cce6bc/attachment.sig>
^ permalink raw reply
* [PATCH 1/2] arm/mm: L2CC shared mutex with ARM TZ
From: Russell King - ARM Linux @ 2012-11-14 10:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <0154077FE026E54BB093CA7EB3FD1AE32DB61E4D23@SAFEX1MAIL3.st.com>
On Wed, Nov 14, 2012 at 11:45:42AM +0100, Etienne CARRIERE ST wrote:
> Thanks for notifying. I will look at the recent release to see if our
> architecture complies with Kernel code.
>
> Our mutex implementation is based on 0/1 lock/unlock value in target
> mutex DDR cell.
Right, so we have another bug here: it is incompatible with the current
ARM spinlock implementation - and using it on the same memory location
as a spinlock will corrupt the spinlock.
^ permalink raw reply
* [PATCH 1/2] arm/mm: L2CC shared mutex with ARM TZ
From: Etienne CARRIERE ST @ 2012-11-14 10:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121114102127.GH3290@n2100.arm.linux.org.uk>
> Sent: Wednesday, November 14, 2012 11:21 AM
> From: Russell King - ARM Linux [mailto:linux at arm.linux.org.uk]
>
> > > Right, so, what this tells me is that the implementation of the
> > > spinlock in the secure software is potentially the same as the
> > > kernel's spinlock.
> > > The kernel's spinlock implementation is GPL'd. If the secure side
> > > spinlock implementation is a copy of the kernel's spinlock
> > > implementation, then that implementation is also GPL'd (...).
> > >
> > > I think someone has some explaining to do.
> >
> > It does.
> >
> > The TZ implementation of the shared mutex is the ARM native mutex
> > instructions set LDREX/STREX, protected by a native ARM IRQ disabling.
> > I believe this is native ARMv7 natural handling and not subject to
> > GPLization.
>
> Maybe, maybe not. There's more to locking than just the instructions used
> - there's the values which are used to represent "locked" and "unlocked",
> and then there's the ticket locking implementation found in recent kernels
> which defines the value to have more meaning than just "locked" and "unlocked".
>
> With ticket locking, you need to know the details of the implementation to be
> able to lock successfully, and that basically means copying the implementation.
Thanks for notifying. I will look at the recent release to see if our architecture complies with Kernel code.
Our mutex implementation is based on 0/1 lock/unlock value in target mutex DDR cell.
etienne
^ permalink raw reply
* [PATCH v8 3/3] ARM: EXYNOS: Enabling samsung-usbphy driver for EXYNOS4210
From: Praveen Paneri @ 2012-11-14 10:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352889938-17311-1-git-send-email-p.paneri@samsung.com>
Adding usbphy node for Exynos4210 along with the platform data.
Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
---
arch/arm/boot/dts/exynos4210-smdkv310.dts | 5 +++++
arch/arm/mach-exynos/Kconfig | 1 +
arch/arm/mach-exynos/include/mach/map.h | 1 +
arch/arm/mach-exynos/mach-exynos4-dt.c | 8 ++++++++
arch/arm/mach-exynos/setup-usb-phy.c | 13 +++++++++++++
5 files changed, 28 insertions(+), 0 deletions(-)
diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts
index 9b23a82..550903a 100644
--- a/arch/arm/boot/dts/exynos4210-smdkv310.dts
+++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts
@@ -59,6 +59,11 @@
status = "okay";
};
+ usbphy at 125B0000 {
+ compatible = "samsung,exynos4210-usbphy";
+ reg = <0x125B0000 0x100>;
+ };
+
keypad at 100A0000 {
samsung,keypad-num-rows = <2>;
samsung,keypad-num-columns = <8>;
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index bb3b09a..315308c 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -410,6 +410,7 @@ config MACH_EXYNOS4_DT
select PINCTRL
select PINCTRL_EXYNOS4
select USE_OF
+ select EXYNOS4_SETUP_USB_PHY
help
Machine support for Samsung Exynos4 machine with device tree enabled.
Select this if a fdt blob is available for the Exynos4 SoC based board.
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index ef4958b..e64fe1c 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -244,6 +244,7 @@
#define S3C_PA_SPI1 EXYNOS4_PA_SPI1
#define S3C_PA_SPI2 EXYNOS4_PA_SPI2
#define S3C_PA_USB_HSOTG EXYNOS4_PA_HSOTG
+#define S3C_PA_USB_PHY EXYNOS4_PA_HSPHY
#define S5P_PA_EHCI EXYNOS4_PA_EHCI
#define S5P_PA_FIMC0 EXYNOS4_PA_FIMC0
diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c
index 8858068..f7887e5 100644
--- a/arch/arm/mach-exynos/mach-exynos4-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos4-dt.c
@@ -13,6 +13,7 @@
#include <linux/of_platform.h>
#include <linux/serial_core.h>
+#include <linux/platform_data/samsung-usbphy.h>
#include <asm/mach/arch.h>
#include <asm/hardware/gic.h>
@@ -20,9 +21,14 @@
#include <plat/cpu.h>
#include <plat/regs-serial.h>
+#include <plat/usb-phy.h>
#include "common.h"
+static struct samsung_usbphy_data exynos4_usbphy_pdata = {
+ .pmu_isolation = s5p_usb_phy_pmu_isolation,
+};
+
/*
* The following lookup table is used to override device names when devices
* are registered from device tree. This is temporarily added to enable
@@ -79,6 +85,8 @@ static const struct of_dev_auxdata exynos4_auxdata_lookup[] __initconst = {
OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA1, "dma-pl330.1", NULL),
OF_DEV_AUXDATA("samsung,exynos4210-tmu", EXYNOS4_PA_TMU,
"exynos-tmu", NULL),
+ OF_DEV_AUXDATA("samsung,exynos4210-usbphy", EXYNOS4_PA_HSPHY,
+ "s3c-usbphy", &exynos4_usbphy_pdata),
{},
};
diff --git a/arch/arm/mach-exynos/setup-usb-phy.c b/arch/arm/mach-exynos/setup-usb-phy.c
index b81cc56..1c62d20 100644
--- a/arch/arm/mach-exynos/setup-usb-phy.c
+++ b/arch/arm/mach-exynos/setup-usb-phy.c
@@ -221,3 +221,16 @@ int s5p_usb_phy_exit(struct platform_device *pdev, int type)
return -EINVAL;
}
+
+void s5p_usb_phy_pmu_isolation(int on)
+{
+ if (on) {
+ writel(readl(S5P_USBDEVICE_PHY_CONTROL)
+ & ~S5P_USBDEVICE_PHY_ENABLE,
+ S5P_USBDEVICE_PHY_CONTROL);
+ } else {
+ writel(readl(S5P_USBDEVICE_PHY_CONTROL)
+ | S5P_USBDEVICE_PHY_ENABLE,
+ S5P_USBDEVICE_PHY_CONTROL);
+ }
+}
--
1.7.1
^ permalink raw reply related
* [PATCH v8 2/3] ARM: S3C64XX: Enabling samsung-usbphy driver
From: Praveen Paneri @ 2012-11-14 10:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352889938-17311-1-git-send-email-p.paneri@samsung.com>
Adding platform device for samsung-usbphy driver. Enabling it for
s3c64xx based machines using s3c-hsotg.
Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
---
arch/arm/mach-s3c64xx/include/mach/map.h | 2 +
arch/arm/mach-s3c64xx/mach-crag6410.c | 7 ++++++
arch/arm/mach-s3c64xx/mach-smartq.c | 8 +++++++
arch/arm/mach-s3c64xx/mach-smdk6410.c | 7 ++++++
arch/arm/mach-s3c64xx/setup-usb-phy.c | 14 +++++++++++++
arch/arm/plat-samsung/devs.c | 28 ++++++++++++++++++++++++++
arch/arm/plat-samsung/include/plat/devs.h | 1 +
arch/arm/plat-samsung/include/plat/usb-phy.h | 1 +
8 files changed, 68 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-s3c64xx/include/mach/map.h b/arch/arm/mach-s3c64xx/include/mach/map.h
index 8e2097b..dc482bb 100644
--- a/arch/arm/mach-s3c64xx/include/mach/map.h
+++ b/arch/arm/mach-s3c64xx/include/mach/map.h
@@ -65,6 +65,7 @@
#define S3C64XX_PA_NAND (0x70200000)
#define S3C64XX_PA_FB (0x77100000)
+#define S3C64XX_PA_USB_HSPHY (0x7C100000)
#define S3C64XX_PA_USB_HSOTG (0x7C000000)
#define S3C64XX_PA_WATCHDOG (0x7E004000)
#define S3C64XX_PA_RTC (0x7E005000)
@@ -113,6 +114,7 @@
#define S3C_PA_FB S3C64XX_PA_FB
#define S3C_PA_USBHOST S3C64XX_PA_USBHOST
#define S3C_PA_USB_HSOTG S3C64XX_PA_USB_HSOTG
+#define S3C_PA_USB_PHY S3C64XX_PA_USB_HSPHY
#define S3C_PA_RTC S3C64XX_PA_RTC
#define S3C_PA_WDT S3C64XX_PA_WATCHDOG
#define S3C_PA_SPI0 S3C64XX_PA_SPI0
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index 48f4a2d..c602379 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -31,6 +31,7 @@
#include <linux/spi/spi.h>
#include <linux/i2c/pca953x.h>
+#include <linux/platform_data/samsung-usbphy.h>
#include <video/platform_lcd.h>
@@ -69,6 +70,7 @@
#include <plat/adc.h>
#include <linux/platform_data/i2c-s3c2410.h>
#include <plat/pm.h>
+#include <plat/usb-phy.h>
#include "common.h"
@@ -353,6 +355,7 @@ static struct platform_device wallvdd_device = {
};
static struct platform_device *crag6410_devices[] __initdata = {
+ &samsung_device_usbphy,
&s3c_device_hsmmc0,
&s3c_device_hsmmc2,
&s3c_device_i2c0,
@@ -804,6 +807,9 @@ static const struct gpio_led_platform_data gpio_leds_pdata = {
.num_leds = ARRAY_SIZE(gpio_leds),
};
+static struct samsung_usbphy_data crag6410_usbphy_pdata __initdata = {
+ .pmu_isolation = s5p_usb_phy_pmu_isolation,
+};
static void __init crag6410_machine_init(void)
{
@@ -829,6 +835,7 @@ static void __init crag6410_machine_init(void)
s3c_i2c0_set_platdata(&i2c0_pdata);
s3c_i2c1_set_platdata(&i2c1_pdata);
s3c_fb_set_platdata(&crag6410_lcd_pdata);
+ samsung_usbphy_set_pdata(&crag6410_usbphy_pdata);
i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c
index 59bb34c..f18a0ab 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq.c
@@ -18,6 +18,7 @@
#include <linux/serial_core.h>
#include <linux/spi/spi_gpio.h>
#include <linux/usb/gpio_vbus.h>
+#include <linux/platform_data/samsung-usbphy.h>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
@@ -36,6 +37,7 @@
#include <linux/platform_data/usb-ohci-s3c2410.h>
#include <plat/sdhci.h>
#include <linux/platform_data/touchscreen-s3c2410.h>
+#include <plat/usb-phy.h>
#include <video/platform_lcd.h>
@@ -234,6 +236,7 @@ static struct i2c_board_info smartq_i2c_devs[] __initdata = {
};
static struct platform_device *smartq_devices[] __initdata = {
+ &samsung_device_usbphy,
&s3c_device_hsmmc1, /* Init iNAND first, ... */
&s3c_device_hsmmc0, /* ... then the external SD card */
&s3c_device_hsmmc2,
@@ -380,9 +383,14 @@ void __init smartq_map_io(void)
smartq_lcd_mode_set();
}
+static struct samsung_usbphy_data smartq_usbphy_pdata __initdata = {
+ .pmu_isolation = s5p_usb_phy_pmu_isolation,
+};
+
void __init smartq_machine_init(void)
{
s3c_i2c0_set_platdata(NULL);
+ samsung_usbphy_set_pdata(&smartq_usbphy_pdata);
s3c_hwmon_set_platdata(&smartq_hwmon_pdata);
s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata);
s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata);
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index 123f452..00e46a6 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -30,6 +30,7 @@
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>
#include <linux/pwm_backlight.h>
+#include <linux/platform_data/samsung-usbphy.h>
#ifdef CONFIG_SMDK6410_WM1190_EV1
#include <linux/mfd/wm8350/core.h>
@@ -72,6 +73,7 @@
#include <linux/platform_data/touchscreen-s3c2410.h>
#include <plat/keypad.h>
#include <plat/backlight.h>
+#include <plat/usb-phy.h>
#include "common.h"
@@ -263,6 +265,7 @@ static struct samsung_keypad_platdata smdk6410_keypad_data __initdata = {
static struct map_desc smdk6410_iodesc[] = {};
static struct platform_device *smdk6410_devices[] __initdata = {
+ &samsung_device_usbphy,
#ifdef CONFIG_SMDK6410_SD_CH0
&s3c_device_hsmmc0,
#endif
@@ -626,6 +629,9 @@ static struct platform_pwm_backlight_data smdk6410_bl_data = {
.pwm_id = 1,
};
+static struct samsung_usbphy_data smdk6410_usbphy_pdata __initdata = {
+ .pmu_isolation = s5p_usb_phy_pmu_isolation,
+};
static void __init smdk6410_map_io(void)
{
@@ -655,6 +661,7 @@ static void __init smdk6410_machine_init(void)
s3c_i2c0_set_platdata(NULL);
s3c_i2c1_set_platdata(NULL);
s3c_fb_set_platdata(&smdk6410_lcd_pdata);
+ samsung_usbphy_set_pdata(&smdk6410_usbphy_pdata);
samsung_keypad_set_platdata(&smdk6410_keypad_data);
diff --git a/arch/arm/mach-s3c64xx/setup-usb-phy.c b/arch/arm/mach-s3c64xx/setup-usb-phy.c
index 7a09553..3aee778 100644
--- a/arch/arm/mach-s3c64xx/setup-usb-phy.c
+++ b/arch/arm/mach-s3c64xx/setup-usb-phy.c
@@ -9,3 +9,17 @@
*
*/
+#include <linux/io.h>
+#include <mach/map.h>
+#include <mach/regs-sys.h>
+
+void s5p_usb_phy_pmu_isolation(int on)
+{
+ if (on) {
+ writel(readl(S3C64XX_OTHERS) & ~S3C64XX_OTHERS_USBMASK,
+ S3C64XX_OTHERS);
+ } else {
+ writel(readl(S3C64XX_OTHERS) | S3C64XX_OTHERS_USBMASK,
+ S3C64XX_OTHERS);
+ }
+}
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index bc50b20..4031c77 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -31,6 +31,7 @@
#include <linux/ioport.h>
#include <linux/platform_data/s3c-hsudc.h>
#include <linux/platform_data/s3c-hsotg.h>
+#include <linux/platform_data/samsung-usbphy.h>
#include <media/s5p_hdmi.h>
@@ -1367,6 +1368,30 @@ struct platform_device s5p_device_mixer = {
/* USB */
+#ifdef CONFIG_ARCH_S3C64XX
+/* USB PHY*/
+static struct resource samsung_usbphy_resource[] = {
+ [0] = {
+ .start = S3C_PA_USB_PHY,
+ .end = S3C_PA_USB_PHY + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device samsung_device_usbphy = {
+ .name = "s3c64xx-usbphy",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(samsung_usbphy_resource),
+ .resource = samsung_usbphy_resource,
+};
+
+void __init samsung_usbphy_set_pdata(struct samsung_usbphy_data *pd)
+{
+ s3c_set_platdata(pd, sizeof(struct samsung_usbphy_data),
+ &samsung_device_usbphy);
+}
+#endif
+
#ifdef CONFIG_S3C_DEV_USB_HOST
static struct resource s3c_usb_resource[] = {
[0] = DEFINE_RES_MEM(S3C_PA_USBHOST, SZ_256),
@@ -1473,6 +1498,8 @@ struct platform_device s3c_device_usb_hsotg = {
},
};
+#ifndef CONFIG_ARCH_S3C64XX
+/* TODO: To be removed later. Currently only S3C64XX is platform data free */
void __init s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd)
{
struct s3c_hsotg_plat *npd;
@@ -1485,6 +1512,7 @@ void __init s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd)
if (!npd->phy_exit)
npd->phy_exit = s5p_usb_phy_exit;
}
+#endif
#endif /* CONFIG_S3C_DEV_USB_HSOTG */
/* USB High Spped 2.0 Device (Gadget) */
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 133e3e4..7f81dbc 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -136,6 +136,7 @@ extern struct platform_device exynos4_device_spdif;
extern struct platform_device samsung_asoc_dma;
extern struct platform_device samsung_asoc_idma;
extern struct platform_device samsung_device_keypad;
+extern struct platform_device samsung_device_usbphy;
/* s3c2440 specific devices */
diff --git a/arch/arm/plat-samsung/include/plat/usb-phy.h b/arch/arm/plat-samsung/include/plat/usb-phy.h
index 959bcdb..165ffe7 100644
--- a/arch/arm/plat-samsung/include/plat/usb-phy.h
+++ b/arch/arm/plat-samsung/include/plat/usb-phy.h
@@ -18,5 +18,6 @@ enum s5p_usb_phy_type {
extern int s5p_usb_phy_init(struct platform_device *pdev, int type);
extern int s5p_usb_phy_exit(struct platform_device *pdev, int type);
+extern void s5p_usb_phy_pmu_isolation(int on);
#endif /* __PLAT_SAMSUNG_USB_PHY_H */
--
1.7.1
^ permalink raw reply related
* [PATCH v8 1/3] ARM: S3C64XX: Removing old phy setup code
From: Praveen Paneri @ 2012-11-14 10:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352889938-17311-1-git-send-email-p.paneri@samsung.com>
This patch removes old phy code from platform side. 'setup-usb-phy.c'
will be used for providing transceiver platform data in next
patch. Not all of the platform data code is removed as there are others
making use of platform_data defined for hsotg. That can be removed once
all the SoCs start using the new transceiver for usb phy setup.
Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
---
arch/arm/mach-s3c64xx/mach-crag6410.c | 3 -
arch/arm/mach-s3c64xx/mach-smartq.c | 3 -
arch/arm/mach-s3c64xx/mach-smdk6410.c | 3 -
arch/arm/mach-s3c64xx/setup-usb-phy.c | 79 ---------------------------------
4 files changed, 0 insertions(+), 88 deletions(-)
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index 2abe95d..48f4a2d 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -31,7 +31,6 @@
#include <linux/spi/spi.h>
#include <linux/i2c/pca953x.h>
-#include <linux/platform_data/s3c-hsotg.h>
#include <video/platform_lcd.h>
@@ -805,7 +804,6 @@ static const struct gpio_led_platform_data gpio_leds_pdata = {
.num_leds = ARRAY_SIZE(gpio_leds),
};
-static struct s3c_hsotg_plat crag6410_hsotg_pdata;
static void __init crag6410_machine_init(void)
{
@@ -831,7 +829,6 @@ static void __init crag6410_machine_init(void)
s3c_i2c0_set_platdata(&i2c0_pdata);
s3c_i2c1_set_platdata(&i2c1_pdata);
s3c_fb_set_platdata(&crag6410_lcd_pdata);
- s3c_hsotg_set_platdata(&crag6410_hsotg_pdata);
i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c
index c6d7390..59bb34c 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq.c
@@ -18,7 +18,6 @@
#include <linux/serial_core.h>
#include <linux/spi/spi_gpio.h>
#include <linux/usb/gpio_vbus.h>
-#include <linux/platform_data/s3c-hsotg.h>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
@@ -187,7 +186,6 @@ static struct s3c_hwmon_pdata smartq_hwmon_pdata __initdata = {
},
};
-static struct s3c_hsotg_plat smartq_hsotg_pdata;
static int __init smartq_lcd_setup_gpio(void)
{
@@ -385,7 +383,6 @@ void __init smartq_map_io(void)
void __init smartq_machine_init(void)
{
s3c_i2c0_set_platdata(NULL);
- s3c_hsotg_set_platdata(&smartq_hsotg_pdata);
s3c_hwmon_set_platdata(&smartq_hwmon_pdata);
s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata);
s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata);
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index da1a771..123f452 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -30,7 +30,6 @@
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>
#include <linux/pwm_backlight.h>
-#include <linux/platform_data/s3c-hsotg.h>
#ifdef CONFIG_SMDK6410_WM1190_EV1
#include <linux/mfd/wm8350/core.h>
@@ -627,7 +626,6 @@ static struct platform_pwm_backlight_data smdk6410_bl_data = {
.pwm_id = 1,
};
-static struct s3c_hsotg_plat smdk6410_hsotg_pdata;
static void __init smdk6410_map_io(void)
{
@@ -657,7 +655,6 @@ static void __init smdk6410_machine_init(void)
s3c_i2c0_set_platdata(NULL);
s3c_i2c1_set_platdata(NULL);
s3c_fb_set_platdata(&smdk6410_lcd_pdata);
- s3c_hsotg_set_platdata(&smdk6410_hsotg_pdata);
samsung_keypad_set_platdata(&smdk6410_keypad_data);
diff --git a/arch/arm/mach-s3c64xx/setup-usb-phy.c b/arch/arm/mach-s3c64xx/setup-usb-phy.c
index f6757e0..7a09553 100644
--- a/arch/arm/mach-s3c64xx/setup-usb-phy.c
+++ b/arch/arm/mach-s3c64xx/setup-usb-phy.c
@@ -9,82 +9,3 @@
*
*/
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <mach/map.h>
-#include <mach/regs-sys.h>
-#include <plat/cpu.h>
-#include <plat/regs-usb-hsotg-phy.h>
-#include <plat/usb-phy.h>
-
-static int s3c_usb_otgphy_init(struct platform_device *pdev)
-{
- struct clk *xusbxti;
- u32 phyclk;
-
- writel(readl(S3C64XX_OTHERS) | S3C64XX_OTHERS_USBMASK, S3C64XX_OTHERS);
-
- /* set clock frequency for PLL */
- phyclk = readl(S3C_PHYCLK) & ~S3C_PHYCLK_CLKSEL_MASK;
-
- xusbxti = clk_get(&pdev->dev, "xusbxti");
- if (xusbxti && !IS_ERR(xusbxti)) {
- switch (clk_get_rate(xusbxti)) {
- case 12 * MHZ:
- phyclk |= S3C_PHYCLK_CLKSEL_12M;
- break;
- case 24 * MHZ:
- phyclk |= S3C_PHYCLK_CLKSEL_24M;
- break;
- default:
- case 48 * MHZ:
- /* default reference clock */
- break;
- }
- clk_put(xusbxti);
- }
-
- /* TODO: select external clock/oscillator */
- writel(phyclk | S3C_PHYCLK_CLK_FORCE, S3C_PHYCLK);
-
- /* set to normal OTG PHY */
- writel((readl(S3C_PHYPWR) & ~S3C_PHYPWR_NORMAL_MASK), S3C_PHYPWR);
- mdelay(1);
-
- /* reset OTG PHY and Link */
- writel(S3C_RSTCON_PHY | S3C_RSTCON_HCLK | S3C_RSTCON_PHYCLK,
- S3C_RSTCON);
- udelay(20); /* at-least 10uS */
- writel(0, S3C_RSTCON);
-
- return 0;
-}
-
-static int s3c_usb_otgphy_exit(struct platform_device *pdev)
-{
- writel((readl(S3C_PHYPWR) | S3C_PHYPWR_ANALOG_POWERDOWN |
- S3C_PHYPWR_OTG_DISABLE), S3C_PHYPWR);
-
- writel(readl(S3C64XX_OTHERS) & ~S3C64XX_OTHERS_USBMASK, S3C64XX_OTHERS);
-
- return 0;
-}
-
-int s5p_usb_phy_init(struct platform_device *pdev, int type)
-{
- if (type == S5P_USB_PHY_DEVICE)
- return s3c_usb_otgphy_init(pdev);
-
- return -EINVAL;
-}
-
-int s5p_usb_phy_exit(struct platform_device *pdev, int type)
-{
- if (type == S5P_USB_PHY_DEVICE)
- return s3c_usb_otgphy_exit(pdev);
-
- return -EINVAL;
-}
--
1.7.1
^ permalink raw reply related
* [PATCH v8 0/3] ARM: Exynos/S3C64XX: usb phy driver support for S3C64XX and EXYNOS4210
From: Praveen Paneri @ 2012-11-14 10:45 UTC (permalink / raw)
To: linux-arm-kernel
This patch series enables usb phy driver for S3C64XX and EXYNOS4210.
The phy driver patches are already sent to linux-usb.
Changes From v7:
Resolved build errors with s3c6400_defconfig, s5pv210_defconfig and
exynos_defconfig.
Tested with all other samsung configs as well.
Reformed PATCH 3 (PATCH 5 of last series) with proper subject.
Separated these arch patches from the driver patches.
Changes from v4:
Changed the platform data code to use __initdata
Changes from v2:
Changed 's3c' to 'samsung' for platform device as well as platform data
Moved platform data structure to a separate file
Praveen Paneri (3):
ARM: S3C64XX: Removing old phy setup code
ARM: S3C64XX: Enabling samsung-usbphy driver
ARM: EXYNOS: Enabling samsung-usbphy driver for EXYNOS4210
arch/arm/boot/dts/exynos4210-smdkv310.dts | 5 ++
arch/arm/mach-exynos/Kconfig | 1 +
arch/arm/mach-exynos/include/mach/map.h | 1 +
arch/arm/mach-exynos/mach-exynos4-dt.c | 8 +++
arch/arm/mach-exynos/setup-usb-phy.c | 13 ++++
arch/arm/mach-s3c64xx/include/mach/map.h | 2 +
arch/arm/mach-s3c64xx/mach-crag6410.c | 10 ++-
arch/arm/mach-s3c64xx/mach-smartq.c | 11 +++-
arch/arm/mach-s3c64xx/mach-smdk6410.c | 10 ++-
arch/arm/mach-s3c64xx/setup-usb-phy.c | 79 ++-----------------------
arch/arm/plat-samsung/devs.c | 28 +++++++++
arch/arm/plat-samsung/include/plat/devs.h | 1 +
arch/arm/plat-samsung/include/plat/usb-phy.h | 1 +
13 files changed, 89 insertions(+), 81 deletions(-)
^ permalink raw reply
* [PATCH 1/2] arm/mm: L2CC shared mutex with ARM TZ
From: Etienne CARRIERE ST @ 2012-11-14 10:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121114095121.GB10142@mudshark.cambridge.arm.com>
Sorry, I don't catch "swizzle your implementation" ?
You are referring to the raw_spinlock LOCKBREAK stuf ?
I will look deeper into linux code to check is some deadlock could appear.
The shared mutex arch spinlock is locked after raw_spinlick locking and released before l2x0 native raw_spinlock releasing.
It is intended to leave kernel preemption stuff inside the linux world.
etienne
-----Original Message-----
From: Will Deacon [mailto:will.deacon at arm.com]
Sent: Wednesday, November 14, 2012 10:51 AM
To: Etienne CARRIERE ST
Cc: Russell King - ARM Linux; linux-arm-kernel at lists.infradead.org; Marc Zyngier; Catalin Marinas; Linus Walleij; Rabin VINCENT; Srinidhi KASAGAR
Subject: Re: [PATCH 1/2] arm/mm: L2CC shared mutex with ARM TZ
On Wed, Nov 14, 2012 at 09:18:31AM +0000, Etienne CARRIERE ST wrote:
> This is why the mutex added for TZ shared of L2 cache maintenance is a "arch_spinlock". It assumes linux handles the spinlock as a native ARM native mutex DDR cell, handled from the ARMv7-A LDREX/STREX.
> I think this is the weakest part of the driver since they is no insurance that linux pristine arch_spinlock will not evolve into something else (i.e features in raw_spinclock).
How does this work with our ticket lock approach? Can you swizzle your locking implementation by inspecting the kernel version of the code running on the non-secure side? (I sincerely hope not...)
Will
^ permalink raw reply
* OMAP* Latest build failures
From: Russell King - ARM Linux @ 2012-11-14 10:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50A36DA3.2080201@ti.com>
On Wed, Nov 14, 2012 at 11:08:35AM +0100, Peter Ujfalusi wrote:
> Hi Russell,
>
> On 11/14/2012 10:26 AM, Russell King - ARM Linux wrote:
> > OMAP* allnoconfig fails:
> >
> > arch/arm/mach-omap2/built-in.o: In function `omap_dss_set_min_bus_tput':
> > twl-common.c:(.text+0x1e08): undefined reference to `omap_pm_set_min_bus_tput'
> > arch/arm/mach-omap2/built-in.o: In function `omap_hwmod_init_postsetup':
> > twl-common.c:(.init.text+0x8f8): undefined reference to `omap_pm_if_early_init'
> > arch/arm/mach-omap2/built-in.o: In function `omap_serial_init_port':
> > twl-common.c:(.init.text+0x1284): undefined reference to `omap_pm_get_dev_context_loss_count'
> > arch/arm/mach-omap2/built-in.o: In function `omap_timer_init':
> > twl-common.c:(.init.text+0x1544): undefined reference to `omap_pm_get_dev_context_loss_count'
> > arch/arm/mach-omap2/built-in.o: In function `omap2_common_pm_init':
> > twl-common.c:(.init.text+0x1af0): undefined reference to `omap_pm_if_init'
> > arch/arm/mach-omap2/built-in.o: In function `omap2_gpio_dev_init':
> > twl-common.c:(.init.text+0x2168): undefined reference to `omap_pm_get_dev_context_loss_count'
> > arch/arm/mach-omap2/built-in.o: In function `omap_display_init':
> > twl-common.c:(.init.text+0x25cc): undefined reference to `omap_pm_get_dev_context_loss_count'
>
> Not sure what is going on here but neither of these are referenced within
> twl-common.c directly.
You can't rely on the .c file issued by the linker. omap_display_init()
is not in twl-common.c, but is in arch/arm/mach-omap2/display.c. So
ignore the "twl-common.c".
> > OMAP4 randconfig fails:
> >
> > arch/arm/mach-omap2/cm_common.c: In function 'cm_register':
> > arch/arm/mach-omap2/cm_common.c:42:11: error: 'EINVAL' undeclared (first use in this function)
> > arch/arm/mach-omap2/cm_common.c:45:11: error: 'EEXIST' undeclared (first use in this function)
> > arch/arm/mach-omap2/cm_common.c: In function 'cm_unregister':
> > arch/arm/mach-omap2/cm_common.c:66:11: error: 'EINVAL' undeclared (first use in this function)
>
> I have already sent a patch to fix this:
> http://lists.infradead.org/pipermail/linux-arm-kernel/2012-November/131341.html
>
> > You know where to find the build information and results...
>
> It seams I can not find the link in my mail archives. Could you point me to
> the correct place?
http://www.arm.linux.org.uk/developer/build/
^ permalink raw reply
* [PATCH v8 2/2] usb: s3c-hsotg: Adding phy driver support
From: Praveen Paneri @ 2012-11-14 10:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352888836-17192-1-git-send-email-p.paneri@samsung.com>
Adding the transceiver to hsotg driver. Keeping the platform data
for continuing the smooth operation for boards which still uses it
Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
drivers/usb/gadget/s3c-hsotg.c | 37 +++++++++++++++++++++++++++----------
1 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index 6f696ee..bc30a2d 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -32,6 +32,7 @@
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
+#include <linux/usb/phy.h>
#include <linux/platform_data/s3c-hsotg.h>
#include <mach/map.h>
@@ -133,7 +134,9 @@ struct s3c_hsotg_ep {
* struct s3c_hsotg - driver state.
* @dev: The parent device supplied to the probe function
* @driver: USB gadget driver
- * @plat: The platform specific configuration data.
+ * @phy: The otg phy transceiver structure for phy control.
+ * @plat: The platform specific configuration data. This can be removed once
+ * all SoCs support usb transceiver.
* @regs: The memory area mapped for accessing registers.
* @irq: The IRQ number we are using
* @supplies: Definition of USB power supplies
@@ -153,6 +156,7 @@ struct s3c_hsotg_ep {
struct s3c_hsotg {
struct device *dev;
struct usb_gadget_driver *driver;
+ struct usb_phy *phy;
struct s3c_hsotg_plat *plat;
spinlock_t lock;
@@ -2854,7 +2858,10 @@ static void s3c_hsotg_phy_enable(struct s3c_hsotg *hsotg)
struct platform_device *pdev = to_platform_device(hsotg->dev);
dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev);
- if (hsotg->plat->phy_init)
+
+ if (hsotg->phy)
+ usb_phy_init(hsotg->phy);
+ else if (hsotg->plat->phy_init)
hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
}
@@ -2869,7 +2876,9 @@ static void s3c_hsotg_phy_disable(struct s3c_hsotg *hsotg)
{
struct platform_device *pdev = to_platform_device(hsotg->dev);
- if (hsotg->plat->phy_exit)
+ if (hsotg->phy)
+ usb_phy_shutdown(hsotg->phy);
+ else if (hsotg->plat->phy_exit)
hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type);
}
@@ -3493,6 +3502,7 @@ static void s3c_hsotg_release(struct device *dev)
static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
{
struct s3c_hsotg_plat *plat = pdev->dev.platform_data;
+ struct usb_phy *phy;
struct device *dev = &pdev->dev;
struct s3c_hsotg_ep *eps;
struct s3c_hsotg *hsotg;
@@ -3501,20 +3511,27 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
int ret;
int i;
- plat = pdev->dev.platform_data;
- if (!plat) {
- dev_err(&pdev->dev, "no platform data defined\n");
- return -EINVAL;
- }
-
hsotg = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsotg), GFP_KERNEL);
if (!hsotg) {
dev_err(dev, "cannot get memory\n");
return -ENOMEM;
}
+ phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
+ if (IS_ERR_OR_NULL(phy)) {
+ /* Fallback for pdata */
+ plat = pdev->dev.platform_data;
+ if (!plat) {
+ dev_err(&pdev->dev, "no platform data or transceiver defined\n");
+ return -EPROBE_DEFER;
+ } else {
+ hsotg->plat = plat;
+ }
+ } else {
+ hsotg->phy = phy;
+ }
+
hsotg->dev = dev;
- hsotg->plat = plat;
hsotg->clk = devm_clk_get(&pdev->dev, "otg");
if (IS_ERR(hsotg->clk)) {
--
1.7.1
^ permalink raw reply related
* [PATCH v8 1/2] usb: phy: samsung: Introducing usb phy driver for hsotg
From: Praveen Paneri @ 2012-11-14 10:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352888836-17192-1-git-send-email-p.paneri@samsung.com>
This driver uses usb_phy interface to interact with s3c-hsotg. Supports
phy_init and phy_shutdown functions to enable/disable usb phy. Support
will be extended to host controllers and more Samsung SoCs.
Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
Acked-by: Heiko Stuebner <heiko@sntech.de>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
.../devicetree/bindings/usb/samsung-usbphy.txt | 11 +
drivers/usb/phy/Kconfig | 8 +
drivers/usb/phy/Makefile | 1 +
drivers/usb/phy/samsung-usbphy.c | 360 ++++++++++++++++++++
include/linux/platform_data/samsung-usbphy.h | 27 ++
5 files changed, 407 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/usb/samsung-usbphy.txt
create mode 100644 drivers/usb/phy/samsung-usbphy.c
create mode 100644 include/linux/platform_data/samsung-usbphy.h
diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
new file mode 100644
index 0000000..7b26e2d
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
@@ -0,0 +1,11 @@
+* Samsung's usb phy transceiver
+
+The Samsung's phy transceiver is used for controlling usb otg phy for
+s3c-hsotg usb device controller.
+TODO: Adding the PHY binding with controller(s) according to the under
+developement generic PHY driver.
+
+Required properties:
+- compatible : should be "samsung,exynos4210-usbphy"
+- reg : base physical address of the phy registers and length of memory mapped
+ region.
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index 7eb73c5..17ad743 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -44,3 +44,11 @@ config USB_RCAR_PHY
To compile this driver as a module, choose M here: the
module will be called rcar-phy.
+
+config SAMSUNG_USBPHY
+ bool "Samsung USB PHY controller Driver"
+ depends on USB_S3C_HSOTG
+ select USB_OTG_UTILS
+ help
+ Enable this to support Samsung USB phy controller for samsung
+ SoCs.
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index 1a579a8..ec304f6 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_USB_ISP1301) += isp1301.o
obj-$(CONFIG_MV_U3D_PHY) += mv_u3d_phy.o
obj-$(CONFIG_USB_EHCI_TEGRA) += tegra_usb_phy.o
obj-$(CONFIG_USB_RCAR_PHY) += rcar-phy.o
+obj-$(CONFIG_SAMSUNG_USBPHY) += samsung-usbphy.o
diff --git a/drivers/usb/phy/samsung-usbphy.c b/drivers/usb/phy/samsung-usbphy.c
new file mode 100644
index 0000000..3c84aab
--- /dev/null
+++ b/drivers/usb/phy/samsung-usbphy.c
@@ -0,0 +1,360 @@
+/* linux/drivers/usb/phy/samsung-usbphy.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Author: Praveen Paneri <p.paneri@samsung.com>
+ *
+ * Samsung USB2.0 High-speed OTG transceiver, talks to S3C HS OTG controller
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/usb/otg.h>
+#include <linux/platform_data/samsung-usbphy.h>
+
+/* Register definitions */
+
+#define SAMSUNG_PHYPWR (0x00)
+
+#define PHYPWR_NORMAL_MASK (0x19 << 0)
+#define PHYPWR_OTG_DISABLE (0x1 << 4)
+#define PHYPWR_ANALOG_POWERDOWN (0x1 << 3)
+#define PHYPWR_FORCE_SUSPEND (0x1 << 1)
+/* For Exynos4 */
+#define PHYPWR_NORMAL_MASK_PHY0 (0x39 << 0)
+#define PHYPWR_SLEEP_PHY0 (0x1 << 5)
+
+#define SAMSUNG_PHYCLK (0x04)
+
+#define PHYCLK_MODE_USB11 (0x1 << 6)
+#define PHYCLK_EXT_OSC (0x1 << 5)
+#define PHYCLK_COMMON_ON_N (0x1 << 4)
+#define PHYCLK_ID_PULL (0x1 << 2)
+#define PHYCLK_CLKSEL_MASK (0x3 << 0)
+#define PHYCLK_CLKSEL_48M (0x0 << 0)
+#define PHYCLK_CLKSEL_12M (0x2 << 0)
+#define PHYCLK_CLKSEL_24M (0x3 << 0)
+
+#define SAMSUNG_RSTCON (0x08)
+
+#define RSTCON_PHYLINK_SWRST (0x1 << 2)
+#define RSTCON_HLINK_SWRST (0x1 << 1)
+#define RSTCON_SWRST (0x1 << 0)
+
+#ifndef MHZ
+#define MHZ (1000*1000)
+#endif
+
+enum samsung_cpu_type {
+ TYPE_S3C64XX,
+ TYPE_EXYNOS4210,
+};
+
+/*
+ * struct samsung_usbphy - transceiver driver state
+ * @phy: transceiver structure
+ * @plat: platform data
+ * @dev: The parent device supplied to the probe function
+ * @clk: usb phy clock
+ * @regs: usb phy register memory base
+ * @ref_clk_freq: reference clock frequency selection
+ * @cpu_type: machine identifier
+ */
+struct samsung_usbphy {
+ struct usb_phy phy;
+ struct samsung_usbphy_data *plat;
+ struct device *dev;
+ struct clk *clk;
+ void __iomem *regs;
+ int ref_clk_freq;
+ int cpu_type;
+};
+
+#define phy_to_sphy(x) container_of((x), struct samsung_usbphy, phy)
+
+/*
+ * Returns reference clock frequency selection value
+ */
+static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
+{
+ struct clk *ref_clk;
+ int refclk_freq = 0;
+
+ ref_clk = clk_get(sphy->dev, "xusbxti");
+ if (IS_ERR(ref_clk)) {
+ dev_err(sphy->dev, "Failed to get reference clock\n");
+ return PTR_ERR(ref_clk);
+ }
+
+ switch (clk_get_rate(ref_clk)) {
+ case 12 * MHZ:
+ refclk_freq = PHYCLK_CLKSEL_12M;
+ break;
+ case 24 * MHZ:
+ refclk_freq = PHYCLK_CLKSEL_24M;
+ break;
+ case 48 * MHZ:
+ refclk_freq = PHYCLK_CLKSEL_48M;
+ break;
+ default:
+ if (sphy->cpu_type == TYPE_S3C64XX)
+ refclk_freq = PHYCLK_CLKSEL_48M;
+ else
+ refclk_freq = PHYCLK_CLKSEL_24M;
+ break;
+ }
+ clk_put(ref_clk);
+
+ return refclk_freq;
+}
+
+static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
+{
+ void __iomem *regs = sphy->regs;
+ u32 phypwr;
+ u32 phyclk;
+ u32 rstcon;
+
+ /* set clock frequency for PLL */
+ phyclk = sphy->ref_clk_freq;
+ phypwr = readl(regs + SAMSUNG_PHYPWR);
+ rstcon = readl(regs + SAMSUNG_RSTCON);
+
+ switch (sphy->cpu_type) {
+ case TYPE_S3C64XX:
+ phyclk &= ~PHYCLK_COMMON_ON_N;
+ phypwr &= ~PHYPWR_NORMAL_MASK;
+ rstcon |= RSTCON_SWRST;
+ break;
+ case TYPE_EXYNOS4210:
+ phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
+ rstcon |= RSTCON_SWRST;
+ default:
+ break;
+ }
+
+ writel(phyclk, regs + SAMSUNG_PHYCLK);
+ /* set to normal of PHY0 */
+ writel(phypwr, regs + SAMSUNG_PHYPWR);
+ /* reset all ports of PHY and Link */
+ writel(rstcon, regs + SAMSUNG_RSTCON);
+ udelay(10);
+ rstcon &= ~RSTCON_SWRST;
+ writel(rstcon, regs + SAMSUNG_RSTCON);
+}
+
+static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
+{
+ void __iomem *regs = sphy->regs;
+ u32 phypwr;
+
+ phypwr = readl(regs + SAMSUNG_PHYPWR);
+
+ switch (sphy->cpu_type) {
+ case TYPE_S3C64XX:
+ phypwr |= PHYPWR_NORMAL_MASK;
+ break;
+ case TYPE_EXYNOS4210:
+ phypwr |= PHYPWR_NORMAL_MASK_PHY0;
+ default:
+ break;
+ }
+
+ /* unset to normal of PHY0 */
+ writel(phypwr, regs + SAMSUNG_PHYPWR);
+}
+
+/*
+ * The function passed to the usb driver for phy initialization
+ */
+static int samsung_usbphy_init(struct usb_phy *phy)
+{
+ struct samsung_usbphy *sphy;
+ int ret = 0;
+
+ sphy = phy_to_sphy(phy);
+
+ /* Enable the phy clock */
+ ret = clk_prepare_enable(sphy->clk);
+ if (ret) {
+ dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__);
+ return ret;
+ }
+
+ /* Disable phy isolation */
+ if (sphy->plat && sphy->plat->pmu_isolation)
+ sphy->plat->pmu_isolation(false);
+
+ /* Initialize usb phy registers */
+ samsung_usbphy_enable(sphy);
+
+ /* Disable the phy clock */
+ clk_disable_unprepare(sphy->clk);
+ return ret;
+}
+
+/*
+ * The function passed to the usb driver for phy shutdown
+ */
+static void samsung_usbphy_shutdown(struct usb_phy *phy)
+{
+ struct samsung_usbphy *sphy;
+
+ sphy = phy_to_sphy(phy);
+
+ if (clk_prepare_enable(sphy->clk)) {
+ dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__);
+ return;
+ }
+
+ /* De-initialize usb phy registers */
+ samsung_usbphy_disable(sphy);
+
+ /* Enable phy isolation */
+ if (sphy->plat && sphy->plat->pmu_isolation)
+ sphy->plat->pmu_isolation(true);
+
+ clk_disable_unprepare(sphy->clk);
+}
+
+static const struct of_device_id samsung_usbphy_dt_match[];
+
+static inline int samsung_usbphy_get_driver_data(struct platform_device *pdev)
+{
+ if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+ int data;
+ const struct of_device_id *match;
+ match = of_match_node(samsung_usbphy_dt_match,
+ pdev->dev.of_node);
+ data = (int) match->data;
+ return data;
+ }
+
+ return platform_get_device_id(pdev)->driver_data;
+}
+
+static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
+{
+ struct samsung_usbphy *sphy;
+ struct samsung_usbphy_data *pdata;
+ struct device *dev = &pdev->dev;
+ struct resource *phy_mem;
+ void __iomem *phy_base;
+ struct clk *clk;
+ int ret = 0;
+
+ pdata = pdev->dev.platform_data;
+ if (!pdata) {
+ dev_err(&pdev->dev, "%s: no platform data defined\n", __func__);
+ return -EINVAL;
+ }
+
+ phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!phy_mem) {
+ dev_err(dev, "%s: missing mem resource\n", __func__);
+ return -ENODEV;
+ }
+
+ phy_base = devm_request_and_ioremap(dev, phy_mem);
+ if (!phy_base) {
+ dev_err(dev, "%s: register mapping failed\n", __func__);
+ return -ENXIO;
+ }
+
+ sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL);
+ if (!sphy)
+ return -ENOMEM;
+
+ clk = devm_clk_get(dev, "otg");
+ if (IS_ERR(clk)) {
+ dev_err(dev, "Failed to get otg clock\n");
+ return PTR_ERR(clk);
+ }
+
+ sphy->dev = &pdev->dev;
+ sphy->plat = pdata;
+ sphy->regs = phy_base;
+ sphy->clk = clk;
+ sphy->phy.dev = sphy->dev;
+ sphy->phy.label = "samsung-usbphy";
+ sphy->phy.init = samsung_usbphy_init;
+ sphy->phy.shutdown = samsung_usbphy_shutdown;
+ sphy->cpu_type = samsung_usbphy_get_driver_data(pdev);
+ sphy->ref_clk_freq = samsung_usbphy_get_refclk_freq(sphy);
+
+ platform_set_drvdata(pdev, sphy);
+
+ ret = usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
+ return ret;
+}
+
+static int __exit samsung_usbphy_remove(struct platform_device *pdev)
+{
+ struct samsung_usbphy *sphy = platform_get_drvdata(pdev);
+
+ usb_remove_phy(&sphy->phy);
+
+ return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id samsung_usbphy_dt_match[] = {
+ {
+ .compatible = "samsung,s3c64xx-usbphy",
+ .data = (void *)TYPE_S3C64XX,
+ }, {
+ .compatible = "samsung,exynos4210-usbphy",
+ .data = (void *)TYPE_EXYNOS4210,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, samsung_usbphy_dt_match);
+#else
+#define samsung_usbphy_dt_match NULL
+#endif
+
+static struct platform_device_id samsung_usbphy_driver_ids[] = {
+ {
+ .name = "s3c64xx-usbphy",
+ .driver_data = TYPE_S3C64XX,
+ }, {
+ .name = "exynos4210-usbphy",
+ .driver_data = TYPE_EXYNOS4210,
+ },
+ {},
+};
+
+MODULE_DEVICE_TABLE(platform, samsung_usbphy_driver_ids);
+
+static struct platform_driver samsung_usbphy_driver = {
+ .probe = samsung_usbphy_probe,
+ .remove = __devexit_p(samsung_usbphy_remove),
+ .id_table = samsung_usbphy_driver_ids,
+ .driver = {
+ .name = "samsung-usbphy",
+ .owner = THIS_MODULE,
+ .of_match_table = samsung_usbphy_dt_match,
+ },
+};
+
+module_platform_driver(samsung_usbphy_driver);
+
+MODULE_DESCRIPTION("Samsung USB phy controller");
+MODULE_AUTHOR("Praveen Paneri <p.paneri@samsung.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:samsung-usbphy");
diff --git a/include/linux/platform_data/samsung-usbphy.h b/include/linux/platform_data/samsung-usbphy.h
new file mode 100644
index 0000000..1bd24cb
--- /dev/null
+++ b/include/linux/platform_data/samsung-usbphy.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ * http://www.samsung.com/
+ * Author: Praveen Paneri <p.paneri@samsung.com>
+ *
+ * Defines platform data for samsung usb phy driver.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __SAMSUNG_USBPHY_PLATFORM_H
+#define __SAMSUNG_USBPHY_PLATFORM_H
+
+/**
+ * samsung_usbphy_data - Platform data for USB PHY driver.
+ * @pmu_isolation: Function to control usb phy isolation in PMU.
+ */
+struct samsung_usbphy_data {
+ void (*pmu_isolation)(int on);
+};
+
+extern void samsung_usbphy_set_pdata(struct samsung_usbphy_data *pd);
+
+#endif /* __SAMSUNG_USBPHY_PLATFORM_H */
--
1.7.1
^ permalink raw reply related
* [PATCH v8 0/2] usb: phy: samsung: Introducing usb phy driver for samsung SoCs
From: Praveen Paneri @ 2012-11-14 10:27 UTC (permalink / raw)
To: linux-arm-kernel
Changes from v7:
Rebased to the latest usb-next branch.
Separating arch patches from these driver patches.
Changes from v6:
Modified register definitions according to the existing ones.
Changed default PHY clk selection for SoCs.
Improved binding text and rebased to the latest usb-next.
Changes from v5:
Moved clk_get() to driver's probe function. Now reference clock frequency
selection value is stored in samsung_usbphy structure for later use. Used
IS_ENABLED() instead of #ifdef in samsung_usbphy_get_driver_data().
Changes from v4:
Moved header file contents to driver's source file
Removed unnecessary print message from driver's probe function
Dropped the Free Software Foundation address from the header
Changes from v3:
Replaced susbsys_initcall()/module_exit() by module_platform_driver().
Accordingly in the hsotg driver returned -EPROBE_DEFER until phy driver
is registered
Removed unnecessary devm_usb_put_phy() call from the hsotg driver remove.
Changes from v2:
Changed the driver filenames to samsung-usbphy
Rectified coding style related errors
Changes from v1:
Rebased patches to latest usb-next branch
Changed the name 'sec_usbphy' to 'samsung_usbphy'
This patch set introduces a phy driver for samsung SoCs. It uses the existing
transceiver infrastructure to provide phy control functions. Use of this driver
can be extended for usb host phy as well. Over the period of time all the phy
related code for most of the samsung SoCs can be integrated here.
Removing the existing phy code from mach-s3c64xx. Same can be done for other SoCs
when they start supporting this phy driver.
This driver is tested with smdk6410 and Exynos4210(with DT).
Praveen Paneri (2):
usb: phy: samsung: Introducing usb phy driver for hsotg
usb: s3c-hsotg: Adding phy driver support
.../devicetree/bindings/usb/samsung-usbphy.txt | 11 +
drivers/usb/gadget/s3c-hsotg.c | 37 ++-
drivers/usb/phy/Kconfig | 8 +
drivers/usb/phy/Makefile | 1 +
drivers/usb/phy/samsung-usbphy.c | 360 ++++++++++++++++++++
include/linux/platform_data/samsung-usbphy.h | 27 ++
6 files changed, 434 insertions(+), 10 deletions(-)
create mode 100644 Documentation/devicetree/bindings/usb/samsung-usbphy.txt
create mode 100644 drivers/usb/phy/samsung-usbphy.c
create mode 100644 include/linux/platform_data/samsung-usbphy.h
^ permalink raw reply
* [PATCH 1/4] mfd: tps65217: Set PMIC to shutdowm on PWR_EN toggle
From: Mark Brown @ 2012-11-14 10:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50A36DB1.3010706@ti.com>
On Wed, Nov 14, 2012 at 11:08:49AM +0100, Benoit Cousson wrote:
> I was wondering that, because exposing a pin to control the whole PMIC
> low power mode seems to be something that should be generic enough to be
> handled by the regulator framework.
Having something that's controlled by software is really not at all
generic - suspending a PMIC from a GPIO is generally tied in very
closely with the CPU power sequencing which means it's typically some
combination of very hard coded things that we can't control or part of
much wider control of sequencing.
> In the current situation we do have a pwr_en pin that can be controlled
> by a GPIO or whatever signal from the SoC.
> That's very similar, at PMIC level, to the fixedregulator that allow a
> GPIO binding to enable it.
> Don't you think that should deserve a support in the fmwk?
I'm not seeing a coherent description of a feature here - what exactly
are you proposing that we do? When and how would this GPIO be set for
example?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121114/c909c844/attachment.sig>
^ permalink raw reply
* [PATCH 1/2] arm/mm: L2CC shared mutex with ARM TZ
From: Russell King - ARM Linux @ 2012-11-14 10:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <0154077FE026E54BB093CA7EB3FD1AE32B57AF1E29@SAFEX1MAIL3.st.com>
On Wed, Nov 14, 2012 at 10:18:31AM +0100, Etienne CARRIERE ST wrote:
> > From: Russell King - ARM Linux [mailto:linux at arm.linux.org.uk]
> > Sent: Tuesday, November 13, 2012 6:07 PM
> >
> > Right, so, what this tells me is that the implementation of the spinlock
> > in the secure software is potentially the same as the kernel's spinlock.
> > The kernel's spinlock implementation is GPL'd. If the secure side spinlock
> > implementation is a copy of the kernel's spinlock implementation, then
> > that implementation is also GPL'd (...).
> >
> > I think someone has some explaining to do.
>
> It does.
>
> The TZ implementation of the shared mutex is the ARM native mutex
> instructions set LDREX/STREX, protected by a native ARM IRQ disabling.
> I believe this is native ARMv7 natural handling and not subject to
> GPLization.
Maybe, maybe not. There's more to locking than just the instructions
used - there's the values which are used to represent "locked" and
"unlocked", and then there's the ticket locking implementation found
in recent kernels which defines the value to have more meaning than
just "locked" and "unlocked".
With ticket locking, you need to know the details of the implementation
to be able to lock successfully, and that basically means copying the
implementation.
^ permalink raw reply
* [PATCH v3 2/6] ARM: davinci: Changed pr_warning() to pr_warn() (part 2)
From: Sergei Shtylyov @ 2012-11-14 10:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352853207-20602-2-git-send-email-rtivy@ti.com>
Hello.
On 14-11-2012 4:33, Robert Tivy wrote:
> Also, while modifying those pr_warning() calls I changed hardcoded
> function names to use '"%s:", __func__' instead
> Signed-off-by: Robert Tivy <rtivy@ti.com>
> ---
> Clean up files that will be otherwise modified in subsequent patch.
> Applies to v3.7-rc2 tag (commit 6f0c0580b70c89094b3422ba81118c7b959c7556) of
> Linus' mainline kernel at git.kernel.org.
> arch/arm/mach-davinci/board-omapl138-hawk.c | 30 ++++++++++-----------------
> 1 file changed, 11 insertions(+), 19 deletions(-)
Taksing of separation of board and SoC specific changes, this patch
shouldn't have been separated from patch 1 at all -- since it's two boards
built around the same chip, OMAP-L138...
> diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
> index dc1208e..8aea169 100644
> --- a/arch/arm/mach-davinci/board-omapl138-hawk.c
> +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
> @@ -48,8 +48,7 @@ static __init void omapl138_hawk_config_emac(void)
> val &= ~BIT(8);
> ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins);
> if (ret) {
> - pr_warning("%s: cpgmac/mii mux setup failed: %d\n",
> - __func__, ret);
> + pr_warn("%s: cpgmac/mii mux setup failed: %d\n", __func__, ret);
I'd have preferred this as "CPGMAC/MII". Almost all other acronyms in the
messages are capitalized.
> return;
> }
>
> @@ -61,8 +60,7 @@ static __init void omapl138_hawk_config_emac(void)
>
> ret = da8xx_register_emac();
> if (ret)
> - pr_warning("%s: emac registration failed: %d\n",
> - __func__, ret);
> + pr_warn("%s: emac registration failed: %d\n", __func__, ret);
... and "EMAC" here.
WBR, Sergei
^ permalink raw reply
* [PATCH 1/2] arm/mm: L2CC shared mutex with ARM TZ
From: Etienne CARRIERE ST @ 2012-11-14 10:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <BLU002-W44C55773365E0FDAC8B3C5E36C0@phx.gbl>
> Tue 11-13-2012 8:23 PM
> From: Abhimanyu Kapur <abhimanyu.kapur@outlook.com>
>
> > Secure code in TrustZone space may need to perform L2 cache
> > maintenance operations. A shared mutex is required to synchronize
> > linux l2cc maintenance and TZ l2cc maintenance.
>
> If you are using PL310 with thrustzone support then the L2 cache lines
> are secure bit tagged ; your design should be such that the secure (TZ)
> side only does operations on secure cache lines and non-secure side
> does operations only on non-secure cache lines. So each entity (TZ
> and nonTZ) if maintains their own cache and ensures integrity before
> switching over via monitor, this might not be needed.
I don't think 2 cores can safely write the LX20_CLEAN/INV_LINE_PA registers of the PL310 at the same time, even if targeting different lines.
Each core TZ code must protect against other core (being UnSecure or TZ mode). The core IRQ disabling is required to protect from deadlock nonTZ and TZ worlds.
Regards,
etienne
^ permalink raw reply
* [PATCH 1/2] arm/mm: L2CC shared mutex with ARM TZ
From: Etienne CARRIERE ST @ 2012-11-14 10:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121113171745.GA6370@linaro.org>
> Tue 11-13-2012 6:18 PM
> From: Dave Martin <dave.martin@linaro.org>
>
> > Secure code in TrustZone space may need to perform L2 cache
> > maintenance operations. A shared mutex is required to synchronize
> > linux l2cc maintenance and TZ l2cc maintenance.
>
> 1) Why is this not a denial-of-service risk? (i.e., why can the Normal
> World not simply hold the mutex forever?)
On SoC's, it is likely that some HW IP are controlled with ARM NS compliant HW support, thus needed for TZ execution (RAMs, ...).
It is likely that nonTZ world, in such situation, could disable a clock, regulator, ... and arm TZ executions, including cache content.
An easy "secu denial of service" hack, is just to reprogram linux based OS to prevent any or selected calls to secure code.
Since linux OS is an untrusted environment, one could just reprogram it to prevent call to secure tagged features.
It is the responsibility of the TZ implementation to insure that secure content is not corrupted nor accessed to from nonTZ world.
> 2) The memory types on both sides have to be _exactly_ the same,
> not just "cached", otherwise unpredictable behaviour may occur when
> accessing the mutex. It is not obvious how this is ensured.
Ok, I will cross check this.
The mapping of the mutex/spinlock "lock" field is under responsibility of the TZ API driver.
Each platform TZ API should define the expected mapping configuration.
> 3) Many people seem to delegate L2 cache maintenence requests
> via SMC in these situations. Can you do that instead?
We can have code that runs in TZ world and heavily processes data, benefitting from cache support, then needing the flush data to DDR.
In such case, TZ would not need to request linux to request cache line maintenance.
Regards,
Etienne
>
> Cheers
> ---Dave
^ permalink raw reply
* [PATCH v3 1/6] ARM: davinci: Changed pr_warning() to pr_warn() (part 1)
From: Sergei Shtylyov @ 2012-11-14 10:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352853207-20602-1-git-send-email-rtivy@ti.com>
Hello.
On 14-11-2012 4:33, Robert Tivy wrote:
These subjects are not very good too -- it's better to specify the scope
of the changes, like "ARM: DaVinci: DA850 EVM: change pr_warning() to pr_warn()".
> Also, while modifying those pr_warning() calls I changed hardcoded
> function names to use '"%s:", __func__' instead
> Signed-off-by: Robert Tivy <rtivy@ti.com>
> ---
> Clean up files that will be otherwise modified in subsequent patch.
> Applies to v3.7-rc2 tag (commit 6f0c0580b70c89094b3422ba81118c7b959c7556) of
> Linus' mainline kernel at git.kernel.org.
> arch/arm/mach-davinci/board-da850-evm.c | 102 +++++++++++++------------------
> 1 file changed, 43 insertions(+), 59 deletions(-)
> diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
> index 32ee3f8..6c172b3 100644
> --- a/arch/arm/mach-davinci/board-da850-evm.c
> +++ b/arch/arm/mach-davinci/board-da850-evm.c
> @@ -347,13 +347,13 @@ static inline void da850_evm_setup_nor_nand(void)
> if (!HAS_MMC) {
> ret = davinci_cfg_reg_list(da850_evm_nand_pins);
> if (ret)
> - pr_warning("da850_evm_init: nand mux setup failed: "
> - "%d\n", ret);
> + pr_warn("%s: nand mux setup failed: %d\n",
My preference is to have the acronyms capitalized, so I'd changed to
"NAND", while at it.
> + __func__, ret);
>
> ret = davinci_cfg_reg_list(da850_evm_nor_pins);
> if (ret)
> - pr_warning("da850_evm_init: nor mux setup failed: %d\n",
> - ret);
> + pr_warn("%s: nor mux setup failed: %d\n",
... and to "NOR" here.
> @@ -688,14 +688,14 @@ static int da850_evm_bb_expander_setup(struct i2c_client *client,
> da850_evm_bb_keys_init(gpio);
> ret = platform_device_register(&da850_evm_bb_keys_device);
> if (ret) {
> - pr_warning("Could not register baseboard GPIO expander keys");
> + pr_warn("Could not register baseboard GPIO expander keys");
> goto io_exp_setup_sw_fail;
> }
>
> da850_evm_bb_leds_init(gpio);
> ret = platform_device_register(&da850_evm_bb_leds_device);
> if (ret) {
> - pr_warning("Could not register baseboard GPIO expander LEDS");
> + pr_warn("Could not register baseboard GPIO expander LEDS");
It's "LEDs".
> @@ -1060,21 +1060,19 @@ static int __init da850_evm_config_emac(void)
> }
>
> if (ret)
> - pr_warning("da850_evm_init: cpgmac/rmii mux setup failed: %d\n",
> - ret);
> + pr_warn("%s: cpgmac/rmii mux setup failed: %d\n",
I'd have changed to "CPGMAC/RMII".
> @@ -1085,8 +1083,7 @@ static int __init da850_evm_config_emac(void)
>
> ret = da8xx_register_emac();
> if (ret)
> - pr_warning("da850_evm_init: emac registration failed: %d\n",
> - ret);
> + pr_warn("%s: emac registration failed: %d\n", __func__, ret);
... and to "EMAC" here.
> @@ -1438,57 +1435,53 @@ static __init void da850_evm_init(void)
>
> ret = pmic_tps65070_init();
> if (ret)
> - pr_warning("da850_evm_init: TPS65070 PMIC init failed: %d\n",
> - ret);
> + pr_warn("%s: TPS65070 PMIC init failed: %d\n", __func__, ret);
>
> ret = da850_register_edma(da850_edma_rsv);
> if (ret)
> - pr_warning("da850_evm_init: edma registration failed: %d\n",
> - ret);
> + pr_warn("%s: edma registration failed: %d\n", __func__, ret);
... and to "EDMA" here.
> ret = davinci_cfg_reg_list(da850_i2c0_pins);
> if (ret)
> - pr_warning("da850_evm_init: i2c0 mux setup failed: %d\n",
> - ret);
> + pr_warn("%s: i2c0 mux setup failed: %d\n", __func__, ret);
... and to "I2C0" here.
>
> ret = da8xx_register_i2c(0, &da850_evm_i2c_0_pdata);
> if (ret)
> - pr_warning("da850_evm_init: i2c0 registration failed: %d\n",
> - ret);
> + pr_warn("%s: i2c0 registration failed: %d\n", __func__, ret);
... and here.
> if (HAS_MMC) {
> ret = davinci_cfg_reg_list(da850_evm_mmcsd0_pins);
> if (ret)
> - pr_warning("da850_evm_init: mmcsd0 mux setup failed:"
> - " %d\n", ret);
> + pr_warn("%s: mmcsd0 mux setup failed: %d\n",
... and to "MMCSD0" here.
[...]
> if (ret)
> - pr_warning("da850_evm_init: mmcsd0 registration failed:"
> - " %d\n", ret);
> + pr_warn("%s: mmcsd0 registration failed: %d\n",
... and here.
> + __func__, ret);
>
> ret = da850_wl12xx_init();
> if (ret)
> - pr_warning("da850_evm_init: wl12xx initialization"
> - " failed: %d\n", ret);
> + pr_warn("%s: wl12xx initialization failed: %d\n",
... and to "WL12xx" here.
> @@ -1506,64 +1499,55 @@ static __init void da850_evm_init(void)
>
> ret = davinci_cfg_reg_list(da850_evm_mcasp_pins);
> if (ret)
> - pr_warning("da850_evm_init: mcasp mux setup failed: %d\n",
> - ret);
> + pr_warn("%s: mcasp mux setup failed: %d\n", __func__, ret);
To "McASP" here.
>
> da8xx_register_mcasp(0, &da850_evm_snd_data);
>
> ret = davinci_cfg_reg_list(da850_lcdcntl_pins);
> if (ret)
> - pr_warning("da850_evm_init: lcdcntl mux setup failed: %d\n",
> - ret);
> + pr_warn("%s: lcdcntl mux setup failed: %d\n", __func__, ret);
To "LCDC" here.
>
> /* Handle board specific muxing for LCD here */
> ret = davinci_cfg_reg_list(da850_evm_lcdc_pins);
> if (ret)
> - pr_warning("da850_evm_init: evm specific lcd mux setup "
> - "failed: %d\n", ret);
> + pr_warn("%s: evm specific lcd mux setup failed: %d\n",
"EVM" and "LCD" here.
> + __func__, ret);
>
> ret = da850_lcd_hw_init();
> if (ret)
> - pr_warning("da850_evm_init: lcd initialization failed: %d\n",
> - ret);
> + pr_warn("%s: lcd initialization failed: %d\n", __func__, ret);
"LCD" here.
>
> sharp_lk043t1dg01_pdata.panel_power_ctrl = da850_panel_power_ctrl,
> ret = da8xx_register_lcdc(&sharp_lk043t1dg01_pdata);
> if (ret)
> - pr_warning("da850_evm_init: lcdc registration failed: %d\n",
> - ret);
> + pr_warn("%s: lcdc registration failed: %d\n", __func__, ret);
"LCDC" here.
>
> ret = da8xx_register_rtc();
> if (ret)
> - pr_warning("da850_evm_init: rtc setup failed: %d\n", ret);
> + pr_warn("%s: rtc setup failed: %d\n", __func__, ret);
"RTC" here.
>
> ret = da850_evm_init_cpufreq();
> if (ret)
> - pr_warning("da850_evm_init: cpufreq registration failed: %d\n",
> - ret);
> + pr_warn("%s: cpufreq registration failed: %d\n", __func__, ret);
>
> ret = da8xx_register_cpuidle();
> if (ret)
> - pr_warning("da850_evm_init: cpuidle registration failed: %d\n",
> - ret);
> + pr_warn("%s: cpuidle registration failed: %d\n", __func__, ret);
>
> ret = da850_register_pm(&da850_pm_device);
> if (ret)
> - pr_warning("da850_evm_init: suspend registration failed: %d\n",
> - ret);
> + pr_warn("%s: suspend registration failed: %d\n", __func__, ret);
>
> da850_vpif_init();
>
> ret = da8xx_register_spi(1, da850evm_spi_info,
> ARRAY_SIZE(da850evm_spi_info));
> if (ret)
> - pr_warning("da850_evm_init: spi 1 registration failed: %d\n",
> - ret);
> + pr_warn("%s: spi 1 registration failed: %d\n", __func__, ret);
"SPI" here.
>
> ret = da850_register_sata(DA850EVM_SATA_REFCLKPN_RATE);
> if (ret)
> - pr_warning("da850_evm_init: sata registration failed: %d\n",
> - ret);
> + pr_warn("%s: sata registration failed: %d\n", __func__, ret);
"SATA" here.
WBR, Sergei
^ permalink raw reply
* [Patch v6 4/4] ASoC: at91sam9g20ek-wm8731: convert to dt support
From: Bo Shen @ 2012-11-14 10:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352887751-21848-1-git-send-email-voice.shen@atmel.com>
convert at91sam9g20ek with wm8731 to device tree support
Signed-off-by: Bo Shen <voice.shen@atmel.com>
---
Change since v5:
No change
Change since v4 RFC:
Using the full name of the EK which make it more clear
Change since v3 RFC:
Remove dai node, remap ssc in place
without pinctrl added, so don't modify the dtsi file, will be added
soon
Change since v2:
No change
Change since v1:
Add sam9g20-wm8731 binding document
---
.../sound/atmel-at91sam9g20ek-wm8731-audio.txt | 26 ++++++++
arch/arm/boot/dts/at91sam9g20ek_common.dtsi | 32 +++++++++-
sound/soc/atmel/Kconfig | 3 +-
sound/soc/atmel/sam9g20_wm8731.c | 63 +++++++++++++++++++-
4 files changed, 119 insertions(+), 5 deletions(-)
create mode 100644 Documentation/devicetree/bindings/sound/atmel-at91sam9g20ek-wm8731-audio.txt
diff --git a/Documentation/devicetree/bindings/sound/atmel-at91sam9g20ek-wm8731-audio.txt b/Documentation/devicetree/bindings/sound/atmel-at91sam9g20ek-wm8731-audio.txt
new file mode 100644
index 0000000..9c5a994
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/atmel-at91sam9g20ek-wm8731-audio.txt
@@ -0,0 +1,26 @@
+* Atmel at91sam9g20ek wm8731 audio complex
+
+Required properties:
+ - compatible: "atmel,at91sam9g20ek-wm8731-audio"
+ - atmel,model: The user-visible name of this sound complex.
+ - atmel,audio-routing: A list of the connections between audio components.
+ - atmel,ssc-controller: The phandle of the SSC controller
+ - atmel,audio-codec: The phandle of the WM8731 audio codec
+Optional properties:
+ - pinctrl-names, pinctrl-0: Please refer to pinctrl-bindings.txt
+
+Example:
+sound {
+ compatible = "atmel,at91sam9g20ek-wm8731-audio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pck0_as_mck>;
+
+ atmel,model = "wm8731 @ AT91SAMG20EK";
+
+ atmel,audio-routing =
+ "Ext Spk", "LHPOUT",
+ "Int MIC", "MICIN";
+
+ atmel,ssc-controller = <&ssc0>;
+ atmel,audio-codec = <&wm8731>;
+};
diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
index 689323d..679f783 100644
--- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
+++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
@@ -30,6 +30,16 @@
ahb {
apb {
+ pinctrl at fffff400 {
+ board {
+ pinctrl_pck0_as_mck: pck0_as_mck {
+ atmel,pins =
+ <2 1 0x2 0x0>; /* PC1 periph B */
+ };
+
+ };
+ };
+
dbgu: serial at fffff200 {
status = "okay";
};
@@ -57,6 +67,11 @@
atmel,vbus-gpio = <&pioC 5 0>;
status = "okay";
};
+
+ ssc0: ssc at fffbc000 {
+ status = "okay";
+ pinctrl-0 = <&pinctrl_ssc0_tx>;
+ };
};
nand0: nand at 40000000 {
@@ -120,7 +135,7 @@
reg = <0x50>;
};
- wm8731 at 1b {
+ wm8731: wm8731 at 1b {
compatible = "wm8731";
reg = <0x1b>;
};
@@ -145,4 +160,19 @@
gpio-key,wakeup;
};
};
+
+ sound {
+ compatible = "atmel,at91sam9g20ek-wm8731-audio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pck0_as_mck>;
+
+ atmel,model = "wm8731 @ AT91SAMG20EK";
+
+ atmel,audio-routing =
+ "Ext Spk", "LHPOUT",
+ "Int Mic", "MICIN";
+
+ atmel,ssc-controller = <&ssc0>;
+ atmel,audio-codec = <&wm8731>;
+ };
};
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index 72b09cf..397ec75 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -16,8 +16,7 @@ config SND_ATMEL_SOC_SSC
config SND_AT91_SOC_SAM9G20_WM8731
tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
- depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC && \
- AT91_PROGRAMMABLE_CLOCKS
+ depends on ATMEL_SSC && SND_ATMEL_SOC && AT91_PROGRAMMABLE_CLOCKS
select SND_ATMEL_SOC_SSC
select SND_SOC_WM8731
help
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index 4deba18..0744610 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -38,6 +38,8 @@
#include <linux/platform_device.h>
#include <linux/i2c.h>
+#include <linux/pinctrl/consumer.h>
+
#include <linux/atmel-ssc.h>
#include <sound/core.h>
@@ -197,12 +199,24 @@ static struct snd_soc_card snd_soc_at91sam9g20ek = {
static int __devinit at91sam9g20ek_audio_probe(struct platform_device *pdev)
{
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *codec_np, *cpu_np;
struct clk *pllb;
struct snd_soc_card *card = &snd_soc_at91sam9g20ek;
+ struct pinctrl *pinctrl;
int ret;
- if (!(machine_is_at91sam9g20ek() || machine_is_at91sam9g20ek_2mmc()))
- return -ENODEV;
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl)) {
+ dev_err(&pdev->dev, "Failed to request pinctrl for mck\n");
+ return PTR_ERR(pinctrl);
+ }
+
+ if (!np) {
+ if (!(machine_is_at91sam9g20ek() ||
+ machine_is_at91sam9g20ek_2mmc()))
+ return -ENODEV;
+ }
ret = atmel_ssc_set_audio(0);
if (ret) {
@@ -236,6 +250,42 @@ static int __devinit at91sam9g20ek_audio_probe(struct platform_device *pdev)
clk_set_rate(mclk, MCLK_RATE);
card->dev = &pdev->dev;
+
+ /* Parse device node info */
+ if (np) {
+ ret = snd_soc_of_parse_card_name(card, "atmel,model");
+ if (ret)
+ goto err;
+
+ ret = snd_soc_of_parse_audio_routing(card,
+ "atmel,audio-routing");
+ if (ret)
+ goto err;
+
+ /* Parse codec info */
+ at91sam9g20ek_dai.codec_name = NULL;
+ codec_np = of_parse_phandle(np, "atmel,audio-codec", 0);
+ if (!codec_np) {
+ dev_err(&pdev->dev, "codec info missing\n");
+ return -EINVAL;
+ }
+ at91sam9g20ek_dai.codec_of_node = codec_np;
+
+ /* Parse dai and platform info */
+ at91sam9g20ek_dai.cpu_dai_name = NULL;
+ at91sam9g20ek_dai.platform_name = NULL;
+ cpu_np = of_parse_phandle(np, "atmel,ssc-controller", 0);
+ if (!cpu_np) {
+ dev_err(&pdev->dev, "dai and pcm info missing\n");
+ return -EINVAL;
+ }
+ at91sam9g20ek_dai.cpu_of_node = cpu_np;
+ at91sam9g20ek_dai.platform_of_node = cpu_np;
+
+ of_node_put(codec_np);
+ of_node_put(cpu_np);
+ }
+
ret = snd_soc_register_card(card);
if (ret) {
printk(KERN_ERR "ASoC: snd_soc_register_card() failed\n");
@@ -263,10 +313,19 @@ static int __devexit at91sam9g20ek_audio_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_OF
+static const struct of_device_id at91sam9g20ek_wm8731_dt_ids[] = {
+ { .compatible = "atmel,at91sam9g20ek-wm8731-audio", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, at91sam9g20ek_wm8731_dt_ids);
+#endif
+
static struct platform_driver at91sam9g20ek_audio_driver = {
.driver = {
.name = "at91sam9g20ek-audio",
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(at91sam9g20ek_wm8731_dt_ids),
},
.probe = at91sam9g20ek_audio_probe,
.remove = __devexit_p(at91sam9g20ek_audio_remove),
--
1.7.9.5
^ permalink raw reply related
* [Patch v6 3/4] ASoC: atmel-ssc-dai: match new method of dai and pcm register
From: Bo Shen @ 2012-11-14 10:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352887751-21848-1-git-send-email-voice.shen@atmel.com>
Remove unneeded code with the new method of dai and pcm register
Signed-off-by: Bo Shen <voice.shen@atmel.com>
---
Change since v5
- initial patch
- split from the previous patch
---
arch/arm/mach-at91/at91sam9260_devices.c | 9 ---------
arch/arm/mach-at91/board-sam9g20ek.c | 6 ------
sound/soc/atmel/sam9g20_wm8731.c | 12 ++++++++++--
3 files changed, 10 insertions(+), 17 deletions(-)
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index df7bebf..6959fd2 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -768,14 +768,6 @@ static inline void configure_ssc_pins(unsigned pins)
at91_set_A_periph(AT91_PIN_PB21, 1);
}
-static struct platform_device at91sam9260_ssc_dai_device = {
- .name = "atmel-ssc-dai",
- .id = 0,
- .dev = {
- .parent = &(at91sam9260_ssc_device.dev),
- },
-};
-
/*
* SSC controllers are accessed through library code, instead of any
* kind of all-singing/all-dancing driver. For example one could be
@@ -800,7 +792,6 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins)
}
platform_device_register(pdev);
- platform_device_register(&at91sam9260_ssc_dai_device);
}
#else
diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c
index 5b6a6f9..ebdbf42 100644
--- a/arch/arm/mach-at91/board-sam9g20ek.c
+++ b/arch/arm/mach-at91/board-sam9g20ek.c
@@ -353,11 +353,6 @@ static struct i2c_board_info __initdata ek_i2c_devices[] = {
},
};
-static struct platform_device sam9g20ek_pcm_device = {
- .name = "atmel-pcm-audio",
- .id = -1,
-};
-
static struct platform_device sam9g20ek_audio_device = {
.name = "at91sam9g20ek-audio",
.id = -1,
@@ -365,7 +360,6 @@ static struct platform_device sam9g20ek_audio_device = {
static void __init ek_add_device_audio(void)
{
- platform_device_register(&sam9g20ek_pcm_device);
platform_device_register(&sam9g20ek_audio_device);
}
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index 228ca6a..4deba18 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -179,10 +179,10 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
static struct snd_soc_dai_link at91sam9g20ek_dai = {
.name = "WM8731",
.stream_name = "WM8731 PCM",
- .cpu_dai_name = "atmel-ssc-dai.0",
+ .cpu_dai_name = "at91rm9200_ssc.0",
.codec_dai_name = "wm8731-hifi",
.init = at91sam9g20ek_wm8731_init,
- .platform_name = "atmel-pcm-audio",
+ .platform_name = "at91rm9200_ssc.0",
.codec_name = "wm8731.0-001b",
.ops = &at91sam9g20ek_ops,
};
@@ -204,6 +204,12 @@ static int __devinit at91sam9g20ek_audio_probe(struct platform_device *pdev)
if (!(machine_is_at91sam9g20ek() || machine_is_at91sam9g20ek_2mmc()))
return -ENODEV;
+ ret = atmel_ssc_set_audio(0);
+ if (ret) {
+ dev_err(&pdev->dev, "ssc channel is not valid\n");
+ return -EINVAL;
+ }
+
/*
* Codec MCLK is supplied by PCK0 - set it up.
*/
@@ -241,6 +247,7 @@ err_mclk:
clk_put(mclk);
mclk = NULL;
err:
+ atmel_ssc_put_audio(0);
return ret;
}
@@ -248,6 +255,7 @@ static int __devexit at91sam9g20ek_audio_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
+ atmel_ssc_put_audio(0);
snd_soc_unregister_card(card);
clk_put(mclk);
mclk = NULL;
--
1.7.9.5
^ permalink raw reply related
* [Patch v6 2/4] ASoC: atmel-ssc-dai: register dai and pcm directly
From: Bo Shen @ 2012-11-14 10:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352887751-21848-1-git-send-email-voice.shen@atmel.com>
change the method for register dai and pcm
- let the atmel-ssc-dai no longer as a standalone platform device
- remap ssc and then register dai directly
- register pcm from dai directly
- modify the code which related with this change
Signed-off-by: Bo Shen <voice.shen@atmel.com>
---
Change since v5
- split the patch, this only include register method change
- fix the backwards
Change since v4 RFC
- no change
Change since v3 RFC
- remap ssc and then register dai and pcm directly
Change since v2
- Register dai and pcm directly according to Mark Brown's suggestion
- using name to distinguish ssc register for audio or library
if for audio, the name with dai subfix
if for library, the name without dai subfix
- fix the issue for sam9g20-wm8731
- when register dai and pcm cause the sam9g20-wm8731 doesn't work,
so fix it
- Add device tree support
- Detail information reference atmel-ssc-dai.txt binding document
Change since v1
No change
---
sound/soc/atmel/atmel-pcm.c | 23 ++----
sound/soc/atmel/atmel-pcm.h | 3 +
sound/soc/atmel/atmel_ssc_dai.c | 157 ++++++++++-----------------------------
sound/soc/atmel/atmel_ssc_dai.h | 3 +-
4 files changed, 50 insertions(+), 136 deletions(-)
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
index 9b84f98..40e17d1 100644
--- a/sound/soc/atmel/atmel-pcm.c
+++ b/sound/soc/atmel/atmel-pcm.c
@@ -473,28 +473,17 @@ static struct snd_soc_platform_driver atmel_soc_platform = {
.resume = atmel_pcm_resume,
};
-static int __devinit atmel_soc_platform_probe(struct platform_device *pdev)
+int atmel_pcm_platform_register(struct device *dev)
{
- return snd_soc_register_platform(&pdev->dev, &atmel_soc_platform);
+ return snd_soc_register_platform(dev, &atmel_soc_platform);
}
+EXPORT_SYMBOL(atmel_pcm_platform_register);
-static int __devexit atmel_soc_platform_remove(struct platform_device *pdev)
+void atmel_pcm_platform_unregister(struct device *dev)
{
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
+ snd_soc_unregister_platform(dev);
}
-
-static struct platform_driver atmel_pcm_driver = {
- .driver = {
- .name = "atmel-pcm-audio",
- .owner = THIS_MODULE,
- },
-
- .probe = atmel_soc_platform_probe,
- .remove = __devexit_p(atmel_soc_platform_remove),
-};
-
-module_platform_driver(atmel_pcm_driver);
+EXPORT_SYMBOL(atmel_pcm_platform_unregister);
MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
MODULE_DESCRIPTION("Atmel PCM module");
diff --git a/sound/soc/atmel/atmel-pcm.h b/sound/soc/atmel/atmel-pcm.h
index 5e0a95e..e6d67b3 100644
--- a/sound/soc/atmel/atmel-pcm.h
+++ b/sound/soc/atmel/atmel-pcm.h
@@ -80,4 +80,7 @@ struct atmel_pcm_dma_params {
#define ssc_readx(base, reg) (__raw_readl((base) + (reg)))
#define ssc_writex(base, reg, value) __raw_writel((value), (base) + (reg))
+int atmel_pcm_platform_register(struct device *dev);
+void atmel_pcm_platform_unregister(struct device *dev);
+
#endif /* _ATMEL_PCM_H */
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index 354341e..7932c05 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -48,11 +48,7 @@
#include "atmel_ssc_dai.h"
-#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
-#define NUM_SSC_DEVICES 1
-#else
#define NUM_SSC_DEVICES 3
-#endif
/*
* SSC PDC registers required by the PCM DMA engine.
@@ -107,7 +103,6 @@ static struct atmel_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
.pdc = &pdc_rx_reg,
.mask = &ssc_rx_mask,
} },
-#if NUM_SSC_DEVICES == 3
{{
.name = "SSC1 PCM out",
.pdc = &pdc_tx_reg,
@@ -128,7 +123,6 @@ static struct atmel_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
.pdc = &pdc_rx_reg,
.mask = &ssc_rx_mask,
} },
-#endif
};
@@ -139,7 +133,6 @@ static struct atmel_ssc_info ssc_info[NUM_SSC_DEVICES] = {
.dir_mask = SSC_DIR_MASK_UNUSED,
.initialized = 0,
},
-#if NUM_SSC_DEVICES == 3
{
.name = "ssc1",
.lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock),
@@ -152,7 +145,6 @@ static struct atmel_ssc_info ssc_info[NUM_SSC_DEVICES] = {
.dir_mask = SSC_DIR_MASK_UNUSED,
.initialized = 0,
},
-#endif
};
@@ -690,27 +682,9 @@ static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai)
static int atmel_ssc_probe(struct snd_soc_dai *dai)
{
struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
- int ret = 0;
snd_soc_dai_set_drvdata(dai, ssc_p);
- /*
- * Request SSC device
- */
- ssc_p->ssc = ssc_request(dai->id);
- if (IS_ERR(ssc_p->ssc)) {
- printk(KERN_ERR "ASoC: Failed to request SSC %d\n", dai->id);
- ret = PTR_ERR(ssc_p->ssc);
- }
-
- return ret;
-}
-
-static int atmel_ssc_remove(struct snd_soc_dai *dai)
-{
- struct atmel_ssc_info *ssc_p = snd_soc_dai_get_drvdata(dai);
-
- ssc_free(ssc_p->ssc);
return 0;
}
@@ -728,48 +702,8 @@ static const struct snd_soc_dai_ops atmel_ssc_dai_ops = {
.set_clkdiv = atmel_ssc_set_dai_clkdiv,
};
-static struct snd_soc_dai_driver atmel_ssc_dai[NUM_SSC_DEVICES] = {
- {
- .name = "atmel-ssc-dai.0",
- .probe = atmel_ssc_probe,
- .remove = atmel_ssc_remove,
- .suspend = atmel_ssc_suspend,
- .resume = atmel_ssc_resume,
- .playback = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = ATMEL_SSC_RATES,
- .formats = ATMEL_SSC_FORMATS,},
- .capture = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = ATMEL_SSC_RATES,
- .formats = ATMEL_SSC_FORMATS,},
- .ops = &atmel_ssc_dai_ops,
- },
-#if NUM_SSC_DEVICES == 3
- {
- .name = "atmel-ssc-dai.1",
- .probe = atmel_ssc_probe,
- .remove = atmel_ssc_remove,
- .suspend = atmel_ssc_suspend,
- .resume = atmel_ssc_resume,
- .playback = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = ATMEL_SSC_RATES,
- .formats = ATMEL_SSC_FORMATS,},
- .capture = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = ATMEL_SSC_RATES,
- .formats = ATMEL_SSC_FORMATS,},
- .ops = &atmel_ssc_dai_ops,
- },
- {
- .name = "atmel-ssc-dai.2",
+static struct snd_soc_dai_driver atmel_ssc_dai = {
.probe = atmel_ssc_probe,
- .remove = atmel_ssc_remove,
.suspend = atmel_ssc_suspend,
.resume = atmel_ssc_resume,
.playback = {
@@ -783,32 +717,37 @@ static struct snd_soc_dai_driver atmel_ssc_dai[NUM_SSC_DEVICES] = {
.rates = ATMEL_SSC_RATES,
.formats = ATMEL_SSC_FORMATS,},
.ops = &atmel_ssc_dai_ops,
- },
-#endif
};
-static __devinit int asoc_ssc_probe(struct platform_device *pdev)
+static int asoc_ssc_init(struct device *dev)
{
- BUG_ON(pdev->id < 0);
- BUG_ON(pdev->id >= ARRAY_SIZE(atmel_ssc_dai));
- return snd_soc_register_dai(&pdev->dev, &atmel_ssc_dai[pdev->id]);
-}
+ int ret;
+
+ ret = snd_soc_register_dai(dev, &atmel_ssc_dai);
+ if (ret) {
+ dev_err(dev, "Could not register DAI: %d\n", ret);
+ goto err;
+ }
+
+ ret = atmel_pcm_platform_register(dev);
+ if (ret) {
+ dev_err(dev, "Could not register PCM: %d\n", ret);
+ goto err_unregister_dai;
+ };
-static int __devexit asoc_ssc_remove(struct platform_device *pdev)
-{
- snd_soc_unregister_dai(&pdev->dev);
return 0;
-}
-static struct platform_driver asoc_ssc_driver = {
- .driver = {
- .name = "atmel-ssc-dai",
- .owner = THIS_MODULE,
- },
+err_unregister_dai:
+ snd_soc_unregister_dai(dev);
+err:
+ return ret;
+}
- .probe = asoc_ssc_probe,
- .remove = __devexit_p(asoc_ssc_remove),
-};
+static void asoc_ssc_exit(struct device *dev)
+{
+ atmel_pcm_platform_unregister(dev);
+ snd_soc_unregister_dai(dev);
+}
/**
* atmel_ssc_set_audio - Allocate the specified SSC for audio use.
@@ -816,50 +755,32 @@ static struct platform_driver asoc_ssc_driver = {
int atmel_ssc_set_audio(int ssc_id)
{
struct ssc_device *ssc;
- static struct platform_device *dma_pdev;
- struct platform_device *ssc_pdev;
int ret;
- if (ssc_id < 0 || ssc_id >= ARRAY_SIZE(atmel_ssc_dai))
- return -EINVAL;
-
- /* Allocate a dummy device for DMA if we don't have one already */
- if (!dma_pdev) {
- dma_pdev = platform_device_alloc("atmel-pcm-audio", -1);
- if (!dma_pdev)
- return -ENOMEM;
-
- ret = platform_device_add(dma_pdev);
- if (ret < 0) {
- platform_device_put(dma_pdev);
- dma_pdev = NULL;
- return ret;
- }
- }
-
- ssc_pdev = platform_device_alloc("atmel-ssc-dai", ssc_id);
- if (!ssc_pdev)
- return -ENOMEM;
-
/* If we can grab the SSC briefly to parent the DAI device off it */
ssc = ssc_request(ssc_id);
- if (IS_ERR(ssc))
- pr_warn("Unable to parent ASoC SSC DAI on SSC: %ld\n",
+ if (IS_ERR(ssc)) {
+ pr_err("Unable to parent ASoC SSC DAI on SSC: %ld\n",
PTR_ERR(ssc));
- else {
- ssc_pdev->dev.parent = &(ssc->pdev->dev);
- ssc_free(ssc);
+ return PTR_ERR(ssc);
+ } else {
+ ssc_info[ssc_id].ssc = ssc;
}
- ret = platform_device_add(ssc_pdev);
- if (ret < 0)
- platform_device_put(ssc_pdev);
+ ret = asoc_ssc_init(&ssc->pdev->dev);
return ret;
}
EXPORT_SYMBOL_GPL(atmel_ssc_set_audio);
-module_platform_driver(asoc_ssc_driver);
+void atmel_ssc_put_audio(int ssc_id)
+{
+ struct ssc_device *ssc = ssc_info[ssc_id].ssc;
+
+ ssc_free(ssc);
+ asoc_ssc_exit(&ssc->pdev->dev);
+}
+EXPORT_SYMBOL_GPL(atmel_ssc_put_audio);
/* Module information */
MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou at atmel.com, www.atmel.com");
diff --git a/sound/soc/atmel/atmel_ssc_dai.h b/sound/soc/atmel/atmel_ssc_dai.h
index 5d4f0f9..b1f08d5 100644
--- a/sound/soc/atmel/atmel_ssc_dai.h
+++ b/sound/soc/atmel/atmel_ssc_dai.h
@@ -117,6 +117,7 @@ struct atmel_ssc_info {
struct atmel_ssc_state ssc_state;
};
-int atmel_ssc_set_audio(int ssc);
+int atmel_ssc_set_audio(int ssc_id);
+void atmel_ssc_put_audio(int ssc_id);
#endif /* _AT91_SSC_DAI_H */
--
1.7.9.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox