Re: [PATCH v9 1/8] drivers: phy: add generic PHY framework
Hi, On Wednesday 17 July 2013 10:55 PM, Greg KH wrote: On Wed, Jul 17, 2013 at 03:02:59PM +0530, Kishon Vijay Abraham I wrote: Hi, On Wednesday 17 July 2013 11:59 AM, Greg KH wrote: On Wed, Jun 26, 2013 at 05:17:29PM +0530, Kishon Vijay Abraham I wrote: +menuconfig GENERIC_PHY + tristate PHY Subsystem + help +Generic PHY support. + +This framework is designed to provide a generic interface for PHY +devices present in the kernel. This layer will have the generic +API by which phy drivers can create PHY using the phy framework and +phy users can obtain reference to the PHY. Shouldn't this be something that other drivers select? How will anyone know if they need this or not? All the PHY drivers should go here. So only if *GENERIC_PHY* is enabled those PHY drivers can be selected like in [1]. The PHY consumer driver should ideally use *depends on* in their Kconfig. [1] - http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html No, switch it around the other way. How would I even _know_ that I need to enable the generic PHY subsystem in the first place? How can I determine that I need this for my hardware? You need to give hints to someone who doesn't even know what a PHY is, otherwise they will always disable it and move on. --- /dev/null +++ b/drivers/phy/phy-core.c @@ -0,0 +1,544 @@ +/* + * phy-core.c -- Generic Phy framework. + * + * Copyright (C) 2013 Texas Instruments + * + * Author: Kishon Vijay Abraham I kis...@ti.com + * + * 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. You really mean any later version (I have to ask)? That was copied from somewhere :-s So, is that what you really mean to have for this code? indeed. + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. Are these two paragraphs needed? This isn't a program, and they got a copy of the GPL already with the kernel. hmm.. I can remove that. +static struct class *phy_class; Why do you need a class? Wanted to group all the PHY drivers to be used by different subsystems (SATA/USB/PCIE/HDMI/VIDEO) into a single entity. There were some comments in my initial version [3] on using a bus_type instead of class but then it was decided to go with class itself. [3] - http://lkml.indiana.edu/hypermail/linux/kernel/1302.2/01389.html Ok, but what does the class usage get you? hmm.. actually I use class only to iterate through the list of devices in *phy* class which could very well be implemented using list. Just that I wont have a /sys/class/phy/ entry to find the list of phys added in the system. I dont think I want to add any other stuff to expose to the user space at this point of time. When modifying/adding new sysfs stuff, you need a Documentation/ABI/ entry as well. I'm not actually adding any new sysfs entry other than what a *class_create* must have created. Do I need to add one for that? If you are not creating anything in sysfs at all, why use the driver model? (hint, I think you need to do something here to justify it...) Well.. it helps me to use pm_runtime to enable clocks utilizing the parent-child relationship. Thanks Kishon -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v9 1/8] drivers: phy: add generic PHY framework
On Thu, Jul 18, 2013 at 11:33:17AM +0530, Kishon Vijay Abraham I wrote: Wanted to group all the PHY drivers to be used by different subsystems (SATA/USB/PCIE/HDMI/VIDEO) into a single entity. There were some comments in my initial version [3] on using a bus_type instead of class but then it was decided to go with class itself. [3] - http://lkml.indiana.edu/hypermail/linux/kernel/1302.2/01389.html Ok, but what does the class usage get you? hmm.. actually I use class only to iterate through the list of devices in *phy* class which could very well be implemented using list. Just that I wont have a /sys/class/phy/ entry to find the list of phys added in the system. I dont think I want to add any other stuff to expose to the user space at this point of time. When modifying/adding new sysfs stuff, you need a Documentation/ABI/ entry as well. I'm not actually adding any new sysfs entry other than what a *class_create* must have created. Do I need to add one for that? If you are not creating anything in sysfs at all, why use the driver model? (hint, I think you need to do something here to justify it...) Well.. it helps me to use pm_runtime to enable clocks utilizing the parent-child relationship. Ok, that's a good reason for this, nevermind then. Care to send the latest patches you have in emails so I can review them? thanks, greg k-h -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v9 1/8] drivers: phy: add generic PHY framework
On Thursday 18 July 2013 11:54 AM, Greg KH wrote: On Thu, Jul 18, 2013 at 11:33:17AM +0530, Kishon Vijay Abraham I wrote: Wanted to group all the PHY drivers to be used by different subsystems (SATA/USB/PCIE/HDMI/VIDEO) into a single entity. There were some comments in my initial version [3] on using a bus_type instead of class but then it was decided to go with class itself. [3] - http://lkml.indiana.edu/hypermail/linux/kernel/1302.2/01389.html Ok, but what does the class usage get you? hmm.. actually I use class only to iterate through the list of devices in *phy* class which could very well be implemented using list. Just that I wont have a /sys/class/phy/ entry to find the list of phys added in the system. I dont think I want to add any other stuff to expose to the user space at this point of time. When modifying/adding new sysfs stuff, you need a Documentation/ABI/ entry as well. I'm not actually adding any new sysfs entry other than what a *class_create* must have created. Do I need to add one for that? If you are not creating anything in sysfs at all, why use the driver model? (hint, I think you need to do something here to justify it...) Well.. it helps me to use pm_runtime to enable clocks utilizing the parent-child relationship. Ok, that's a good reason for this, nevermind then. Care to send the latest patches you have in emails so I can review them? Sure. Thanks Kishon -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/3] ARM: OMAP2+: omap_device: add dynamic pinctrl handling
On 07/17/2013 03:30 PM, Grygorii Strashko wrote: On 07/17/2013 02:57 PM, Roger Quadros wrote: Hi Grygorii, On 07/17/2013 02:41 PM, Grygorii Strashko wrote: Hi Tony, Kevin This patch series introduces dynamic pinctrl handling in OMAP device framework in the same way as it was before switching to DT. This allow OMAP devices driver's developers to simply add dynamic pinctrl handling for default, active, idle, sleep PIN states in their drivers by modifying DT definitions only - no modifications in drivers code are not needed. Overall I like the idea but can we make a provision for device drivers to override this default pin state handling? The OMAP EHCI driver is one such special case where the wakeup mechanism is tied to pinctrl states as it uses IO daisy chaining to implement wakeup. So depending on whether wakeup needs to be enabled or not I must be able to chose whether I put the pin in just sleep state or sleep with wakeup state. I think, in this case you can't use default behavior and need to define custom pins states like sleep_wakeup/sleep_no_wakeup and do not define pins state with name sleep', so Device core and OMAP device framework will not touch your pins. Yes, I think this should be fine. Thanks. cheers, -roger -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 15/15] video: exynos_dp: Use the generic PHY driver
From: Jingoo Han jg1@samsung.com Use the generic PHY API to control the DP PHY. Signed-off-by: Jingoo Han jg1@samsung.com Reviewed-by: Tomasz Figa t.f...@samsung.com Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- .../devicetree/bindings/video/exynos_dp.txt | 18 +- drivers/video/exynos/exynos_dp_core.c| 16 drivers/video/exynos/exynos_dp_core.h|1 + 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt index 84f10c1..2f56376 100644 --- a/Documentation/devicetree/bindings/video/exynos_dp.txt +++ b/Documentation/devicetree/bindings/video/exynos_dp.txt @@ -6,10 +6,10 @@ We use two nodes: -dptx-phy node(defined inside dp-controller node) For the DP-PHY initialization, we use the dptx-phy node. -Required properties for dptx-phy: - -reg: +Required properties for dptx-phy: deprecated, use phys and phy-names + -reg: deprecated Base address of DP PHY register. - -samsung,enable-mask: + -samsung,enable-mask: deprecated The bit-mask used to enable/disable DP PHY. For the Panel initialization, we read data from dp-controller node. @@ -25,6 +25,10 @@ Required properties for dp-controller: from common clock binding: handle to dp clock. -clock-names: from common clock binding: Shall be dp. + -phys: + from general PHY binding: the phandle for the PHY device. + -phy-names: + from general PHY binding: Should be dp. -interrupt-parent: phandle to Interrupt combiner node. -samsung,color-space: @@ -67,12 +71,8 @@ SOC specific portion: interrupt-parent = combiner; clocks = clock 342; clock-names = dp; - - dptx-phy { - reg = 0x10040720; - samsung,enable-mask = 1; - }; - + phys = dp_phy; + phy-names = dp; }; Board Specific portion: diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c index 05fed7d..5e1a715 100644 --- a/drivers/video/exynos/exynos_dp_core.c +++ b/drivers/video/exynos/exynos_dp_core.c @@ -19,6 +19,7 @@ #include linux/interrupt.h #include linux/delay.h #include linux/of.h +#include linux/phy/phy.h #include exynos_dp_core.h @@ -960,8 +961,11 @@ static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp) dp_phy_node = of_find_node_by_name(dp_phy_node, dptx-phy); if (!dp_phy_node) { - dev_err(dp-dev, could not find dptx-phy node\n); - return -ENODEV; + dp-phy = devm_phy_get(dp-dev, dp); + if (IS_ERR(dp-phy)) + return PTR_ERR(dp-phy); + else + return 0; } if (of_property_read_u32(dp_phy_node, reg, phy_base)) { @@ -992,7 +996,9 @@ err: static void exynos_dp_phy_init(struct exynos_dp_device *dp) { - if (dp-phy_addr) { + if (dp-phy) { + phy_power_on(dp-phy); + } else if (dp-phy_addr) { u32 reg; reg = __raw_readl(dp-phy_addr); @@ -1003,7 +1009,9 @@ static void exynos_dp_phy_init(struct exynos_dp_device *dp) static void exynos_dp_phy_exit(struct exynos_dp_device *dp) { - if (dp-phy_addr) { + if (dp-phy) { + phy_power_off(dp-phy); + } else if (dp-phy_addr) { u32 reg; reg = __raw_readl(dp-phy_addr); diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h index 56cfec8..607e36d 100644 --- a/drivers/video/exynos/exynos_dp_core.h +++ b/drivers/video/exynos/exynos_dp_core.h @@ -151,6 +151,7 @@ struct exynos_dp_device { struct video_info *video_info; struct link_train link_train; struct work_struct hotplug_work; + struct phy *phy; }; /* exynos_dp_reg.c */ -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 14/15] video: exynos_dp: remove non-DT support for Exynos Display Port
From: Jingoo Han jg1@samsung.com Exynos Display Port can be used only for Exynos SoCs. In addition, non-DT for EXYNOS SoCs is not supported from v3.11; thus, there is no need to support non-DT for Exynos Display Port. The 'include/video/exynos_dp.h' file has been used for non-DT support and the content of file include/video/exynos_dp.h is moved to drivers/video/exynos/exynos_dp_core.h. Thus, the 'exynos_dp.h' file is removed. Also, 'struct exynos_dp_platdata' is removed, because it is not used any more. Signed-off-by: Jingoo Han jg1@samsung.com Reviewed-by: Tomasz Figa t.f...@samsung.com Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/video/exynos/Kconfig |2 +- drivers/video/exynos/exynos_dp_core.c | 116 +++-- drivers/video/exynos/exynos_dp_core.h | 109 +++ drivers/video/exynos/exynos_dp_reg.c |2 - include/video/exynos_dp.h | 131 - 5 files changed, 135 insertions(+), 225 deletions(-) delete mode 100644 include/video/exynos_dp.h diff --git a/drivers/video/exynos/Kconfig b/drivers/video/exynos/Kconfig index 1b035b2..fab9019 100644 --- a/drivers/video/exynos/Kconfig +++ b/drivers/video/exynos/Kconfig @@ -29,7 +29,7 @@ config EXYNOS_LCD_S6E8AX0 config EXYNOS_DP bool EXYNOS DP driver support - depends on ARCH_EXYNOS + depends on OF ARCH_EXYNOS default n help This enables support for DP device. diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c index 12bbede..05fed7d 100644 --- a/drivers/video/exynos/exynos_dp_core.c +++ b/drivers/video/exynos/exynos_dp_core.c @@ -20,8 +20,6 @@ #include linux/delay.h #include linux/of.h -#include video/exynos_dp.h - #include exynos_dp_core.h static int exynos_dp_init_dp(struct exynos_dp_device *dp) @@ -894,26 +892,17 @@ static void exynos_dp_hotplug(struct work_struct *work) dev_err(dp-dev, unable to config video\n); } -#ifdef CONFIG_OF -static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev) +static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev) { struct device_node *dp_node = dev-of_node; - struct exynos_dp_platdata *pd; struct video_info *dp_video_config; - pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); - if (!pd) { - dev_err(dev, memory allocation for pdata failed\n); - return ERR_PTR(-ENOMEM); - } dp_video_config = devm_kzalloc(dev, sizeof(*dp_video_config), GFP_KERNEL); - if (!dp_video_config) { dev_err(dev, memory allocation for video config failed\n); return ERR_PTR(-ENOMEM); } - pd-video_info = dp_video_config; dp_video_config-h_sync_polarity = of_property_read_bool(dp_node, hsync-active-high); @@ -960,7 +949,7 @@ static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev) return ERR_PTR(-EINVAL); } - return pd; + return dp_video_config; } static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp) @@ -1003,48 +992,30 @@ err: static void exynos_dp_phy_init(struct exynos_dp_device *dp) { - u32 reg; + if (dp-phy_addr) { + u32 reg; - reg = __raw_readl(dp-phy_addr); - reg |= dp-enable_mask; - __raw_writel(reg, dp-phy_addr); + reg = __raw_readl(dp-phy_addr); + reg |= dp-enable_mask; + __raw_writel(reg, dp-phy_addr); + } } static void exynos_dp_phy_exit(struct exynos_dp_device *dp) { - u32 reg; - - reg = __raw_readl(dp-phy_addr); - reg = ~(dp-enable_mask); - __raw_writel(reg, dp-phy_addr); -} -#else -static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev) -{ - return NULL; -} - -static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp) -{ - return -EINVAL; -} - -static void exynos_dp_phy_init(struct exynos_dp_device *dp) -{ - return; -} + if (dp-phy_addr) { + u32 reg; -static void exynos_dp_phy_exit(struct exynos_dp_device *dp) -{ - return; + reg = __raw_readl(dp-phy_addr); + reg = ~(dp-enable_mask); + __raw_writel(reg, dp-phy_addr); + } } -#endif /* CONFIG_OF */ static int exynos_dp_probe(struct platform_device *pdev) { struct resource *res; struct exynos_dp_device *dp; - struct exynos_dp_platdata *pdata; int ret = 0; @@ -1057,21 +1028,13 @@ static int exynos_dp_probe(struct platform_device *pdev) dp-dev = pdev-dev; - if (pdev-dev.of_node) { - pdata = exynos_dp_dt_parse_pdata(pdev-dev); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); + dp-video_info =
[PATCH 12/15] ARM: Samsung: Remove the MIPI PHY setup code
From: Sylwester Nawrocki s.nawro...@samsung.com Generic PHY drivers are used to handle the MIPI CSIS and MIPI DSIM DPHYs so we can remove now unused code at arch/arm/plat-samsung. In case there is any board file for S5PV210 platforms using MIPI CSIS/DSIM (not any upstream currently) it should use the generic PHY API to bind the PHYs to respective PHY consumer drivers and a platform device for the PHY provider should be defined. Signed-off-by: Sylwester Nawrocki s.nawro...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com Acked-by: Felipe Balbi ba...@ti.com Acked-by: Kukjin Kim kgene@samsung.com Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- arch/arm/mach-exynos/include/mach/regs-pmu.h|5 -- arch/arm/mach-s5pv210/include/mach/regs-clock.h |4 -- arch/arm/plat-samsung/Kconfig |5 -- arch/arm/plat-samsung/Makefile |1 - arch/arm/plat-samsung/setup-mipiphy.c | 60 --- 5 files changed, 75 deletions(-) delete mode 100644 arch/arm/plat-samsung/setup-mipiphy.c diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h index 57344b7..2cdb63e 100644 --- a/arch/arm/mach-exynos/include/mach/regs-pmu.h +++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h @@ -44,11 +44,6 @@ #define S5P_DAC_PHY_CONTROLS5P_PMUREG(0x070C) #define S5P_DAC_PHY_ENABLE (1 0) -#define S5P_MIPI_DPHY_CONTROL(n) S5P_PMUREG(0x0710 + (n) * 4) -#define S5P_MIPI_DPHY_ENABLE (1 0) -#define S5P_MIPI_DPHY_SRESETN (1 1) -#define S5P_MIPI_DPHY_MRESETN (1 2) - #define S5P_INFORM0S5P_PMUREG(0x0800) #define S5P_INFORM1S5P_PMUREG(0x0804) #define S5P_INFORM2S5P_PMUREG(0x0808) diff --git a/arch/arm/mach-s5pv210/include/mach/regs-clock.h b/arch/arm/mach-s5pv210/include/mach/regs-clock.h index 032de66..e345584 100644 --- a/arch/arm/mach-s5pv210/include/mach/regs-clock.h +++ b/arch/arm/mach-s5pv210/include/mach/regs-clock.h @@ -147,10 +147,6 @@ #define S5P_HDMI_PHY_CONTROL S5P_CLKREG(0xE804) #define S5P_USB_PHY_CONTROLS5P_CLKREG(0xE80C) #define S5P_DAC_PHY_CONTROLS5P_CLKREG(0xE810) -#define S5P_MIPI_DPHY_CONTROL(x) S5P_CLKREG(0xE814) -#define S5P_MIPI_DPHY_ENABLE (1 0) -#define S5P_MIPI_DPHY_SRESETN (1 1) -#define S5P_MIPI_DPHY_MRESETN (1 2) #define S5P_INFORM0S5P_CLKREG(0xF000) #define S5P_INFORM1S5P_CLKREG(0xF004) diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index 3dc5cbe..db2d814 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -402,11 +402,6 @@ config S3C24XX_PWM Support for exporting the PWM timer blocks via the pwm device system -config S5P_SETUP_MIPIPHY - bool - help - Compile in common setup code for MIPI-CSIS and MIPI-DSIM devices - config S3C_SETUP_CAMIF bool help diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index 98d07d8..98f1e31 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -41,7 +41,6 @@ obj-$(CONFIG_S5P_DEV_UART)+= s5p-dev-uart.o obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT)+= dev-backlight.o obj-$(CONFIG_S3C_SETUP_CAMIF) += setup-camif.o -obj-$(CONFIG_S5P_SETUP_MIPIPHY)+= setup-mipiphy.o # DMA support diff --git a/arch/arm/plat-samsung/setup-mipiphy.c b/arch/arm/plat-samsung/setup-mipiphy.c deleted file mode 100644 index 66df315..000 --- a/arch/arm/plat-samsung/setup-mipiphy.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2011 Samsung Electronics Co., Ltd. - * - * S5P - Helper functions for MIPI-CSIS and MIPI-DSIM D-PHY control - * - * 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/export.h -#include linux/kernel.h -#include linux/platform_device.h -#include linux/io.h -#include linux/spinlock.h -#include mach/regs-clock.h - -static int __s5p_mipi_phy_control(int id, bool on, u32 reset) -{ - static DEFINE_SPINLOCK(lock); - void __iomem *addr; - unsigned long flags; - u32 cfg; - - id = max(0, id); - if (id 1) - return -EINVAL; - - addr = S5P_MIPI_DPHY_CONTROL(id); - - spin_lock_irqsave(lock, flags); - - cfg = __raw_readl(addr); - cfg = on ? (cfg | reset) : (cfg ~reset); - __raw_writel(cfg, addr); - - if (on) { - cfg |= S5P_MIPI_DPHY_ENABLE; - } else if (!(cfg (S5P_MIPI_DPHY_SRESETN | - S5P_MIPI_DPHY_MRESETN) ~reset)) { - cfg = ~S5P_MIPI_DPHY_ENABLE; - } - - __raw_writel(cfg, addr); -
[PATCH 13/15] phy: Add driver for Exynos DP PHY
From: Jingoo Han jg1@samsung.com Add a PHY provider driver for the Samsung Exynos SoC Display Port PHY. Signed-off-by: Jingoo Han jg1@samsung.com Reviewed-by: Tomasz Figa t.f...@samsung.com Cc: Sylwester Nawrocki s.nawro...@samsung.com Acked-by: Felipe Balbi ba...@ti.com Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- .../devicetree/bindings/phy/samsung-phy.txt|8 ++ drivers/phy/Kconfig|6 ++ drivers/phy/Makefile |1 + drivers/phy/phy-exynos-dp-video.c | 111 4 files changed, 126 insertions(+) create mode 100644 drivers/phy/phy-exynos-dp-video.c diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt index 5ff208c..c0fccaa 100644 --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt @@ -12,3 +12,11 @@ the PHY specifier identifies the PHY and its meaning is as follows: 1 - MIPI DSIM 0, 2 - MIPI CSIS 1, 3 - MIPI DSIM 1. + +Samsung EXYNOS SoC series Display Port PHY +- + +Required properties: +- compatible : should be samsung,exynos5250-dp-video-phy; +- reg : offset and length of the Display Port PHY register set; +- #phy-cells : from the generic PHY bindings, must be 0; diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 6f446d0..ed0b1b8 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -19,4 +19,10 @@ config PHY_EXYNOS_MIPI_VIDEO help Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung S5P and EXYNOS SoCs. + +config PHY_EXYNOS_DP_VIDEO + tristate EXYNOS SoC series Display Port PHY driver + depends on OF + help + Support for Display Port PHY found on Samsung EXYNOS SoCs. endif diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 71d8841..0fd1340 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_GENERIC_PHY) += phy-core.o obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO)+= phy-exynos-mipi-video.o +obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o diff --git a/drivers/phy/phy-exynos-dp-video.c b/drivers/phy/phy-exynos-dp-video.c new file mode 100644 index 000..3c8e247 --- /dev/null +++ b/drivers/phy/phy-exynos-dp-video.c @@ -0,0 +1,111 @@ +/* + * Samsung EXYNOS SoC series Display Port PHY driver + * + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Author: Jingoo Han jg1@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/io.h +#include linux/kernel.h +#include linux/module.h +#include linux/of.h +#include linux/of_address.h +#include linux/phy/phy.h +#include linux/platform_device.h + +/* DPTX_PHY_CONTROL register */ +#define EXYNOS_DPTX_PHY_ENABLE (1 0) + +struct exynos_dp_video_phy { + void __iomem *regs; +}; + +static int __set_phy_state(struct exynos_dp_video_phy *state, unsigned int on) +{ + u32 reg; + + reg = readl(state-regs); + if (on) + reg |= EXYNOS_DPTX_PHY_ENABLE; + else + reg = ~EXYNOS_DPTX_PHY_ENABLE; + writel(reg, state-regs); + + return 0; +} + +static int exynos_dp_video_phy_power_on(struct phy *phy) +{ + struct exynos_dp_video_phy *state = phy_get_drvdata(phy); + + return __set_phy_state(state, 1); +} + +static int exynos_dp_video_phy_power_off(struct phy *phy) +{ + struct exynos_dp_video_phy *state = phy_get_drvdata(phy); + + return __set_phy_state(state, 0); +} + +static struct phy_ops exynos_dp_video_phy_ops = { + .power_on = exynos_dp_video_phy_power_on, + .power_off = exynos_dp_video_phy_power_off, + .owner = THIS_MODULE, +}; + +static int exynos_dp_video_phy_probe(struct platform_device *pdev) +{ + struct exynos_dp_video_phy *state; + struct device *dev = pdev-dev; + struct resource *res; + struct phy_provider *phy_provider; + struct phy *phy; + + state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); + if (!state) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + state-regs = devm_ioremap_resource(dev, res); + if (IS_ERR(state-regs)) + return PTR_ERR(state-regs); + + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + if (IS_ERR(phy_provider)) + return PTR_ERR(phy_provider); + + phy = devm_phy_create(dev, 0, exynos_dp_video_phy_ops, NULL); + if (IS_ERR(phy)) { + dev_err(dev, failed to create Display Port PHY\n); + return PTR_ERR(phy); + } + phy_set_drvdata(phy,
[PATCH 05/15] ARM: dts: omap: update usb_otg_hs data
Updated the usb_otg_hs dt data to include the *phy* and *phy-names* binding in order for the driver to use the new generic PHY framework. Also updated the Documentation to include the binding information. The PHY binding information can be found at Documentation/devicetree/bindings/phy/phy-bindings.txt Signed-off-by: Kishon Vijay Abraham I kis...@ti.com Acked-by: Felipe Balbi ba...@ti.com Reviewed-by: Sylwester Nawrocki s.nawro...@samsung.com --- Documentation/devicetree/bindings/usb/omap-usb.txt |5 + Documentation/devicetree/bindings/usb/usb-phy.txt |6 ++ arch/arm/boot/dts/omap3-beagle-xm.dts |2 ++ arch/arm/boot/dts/omap3-evm.dts|2 ++ arch/arm/boot/dts/omap3-overo.dtsi |2 ++ arch/arm/boot/dts/omap4.dtsi |3 +++ arch/arm/boot/dts/twl4030.dtsi |1 + 7 files changed, 21 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/omap-usb.txt b/Documentation/devicetree/bindings/usb/omap-usb.txt index 57e71f6..825790d 100644 --- a/Documentation/devicetree/bindings/usb/omap-usb.txt +++ b/Documentation/devicetree/bindings/usb/omap-usb.txt @@ -19,6 +19,9 @@ OMAP MUSB GLUE - power : Should be 50. This signifies the controller can supply up to 100mA when operating in host mode. - usb-phy : the phandle for the PHY device + - phys : the phandle for the PHY device (used by generic PHY framework) + - phy-names : the names of the PHY corresponding to the PHYs present in the + *phy* phandle. Optional properties: - ctrl-module : phandle of the control module this glue uses to write to @@ -33,6 +36,8 @@ usb_otg_hs: usb_otg_hs@4a0ab000 { num-eps = 16; ram-bits = 12; ctrl-module = omap_control_usb; + phys = usb2_phy; + phy-names = usb2-phy; }; Board specific device node entry diff --git a/Documentation/devicetree/bindings/usb/usb-phy.txt b/Documentation/devicetree/bindings/usb/usb-phy.txt index 61496f5..c0245c8 100644 --- a/Documentation/devicetree/bindings/usb/usb-phy.txt +++ b/Documentation/devicetree/bindings/usb/usb-phy.txt @@ -5,6 +5,8 @@ OMAP USB2 PHY Required properties: - compatible: Should be ti,omap-usb2 - reg : Address and length of the register set for the device. + - #phy-cells: determine the number of cells that should be given in the + phandle while referencing this phy. Optional properties: - ctrl-module : phandle of the control module used by PHY driver to power on @@ -16,6 +18,7 @@ usb2phy@4a0ad080 { compatible = ti,omap-usb2; reg = 0x4a0ad080 0x58; ctrl-module = omap_control_usb; + #phy-cells = 0; }; OMAP USB3 PHY @@ -25,6 +28,8 @@ Required properties: - reg : Address and length of the register set for the device. - reg-names: The names of the register addresses corresponding to the registers filled in reg. + - #phy-cells: determine the number of cells that should be given in the + phandle while referencing this phy. Optional properties: - ctrl-module : phandle of the control module used by PHY driver to power on @@ -39,4 +44,5 @@ usb3phy@4a084400 { 0x4a084c00 0x40; reg-names = phy_rx, phy_tx, pll_ctrl; ctrl-module = omap_control_usb; + #phy-cells = 0; }; diff --git a/arch/arm/boot/dts/omap3-beagle-xm.dts b/arch/arm/boot/dts/omap3-beagle-xm.dts index afdb164..533b2da 100644 --- a/arch/arm/boot/dts/omap3-beagle-xm.dts +++ b/arch/arm/boot/dts/omap3-beagle-xm.dts @@ -144,6 +144,8 @@ usb_otg_hs { interface-type = 0; usb-phy = usb2_phy; + phys = usb2_phy; + phy-names = usb2-phy; mode = 3; power = 50; }; diff --git a/arch/arm/boot/dts/omap3-evm.dts b/arch/arm/boot/dts/omap3-evm.dts index 7d4329d..4134dd0 100644 --- a/arch/arm/boot/dts/omap3-evm.dts +++ b/arch/arm/boot/dts/omap3-evm.dts @@ -70,6 +70,8 @@ usb_otg_hs { interface-type = 0; usb-phy = usb2_phy; + phys = usb2_phy; + phy-names = usb2-phy; mode = 3; power = 50; }; diff --git a/arch/arm/boot/dts/omap3-overo.dtsi b/arch/arm/boot/dts/omap3-overo.dtsi index 8f1abec..a461d2f 100644 --- a/arch/arm/boot/dts/omap3-overo.dtsi +++ b/arch/arm/boot/dts/omap3-overo.dtsi @@ -76,6 +76,8 @@ usb_otg_hs { interface-type = 0; usb-phy = usb2_phy; + phys = usb2_phy; + phy-names = usb2-phy; mode = 3; power = 50; }; diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index 22d9f2b..1e8e2fe 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi @@ -520,6 +520,7 @@ compatible = ti,omap-usb2; reg = 0x4a0ad080 0x58; ctrl-module = omap_control_usb; + #phy-cells = 0; }; }; @@ -658,6 +659,8 @@ interrupt-names = mc, dma;
[PATCH 09/15] phy: Add driver for Exynos MIPI CSIS/DSIM DPHYs
From: Sylwester Nawrocki s.nawro...@samsung.com Add a PHY provider driver for the Samsung S5P/Exynos SoC MIPI CSI-2 receiver and MIPI DSI transmitter DPHYs. Signed-off-by: Sylwester Nawrocki s.nawro...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com Acked-by: Felipe Balbi ba...@ti.com Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- .../devicetree/bindings/phy/samsung-phy.txt| 14 ++ drivers/phy/Kconfig|9 ++ drivers/phy/Makefile |3 +- drivers/phy/phy-exynos-mipi-video.c| 169 4 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/phy/samsung-phy.txt create mode 100644 drivers/phy/phy-exynos-mipi-video.c diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt new file mode 100644 index 000..5ff208c --- /dev/null +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt @@ -0,0 +1,14 @@ +Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY +- + +Required properties: +- compatible : should be samsung,s5pv210-mipi-video-phy; +- reg : offset and length of the MIPI DPHY register set; +- #phy-cells : from the generic phy bindings, must be 1; + +For samsung,s5pv210-mipi-video-phy compatible PHYs the second cell in +the PHY specifier identifies the PHY and its meaning is as follows: + 0 - MIPI CSIS 0, + 1 - MIPI DSIM 0, + 2 - MIPI CSIS 1, + 3 - MIPI DSIM 1. diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 5f85909..6f446d0 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -11,3 +11,12 @@ menuconfig GENERIC_PHY devices present in the kernel. This layer will have the generic API by which phy drivers can create PHY using the phy framework and phy users can obtain reference to the PHY. + +if GENERIC_PHY + +config PHY_EXYNOS_MIPI_VIDEO + tristate S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver + help + Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung + S5P and EXYNOS SoCs. +endif diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 9e9560f..71d8841 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -2,4 +2,5 @@ # Makefile for the phy drivers. # -obj-$(CONFIG_GENERIC_PHY) += phy-core.o +obj-$(CONFIG_GENERIC_PHY) += phy-core.o +obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO)+= phy-exynos-mipi-video.o diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c new file mode 100644 index 000..7e7fcd7 --- /dev/null +++ b/drivers/phy/phy-exynos-mipi-video.c @@ -0,0 +1,169 @@ +/* + * Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY driver + * + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Author: Sylwester Nawrocki s.nawro...@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/io.h +#include linux/kernel.h +#include linux/module.h +#include linux/of.h +#include linux/of_address.h +#include linux/phy/phy.h +#include linux/platform_device.h +#include linux/spinlock.h + +/* MIPI_PHYn_CONTROL register offset: n = 0..1 */ +#define EXYNOS_MIPI_PHY_CONTROL(n) ((n) * 4) +#define EXYNOS_MIPI_PHY_ENABLE (1 0) +#define EXYNOS_MIPI_PHY_SRESETN(1 1) +#define EXYNOS_MIPI_PHY_MRESETN(1 2) +#define EXYNOS_MIPI_PHY_RESET_MASK (3 1) + +enum exynos_mipi_phy_id { + EXYNOS_MIPI_PHY_ID_CSIS0, + EXYNOS_MIPI_PHY_ID_DSIM0, + EXYNOS_MIPI_PHY_ID_CSIS1, + EXYNOS_MIPI_PHY_ID_DSIM1, + EXYNOS_MIPI_PHYS_NUM +}; + +#define IS_EXYNOS_MIPI_DSIM_PHY_ID(id) \ + ((id) == EXYNOS_MIPI_PHY_ID_DSIM0 || (id) == EXYNOS_MIPI_PHY_ID_DSIM0) + +struct exynos_mipi_video_phy { + spinlock_t slock; + struct phy *phys[EXYNOS_MIPI_PHYS_NUM]; + void __iomem *regs; +}; + +static int __set_phy_state(struct exynos_mipi_video_phy *state, + enum exynos_mipi_phy_id id, unsigned int on) +{ + void __iomem *addr; + u32 reg, reset; + + addr = state-regs + EXYNOS_MIPI_PHY_CONTROL(id / 2); + + if (IS_EXYNOS_MIPI_DSIM_PHY_ID(id)) + reset = EXYNOS_MIPI_PHY_MRESETN; + else + reset = EXYNOS_MIPI_PHY_SRESETN; + + spin_lock(state-slock); + reg = readl(addr); + if (on) + reg |= reset; + else + reg = ~reset; + writel(reg, addr); + + /* Clear ENABLE bit only if MRESETN, SRESETN bits are not set. */ + if (on) + reg |= EXYNOS_MIPI_PHY_ENABLE; + else if (!(reg EXYNOS_MIPI_PHY_RESET_MASK)) + reg = ~EXYNOS_MIPI_PHY_ENABLE; + + writel(reg, addr); +
[PATCH 06/15] usb: musb: omap2430: use the new generic PHY framework
Use the generic PHY framework API to get the PHY. The usb_phy_set_resume and usb_phy_set_suspend is replaced with power_on and power_off to align with the new PHY framework. musb-xceiv can't be removed as of now because musb core uses xceiv.state and xceiv.otg. Once there is a separate state machine to handle otg, these can be moved out of xceiv and then we can start using the generic PHY framework. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com Reviewed-by: Sylwester Nawrocki s.nawro...@samsung.com Acked-by: Felipe Balbi ba...@ti.com --- drivers/usb/musb/Kconfig |1 + drivers/usb/musb/musb_core.c |1 + drivers/usb/musb/musb_core.h |3 +++ drivers/usb/musb/omap2430.c | 26 -- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 797e3fd..01381ac 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -76,6 +76,7 @@ config USB_MUSB_TUSB6010 config USB_MUSB_OMAP2PLUS tristate OMAP2430 and onwards depends on ARCH_OMAP2PLUS + depends on GENERIC_PHY config USB_MUSB_AM35X tristate AM35x diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 29a24ce..cca12c0 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1814,6 +1814,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) musb-min_power = plat-min_power; musb-ops = plat-platform_ops; musb-port_mode = plat-mode; + musb-phy_label = plat-phy_label; /* The musb_platform_init() call: * - adjusts musb-mregs diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 7d341c3..8f017ab 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -46,6 +46,7 @@ #include linux/usb.h #include linux/usb/otg.h #include linux/usb/musb.h +#include linux/phy/phy.h struct musb; struct musb_hw_ep; @@ -346,6 +347,7 @@ struct musb { u16 int_tx; struct usb_phy *xceiv; + struct phy *phy; int nIrq; unsignedirq_wake:1; @@ -424,6 +426,7 @@ struct musb { unsigneddouble_buffer_not_ok:1; struct musb_hdrc_config *config; + const char *phy_label; #ifdef MUSB_CONFIG_PROC_FS struct proc_dir_entry *proc_entry; diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 6708a3b..87dac0f 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -348,11 +348,21 @@ static int omap2430_musb_init(struct musb *musb) * up through ULPI. TWL4030-family PMICs include one, * which needs a driver, drivers aren't always needed. */ - if (dev-parent-of_node) + if (dev-parent-of_node) { + musb-phy = devm_phy_get(dev-parent, usb2-phy); + + /* We can't totally remove musb-xceiv as of now because +* musb core uses xceiv.state and xceiv.otg. Once we have +* a separate state machine to handle otg, these can be moved +* out of xceiv and then we can start using the generic PHY +* framework +*/ musb-xceiv = devm_usb_get_phy_by_phandle(dev-parent, usb-phy, 0); - else + } else { musb-xceiv = devm_usb_get_phy_dev(dev, 0); + musb-phy = devm_phy_get(dev, musb-phy_label); + } if (IS_ERR(musb-xceiv)) { status = PTR_ERR(musb-xceiv); @@ -364,6 +374,10 @@ static int omap2430_musb_init(struct musb *musb) return -EPROBE_DEFER; } + if (IS_ERR(musb-phy)) { + pr_err(HS USB OTG: no PHY configured\n); + return PTR_ERR(musb-phy); + } musb-isr = omap2430_musb_interrupt; status = pm_runtime_get_sync(dev); @@ -397,7 +411,7 @@ static int omap2430_musb_init(struct musb *musb) if (glue-status != OMAP_MUSB_UNKNOWN) omap_musb_set_mailbox(glue); - usb_phy_init(musb-xceiv); + phy_init(musb-phy); pm_runtime_put_noidle(musb-controller); return 0; @@ -460,6 +474,7 @@ static int omap2430_musb_exit(struct musb *musb) del_timer_sync(musb_idle_timer); omap2430_low_level_exit(musb); + phy_exit(musb-phy); return 0; } @@ -633,7 +648,7 @@ static int omap2430_runtime_suspend(struct device *dev) OTG_INTERFSEL); omap2430_low_level_exit(musb); - usb_phy_set_suspend(musb-xceiv, 1); + phy_power_off(musb-phy); } return 0; @@ -648,8 +663,7 @@ static int omap2430_runtime_resume(struct device *dev) omap2430_low_level_init(musb); musb_writel(musb-mregs, OTG_INTERFSEL,
[PATCH 07/15] usb: phy: omap-usb2: remove *set_suspend* callback from omap-usb2
Now that omap-usb2 is adapted to the new generic PHY framework, *set_suspend* ops can be removed from omap-usb2 driver. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com Acked-by: Felipe Balbi ba...@ti.com Reviewed-by: Sylwester Nawrocki s.nawro...@samsung.com --- drivers/usb/phy/phy-omap-usb2.c | 25 - 1 file changed, 25 deletions(-) diff --git a/drivers/usb/phy/phy-omap-usb2.c b/drivers/usb/phy/phy-omap-usb2.c index 751b30f..3f2b125 100644 --- a/drivers/usb/phy/phy-omap-usb2.c +++ b/drivers/usb/phy/phy-omap-usb2.c @@ -97,29 +97,6 @@ static int omap_usb_set_peripheral(struct usb_otg *otg, return 0; } -static int omap_usb2_suspend(struct usb_phy *x, int suspend) -{ - u32 ret; - struct omap_usb *phy = phy_to_omapusb(x); - - if (suspend !phy-is_suspended) { - omap_control_usb_phy_power(phy-control_dev, 0); - pm_runtime_put_sync(phy-dev); - phy-is_suspended = 1; - } else if (!suspend phy-is_suspended) { - ret = pm_runtime_get_sync(phy-dev); - if (ret 0) { - dev_err(phy-dev, get_sync failed with err %d\n, - ret); - return ret; - } - omap_control_usb_phy_power(phy-control_dev, 1); - phy-is_suspended = 0; - } - - return 0; -} - static int omap_usb_power_off(struct phy *x) { struct omap_usb *phy = phy_get_drvdata(x); @@ -167,7 +144,6 @@ static int omap_usb2_probe(struct platform_device *pdev) phy-phy.dev= phy-dev; phy-phy.label = omap-usb2; - phy-phy.set_suspend= omap_usb2_suspend; phy-phy.otg= otg; phy-phy.type = USB_PHY_TYPE_USB2; @@ -182,7 +158,6 @@ static int omap_usb2_probe(struct platform_device *pdev) return -ENODEV; } - phy-is_suspended = 1; omap_control_usb_phy_power(phy-control_dev, 0); otg-set_host = omap_usb_set_host; -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 04/15] ARM: OMAP: USB: Add phy binding information
In order for controllers to get PHY in case of non dt boot, the phy binding information (phy device name) should be added in the platform data of the controller. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com Reviewed-by: Sylwester Nawrocki s.nawro...@samsung.com Acked-by: Felipe Balbi ba...@ti.com --- arch/arm/mach-omap2/usb-musb.c |3 +++ include/linux/usb/musb.h |3 +++ 2 files changed, 6 insertions(+) diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c index 8c4de27..6aa7cbf 100644 --- a/arch/arm/mach-omap2/usb-musb.c +++ b/arch/arm/mach-omap2/usb-musb.c @@ -85,6 +85,9 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data) musb_plat.mode = board_data-mode; musb_plat.extvbus = board_data-extvbus; + if (cpu_is_omap34xx()) + musb_plat.phy_label = twl4030; + if (soc_is_am35xx()) { oh_name = am35x_otg_hs; name = musb-am35x; diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h index 053c268..596f8c8 100644 --- a/include/linux/usb/musb.h +++ b/include/linux/usb/musb.h @@ -104,6 +104,9 @@ struct musb_hdrc_platform_data { /* for clk_get() */ const char *clock; + /* phy label */ + const char *phy_label; + /* (HOST or OTG) switch VBUS on/off */ int (*set_vbus)(struct device *dev, int is_on); -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 11/15] exynos4-is: Use the generic MIPI CSIS PHY driver
From: Sylwester Nawrocki s.nawro...@samsung.com Use the generic PHY API instead of the platform callback to control the MIPI CSIS DPHY. The 'phy_label' field is added to the platform data structure to allow PHY lookup on non-dt platforms Signed-off-by: Sylwester Nawrocki s.nawro...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com Acked-by: Felipe Balbi ba...@ti.com Acked-by: Mauro Carvalho Chehab mche...@redhat.com Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/media/platform/exynos4-is/mipi-csis.c | 16 +--- include/linux/platform_data/mipi-csis.h | 11 ++- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c index 0914230..94028ce 100644 --- a/drivers/media/platform/exynos4-is/mipi-csis.c +++ b/drivers/media/platform/exynos4-is/mipi-csis.c @@ -20,6 +20,7 @@ #include linux/memory.h #include linux/module.h #include linux/of.h +#include linux/phy/phy.h #include linux/platform_data/mipi-csis.h #include linux/platform_device.h #include linux/pm_runtime.h @@ -180,6 +181,7 @@ struct csis_drvdata { * @sd: v4l2_subdev associated with CSIS device instance * @index: the hardware instance index * @pdev: CSIS platform device + * @phy: pointer to the CSIS generic PHY * @regs: mmaped I/O registers memory * @supplies: CSIS regulator supplies * @clock: CSIS clocks @@ -203,6 +205,8 @@ struct csis_state { struct v4l2_subdev sd; u8 index; struct platform_device *pdev; + struct phy *phy; + const char *phy_label; void __iomem *regs; struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES]; struct clk *clock[NUM_CSIS_CLOCKS]; @@ -742,6 +746,7 @@ static int s5pcsis_get_platform_data(struct platform_device *pdev, state-index = max(0, pdev-id); state-max_num_lanes = state-index ? CSIS1_MAX_LANES : CSIS0_MAX_LANES; + state-phy_label = pdata-phy_label; return 0; } @@ -779,8 +784,9 @@ static int s5pcsis_parse_dt(struct platform_device *pdev, samsung,csis-wclk); state-num_lanes = endpoint.bus.mipi_csi2.num_data_lanes; - of_node_put(node); + + state-phy_label = csis; return 0; } #else @@ -829,6 +835,10 @@ static int s5pcsis_probe(struct platform_device *pdev) return -EINVAL; } + state-phy = devm_phy_get(dev, state-phy_label); + if (IS_ERR(state-phy)) + return PTR_ERR(state-phy); + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); state-regs = devm_ioremap_resource(dev, mem_res); if (IS_ERR(state-regs)) @@ -922,7 +932,7 @@ static int s5pcsis_pm_suspend(struct device *dev, bool runtime) mutex_lock(state-lock); if (state-flags ST_POWERED) { s5pcsis_stop_stream(state); - ret = s5p_csis_phy_enable(state-index, false); + ret = phy_power_off(state-phy); if (ret) goto unlock; ret = regulator_bulk_disable(CSIS_NUM_SUPPLIES, @@ -958,7 +968,7 @@ static int s5pcsis_pm_resume(struct device *dev, bool runtime) state-supplies); if (ret) goto unlock; - ret = s5p_csis_phy_enable(state-index, true); + ret = phy_power_on(state-phy); if (!ret) { state-flags |= ST_POWERED; } else { diff --git a/include/linux/platform_data/mipi-csis.h b/include/linux/platform_data/mipi-csis.h index bf34e17..9214317 100644 --- a/include/linux/platform_data/mipi-csis.h +++ b/include/linux/platform_data/mipi-csis.h @@ -17,21 +17,14 @@ * @wclk_source: CSI wrapper clock selection: 0 - bus clock, 1 - ext. SCLK_CAM * @lanes: number of data lanes used * @hs_settle: HS-RX settle time + * @phy_label: the generic PHY label */ struct s5p_platform_mipi_csis { unsigned long clk_rate; u8 wclk_source; u8 lanes; u8 hs_settle; + const char *phy_label; }; -/** - * s5p_csis_phy_enable - global MIPI-CSI receiver D-PHY control - * @id: MIPI-CSIS harware instance index (0...1) - * @on: true to enable D-PHY and deassert its reset - * false to disable D-PHY - * @return: 0 on success, or negative error code on failure - */ -int s5p_csis_phy_enable(int id, bool on); - #endif /* __PLAT_SAMSUNG_MIPI_CSIS_H_ */ -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 10/15] video: exynos_mipi_dsim: Use the generic PHY driver
From: Sylwester Nawrocki s.nawro...@samsung.com Use the generic PHY API instead of the platform callback to control the MIPI DSIM DPHY. The 'phy_label' field is added to the platform data structure to allow PHY lookup on non-dt platforms. Signed-off-by: Sylwester Nawrocki s.nawro...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com Acked-by: Felipe Balbi ba...@ti.com Acked-by: Donghwa Lee dh09@samsung.com Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/video/exynos/exynos_mipi_dsi.c | 19 ++- include/video/exynos_mipi_dsim.h |6 -- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/exynos/exynos_mipi_dsi.c index 32e5406..248e444 100644 --- a/drivers/video/exynos/exynos_mipi_dsi.c +++ b/drivers/video/exynos/exynos_mipi_dsi.c @@ -30,6 +30,7 @@ #include linux/interrupt.h #include linux/kthread.h #include linux/notifier.h +#include linux/phy/phy.h #include linux/regulator/consumer.h #include linux/pm_runtime.h #include linux/err.h @@ -156,8 +157,7 @@ static int exynos_mipi_dsi_blank_mode(struct mipi_dsim_device *dsim, int power) exynos_mipi_regulator_enable(dsim); /* enable MIPI-DSI PHY. */ - if (dsim-pd-phy_enable) - dsim-pd-phy_enable(pdev, true); + phy_power_on(dsim-phy); clk_enable(dsim-clock); @@ -373,6 +373,10 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev) return ret; } + dsim-phy = devm_phy_get(pdev-dev, dsim_pd-phy_label); + if (IS_ERR(dsim-phy)) + return PTR_ERR(dsim-phy); + dsim-clock = devm_clk_get(pdev-dev, dsim0); if (IS_ERR(dsim-clock)) { dev_err(pdev-dev, failed to get dsim clock source\n); @@ -439,8 +443,7 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev) exynos_mipi_regulator_enable(dsim); /* enable MIPI-DSI PHY. */ - if (dsim-pd-phy_enable) - dsim-pd-phy_enable(pdev, true); + phy_power_on(dsim-phy); exynos_mipi_update_cfg(dsim); @@ -504,9 +507,8 @@ static int exynos_mipi_dsi_suspend(struct device *dev) if (client_drv client_drv-suspend) client_drv-suspend(client_dev); - /* enable MIPI-DSI PHY. */ - if (dsim-pd-phy_enable) - dsim-pd-phy_enable(pdev, false); + /* disable MIPI-DSI PHY. */ + phy_power_off(dsim-phy); clk_disable(dsim-clock); @@ -536,8 +538,7 @@ static int exynos_mipi_dsi_resume(struct device *dev) exynos_mipi_regulator_enable(dsim); /* enable MIPI-DSI PHY. */ - if (dsim-pd-phy_enable) - dsim-pd-phy_enable(pdev, true); + phy_power_on(dsim-phy); clk_enable(dsim-clock); diff --git a/include/video/exynos_mipi_dsim.h b/include/video/exynos_mipi_dsim.h index 89dc88a..0e7e43b 100644 --- a/include/video/exynos_mipi_dsim.h +++ b/include/video/exynos_mipi_dsim.h @@ -216,6 +216,7 @@ struct mipi_dsim_config { * automatically. * @e_clk_src: select byte clock source. * @pd: pointer to MIPI-DSI driver platform data. + * @phy: pointer to the generic PHY */ struct mipi_dsim_device { struct device *dev; @@ -236,6 +237,7 @@ struct mipi_dsim_device { boolsuspended; struct mipi_dsim_platform_data *pd; + struct phy *phy; }; /* @@ -248,7 +250,7 @@ struct mipi_dsim_device { * @enabled: indicate whether mipi controller got enabled or not. * @lcd_panel_info: pointer for lcd panel specific structure. * this structure specifies width, height, timing and polarity and so on. - * @phy_enable: pointer to a callback controlling D-PHY enable/reset + * @phy_label: the generic PHY label */ struct mipi_dsim_platform_data { charlcd_panel_name[PANEL_NAME_SIZE]; @@ -257,7 +259,7 @@ struct mipi_dsim_platform_data { unsigned intenabled; void*lcd_panel_info; - int (*phy_enable)(struct platform_device *pdev, bool on); + const char *phy_label; }; /* -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 08/15] usb: phy: twl4030-usb: remove *set_suspend* and *phy_init* ops
Now that twl4030-usb is adapted to the new generic PHY framework, *set_suspend* and *phy_init* ops can be removed from twl4030-usb driver. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com Acked-by: Felipe Balbi ba...@ti.com Reviewed-by: Sylwester Nawrocki s.nawro...@samsung.com --- drivers/usb/phy/phy-twl4030-usb.c | 57 + 1 file changed, 13 insertions(+), 44 deletions(-) diff --git a/drivers/usb/phy/phy-twl4030-usb.c b/drivers/usb/phy/phy-twl4030-usb.c index 9051756..44f8b1b 100644 --- a/drivers/usb/phy/phy-twl4030-usb.c +++ b/drivers/usb/phy/phy-twl4030-usb.c @@ -422,25 +422,20 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on) } } -static void twl4030_phy_suspend(struct twl4030_usb *twl, int controller_off) +static int twl4030_phy_power_off(struct phy *phy) { + struct twl4030_usb *twl = phy_get_drvdata(phy); + if (twl-asleep) - return; + return 0; twl4030_phy_power(twl, 0); twl-asleep = 1; dev_dbg(twl-dev, %s\n, __func__); -} - -static int twl4030_phy_power_off(struct phy *phy) -{ - struct twl4030_usb *twl = phy_get_drvdata(phy); - - twl4030_phy_suspend(twl, 0); return 0; } -static void __twl4030_phy_resume(struct twl4030_usb *twl) +static void __twl4030_phy_power_on(struct twl4030_usb *twl) { twl4030_phy_power(twl, 1); twl4030_i2c_access(twl, 1); @@ -449,11 +444,13 @@ static void __twl4030_phy_resume(struct twl4030_usb *twl) twl4030_i2c_access(twl, 0); } -static void twl4030_phy_resume(struct twl4030_usb *twl) +static int twl4030_phy_power_on(struct phy *phy) { + struct twl4030_usb *twl = phy_get_drvdata(phy); + if (!twl-asleep) - return; - __twl4030_phy_resume(twl); + return 0; + __twl4030_phy_power_on(twl); twl-asleep = 0; dev_dbg(twl-dev, %s\n, __func__); @@ -466,13 +463,6 @@ static void twl4030_phy_resume(struct twl4030_usb *twl) cancel_delayed_work(twl-id_workaround_work); schedule_delayed_work(twl-id_workaround_work, HZ); } -} - -static int twl4030_phy_power_on(struct phy *phy) -{ - struct twl4030_usb *twl = phy_get_drvdata(phy); - - twl4030_phy_resume(twl); return 0; } @@ -604,9 +594,9 @@ static void twl4030_id_workaround_work(struct work_struct *work) } } -static int twl4030_usb_phy_init(struct usb_phy *phy) +static int twl4030_phy_init(struct phy *phy) { - struct twl4030_usb *twl = phy_to_twl(phy); + struct twl4030_usb *twl = phy_get_drvdata(phy); enum omap_musb_vbus_id_status status; /* @@ -621,32 +611,13 @@ static int twl4030_usb_phy_init(struct usb_phy *phy) if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID) { omap_musb_mailbox(twl-linkstat); - twl4030_phy_resume(twl); + twl4030_phy_power_on(phy); } sysfs_notify(twl-dev-kobj, NULL, vbus); return 0; } -static int twl4030_phy_init(struct phy *phy) -{ - struct twl4030_usb *twl = phy_get_drvdata(phy); - - return twl4030_usb_phy_init(twl-phy); -} - -static int twl4030_set_suspend(struct usb_phy *x, int suspend) -{ - struct twl4030_usb *twl = phy_to_twl(x); - - if (suspend) - twl4030_phy_suspend(twl, 1); - else - twl4030_phy_resume(twl); - - return 0; -} - static int twl4030_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) { @@ -717,8 +688,6 @@ static int twl4030_usb_probe(struct platform_device *pdev) twl-phy.label = twl4030; twl-phy.otg= otg; twl-phy.type = USB_PHY_TYPE_USB2; - twl-phy.set_suspend= twl4030_set_suspend; - twl-phy.init = twl4030_usb_phy_init; otg-phy= twl-phy; otg-set_host = twl4030_set_host; -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 03/15] usb: phy: twl4030: use the new generic PHY framework
Used the generic PHY framework API to create the PHY. For powering on and powering off the PHY, power_on and power_off ops are used. Once the MUSB OMAP glue is adapted to the new framework, the suspend and resume ops of usb phy library will be removed. However using the old usb phy library cannot be completely removed because otg is intertwined with phy and moving to the new framework completely will break otg. Once we have a separate otg state machine, we can get rid of the usb phy library. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com Acked-by: Felipe Balbi ba...@ti.com Reviewed-by: Sylwester Nawrocki s.nawro...@samsung.com --- drivers/usb/phy/phy-twl4030-usb.c | 50 - 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/drivers/usb/phy/phy-twl4030-usb.c b/drivers/usb/phy/phy-twl4030-usb.c index 8f78d2d..9051756 100644 --- a/drivers/usb/phy/phy-twl4030-usb.c +++ b/drivers/usb/phy/phy-twl4030-usb.c @@ -33,6 +33,7 @@ #include linux/io.h #include linux/delay.h #include linux/usb/otg.h +#include linux/phy/phy.h #include linux/usb/musb-omap.h #include linux/usb/ulpi.h #include linux/i2c/twl.h @@ -431,6 +432,14 @@ static void twl4030_phy_suspend(struct twl4030_usb *twl, int controller_off) dev_dbg(twl-dev, %s\n, __func__); } +static int twl4030_phy_power_off(struct phy *phy) +{ + struct twl4030_usb *twl = phy_get_drvdata(phy); + + twl4030_phy_suspend(twl, 0); + return 0; +} + static void __twl4030_phy_resume(struct twl4030_usb *twl) { twl4030_phy_power(twl, 1); @@ -459,6 +468,14 @@ static void twl4030_phy_resume(struct twl4030_usb *twl) } } +static int twl4030_phy_power_on(struct phy *phy) +{ + struct twl4030_usb *twl = phy_get_drvdata(phy); + + twl4030_phy_resume(twl); + return 0; +} + static int twl4030_usb_ldo_init(struct twl4030_usb *twl) { /* Enable writing to power configuration registers */ @@ -602,13 +619,22 @@ static int twl4030_usb_phy_init(struct usb_phy *phy) status = twl4030_usb_linkstat(twl); twl-linkstat = status; - if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID) + if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID) { omap_musb_mailbox(twl-linkstat); + twl4030_phy_resume(twl); + } sysfs_notify(twl-dev-kobj, NULL, vbus); return 0; } +static int twl4030_phy_init(struct phy *phy) +{ + struct twl4030_usb *twl = phy_get_drvdata(phy); + + return twl4030_usb_phy_init(twl-phy); +} + static int twl4030_set_suspend(struct usb_phy *x, int suspend) { struct twl4030_usb *twl = phy_to_twl(x); @@ -646,13 +672,22 @@ static int twl4030_set_host(struct usb_otg *otg, struct usb_bus *host) return 0; } +static const struct phy_ops ops = { + .init = twl4030_phy_init, + .power_on = twl4030_phy_power_on, + .power_off = twl4030_phy_power_off, + .owner = THIS_MODULE, +}; + static int twl4030_usb_probe(struct platform_device *pdev) { struct twl4030_usb_data *pdata = pdev-dev.platform_data; struct twl4030_usb *twl; + struct phy *phy; int status, err; struct usb_otg *otg; struct device_node *np = pdev-dev.of_node; + struct phy_provider *phy_provider; twl = devm_kzalloc(pdev-dev, sizeof *twl, GFP_KERNEL); if (!twl) @@ -689,6 +724,19 @@ static int twl4030_usb_probe(struct platform_device *pdev) otg-set_host = twl4030_set_host; otg-set_peripheral = twl4030_set_peripheral; + phy_provider = devm_of_phy_provider_register(twl-dev, + of_phy_simple_xlate); + if (IS_ERR(phy_provider)) + return PTR_ERR(phy_provider); + + phy = devm_phy_create(twl-dev, 0, ops, twl4030); + if (IS_ERR(phy)) { + dev_dbg(pdev-dev, Failed to create PHY\n); + return PTR_ERR(phy); + } + + phy_set_drvdata(phy, twl); + /* init spinlock for workqueue */ spin_lock_init(twl-lock); -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/15] drivers: phy: add generic PHY framework
The PHY framework provides a set of APIs for the PHY drivers to create/destroy a PHY and APIs for the PHY users to obtain a reference to the PHY with or without using phandle. For dt-boot, the PHY drivers should also register *PHY provider* with the framework. PHY drivers should create the PHY by passing id and ops like init, exit, power_on and power_off. This framework is also pm runtime enabled. The documentation for the generic PHY framework is added in Documentation/phy.txt and the documentation for dt binding can be found at Documentation/devicetree/bindings/phy/phy-bindings.txt Signed-off-by: Kishon Vijay Abraham I kis...@ti.com Acked-by: Felipe Balbi ba...@ti.com Tested-by: Sylwester Nawrocki s.nawro...@samsung.com --- .../devicetree/bindings/phy/phy-bindings.txt | 66 +++ Documentation/phy.txt | 129 + MAINTAINERS|7 + drivers/Kconfig|2 + drivers/Makefile |2 + drivers/phy/Kconfig| 13 + drivers/phy/Makefile |5 + drivers/phy/phy-core.c | 544 include/linux/phy/phy.h| 344 + 9 files changed, 1112 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/phy-bindings.txt create mode 100644 Documentation/phy.txt create mode 100644 drivers/phy/Kconfig create mode 100644 drivers/phy/Makefile create mode 100644 drivers/phy/phy-core.c create mode 100644 include/linux/phy/phy.h diff --git a/Documentation/devicetree/bindings/phy/phy-bindings.txt b/Documentation/devicetree/bindings/phy/phy-bindings.txt new file mode 100644 index 000..8ae844f --- /dev/null +++ b/Documentation/devicetree/bindings/phy/phy-bindings.txt @@ -0,0 +1,66 @@ +This document explains only the device tree data binding. For general +information about PHY subsystem refer to Documentation/phy.txt + +PHY device node +=== + +Required Properties: +#phy-cells:Number of cells in a PHY specifier; The meaning of all those + cells is defined by the binding for the phy node. The PHY + provider can use the values in cells to find the appropriate + PHY. + +For example: + +phys: phy { +compatible = xxx; +reg = ...; +. +. +#phy-cells = 1; +. +. +}; + +That node describes an IP block (PHY provider) that implements 2 different PHYs. +In order to differentiate between these 2 PHYs, an additonal specifier should be +given while trying to get a reference to it. + +PHY user node += + +Required Properties: +phys : the phandle for the PHY device (used by the PHY subsystem) +phy-names : the names of the PHY corresponding to the PHYs present in the + *phys* phandle + +Example 1: +usb1: usb_otg_ss@xxx { +compatible = xxx; +reg = xxx; +. +. +phys = usb2_phy, usb3_phy; +phy-names = usb2phy, usb3phy; +. +. +}; + +This node represents a controller that uses two PHYs, one for usb2 and one for +usb3. + +Example 2: +usb2: usb_otg_ss@xxx { +compatible = xxx; +reg = xxx; +. +. +phys = phys 1; +phy-names = usbphy; +. +. +}; + +This node represents a controller that uses one of the PHYs of the PHY provider +device defined previously. Note that the phy handle has an additional specifier +1 to differentiate between the two PHYs. diff --git a/Documentation/phy.txt b/Documentation/phy.txt new file mode 100644 index 000..05f8fda --- /dev/null +++ b/Documentation/phy.txt @@ -0,0 +1,129 @@ + PHY SUBSYSTEM + Kishon Vijay Abraham I kis...@ti.com + +This document explains the Generic PHY Framework along with the APIs provided, +and how-to-use. + +1. Introduction + +*PHY* is the abbreviation for physical layer. It is used to connect a device +to the physical medium e.g., the USB controller has a PHY to provide functions +such as serialization, de-serialization, encoding, decoding and is responsible +for obtaining the required data transmission rate. Note that some USB +controllers have PHY functionality embedded into it and others use an external +PHY. Other peripherals that use PHY include Wireless LAN, Ethernet, +SATA etc. + +The intention of creating this framework is to bring the PHY drivers spread +all over the Linux kernel to drivers/phy to increase code re-use and for +better code maintainability. + +This framework will be of use only to devices that use external PHY (PHY +functionality is not embedded within the controller). + +2. Registering/Unregistering the PHY provider + +PHY provider refers to an entity that implements one or more PHY instances. +For the simple case where the PHY provider implements only a single instance of +the PHY, the framework provides its own implementation of of_xlate in
[PATCH 00/15] PHY framework
Added a generic PHY framework that provides a set of APIs for the PHY drivers to create/destroy a PHY and APIs for the PHY users to obtain a reference to the PHY with or without using phandle. This framework will be of use only to devices that uses external PHY (PHY functionality is not embedded within the controller). The intention of creating this framework is to bring the phy drivers spread all over the Linux kernel to drivers/phy to increase code re-use and to increase code maintainability. Comments to make PHY as bus wasn't done because PHY devices can be part of other bus and making a same device attached to multiple bus leads to bad design. If the PHY driver has to send notification on connect/disconnect, the PHY driver should make use of the extcon framework. Using this susbsystem to use extcon framwork will have to be analysed. Exynos MIPI CSIS/DSIM PHY and Displayport PHY have started using this framework. Have included those patches also in this series. twl4030-usb and omap-usb2 have also been adapted to this framework. These patches are also available @ git://gitorious.org/linuxphy/linuxphy.git tags/phy-for-v3.12 Jingoo Han (3): phy: Add driver for Exynos DP PHY video: exynos_dp: remove non-DT support for Exynos Display Port video: exynos_dp: Use the generic PHY driver Kishon Vijay Abraham I (8): drivers: phy: add generic PHY framework usb: phy: omap-usb2: use the new generic PHY framework usb: phy: twl4030: use the new generic PHY framework ARM: OMAP: USB: Add phy binding information ARM: dts: omap: update usb_otg_hs data usb: musb: omap2430: use the new generic PHY framework usb: phy: omap-usb2: remove *set_suspend* callback from omap-usb2 usb: phy: twl4030-usb: remove *set_suspend* and *phy_init* ops Sylwester Nawrocki (4): phy: Add driver for Exynos MIPI CSIS/DSIM DPHYs video: exynos_mipi_dsim: Use the generic PHY driver exynos4-is: Use the generic MIPI CSIS PHY driver ARM: Samsung: Remove the MIPI PHY setup code .../devicetree/bindings/phy/phy-bindings.txt | 66 +++ .../devicetree/bindings/phy/samsung-phy.txt| 22 + Documentation/devicetree/bindings/usb/omap-usb.txt |5 + Documentation/devicetree/bindings/usb/usb-phy.txt |6 + .../devicetree/bindings/video/exynos_dp.txt| 18 +- Documentation/phy.txt | 129 + MAINTAINERS|7 + arch/arm/boot/dts/omap3-beagle-xm.dts |2 + arch/arm/boot/dts/omap3-evm.dts|2 + arch/arm/boot/dts/omap3-overo.dtsi |2 + arch/arm/boot/dts/omap4.dtsi |3 + arch/arm/boot/dts/twl4030.dtsi |1 + arch/arm/mach-exynos/include/mach/regs-pmu.h |5 - arch/arm/mach-omap2/usb-musb.c |3 + arch/arm/mach-s5pv210/include/mach/regs-clock.h|4 - arch/arm/plat-samsung/Kconfig |5 - arch/arm/plat-samsung/Makefile |1 - arch/arm/plat-samsung/setup-mipiphy.c | 60 --- drivers/Kconfig|2 + drivers/Makefile |2 + drivers/media/platform/exynos4-is/mipi-csis.c | 16 +- drivers/phy/Kconfig| 28 + drivers/phy/Makefile |7 + drivers/phy/phy-core.c | 544 drivers/phy/phy-exynos-dp-video.c | 111 drivers/phy/phy-exynos-mipi-video.c| 169 ++ drivers/usb/musb/Kconfig |1 + drivers/usb/musb/musb_core.c |1 + drivers/usb/musb/musb_core.h |3 + drivers/usb/musb/omap2430.c| 26 +- drivers/usb/phy/Kconfig|1 + drivers/usb/phy/phy-omap-usb2.c| 60 ++- drivers/usb/phy/phy-twl4030-usb.c | 63 ++- drivers/video/exynos/Kconfig |2 +- drivers/video/exynos/exynos_dp_core.c | 132 ++--- drivers/video/exynos/exynos_dp_core.h | 110 drivers/video/exynos/exynos_dp_reg.c |2 - drivers/video/exynos/exynos_mipi_dsi.c | 19 +- include/linux/phy/phy.h| 344 + include/linux/platform_data/mipi-csis.h| 11 +- include/linux/usb/musb.h |3 + include/video/exynos_dp.h | 131 - include/video/exynos_mipi_dsim.h |6 +- 43 files changed, 1746 insertions(+), 389 deletions(-) create mode 100644 Documentation/devicetree/bindings/phy/phy-bindings.txt create mode 100644 Documentation/devicetree/bindings/phy/samsung-phy.txt create mode 100644 Documentation/phy.txt delete mode 100644
[PATCH 02/15] usb: phy: omap-usb2: use the new generic PHY framework
Used the generic PHY framework API to create the PHY. Now the power off and power on are done in omap_usb_power_off and omap_usb_power_on respectively. However using the old USB PHY library cannot be completely removed because OTG is intertwined with PHY and moving to the new framework will break OTG. Once we have a separate OTG state machine, we can get rid of the USB PHY library. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com Reviewed-by: Sylwester Nawrocki s.nawro...@samsung.com Acked-by: Felipe Balbi ba...@ti.com --- drivers/usb/phy/Kconfig |1 + drivers/usb/phy/phy-omap-usb2.c | 45 +++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 3622fff..cc55993 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -75,6 +75,7 @@ config OMAP_CONTROL_USB config OMAP_USB2 tristate OMAP USB2 PHY Driver depends on ARCH_OMAP2PLUS + depends on GENERIC_PHY select OMAP_CONTROL_USB help Enable this to support the transceiver that is part of SOC. This diff --git a/drivers/usb/phy/phy-omap-usb2.c b/drivers/usb/phy/phy-omap-usb2.c index 844ab68..751b30f 100644 --- a/drivers/usb/phy/phy-omap-usb2.c +++ b/drivers/usb/phy/phy-omap-usb2.c @@ -28,6 +28,7 @@ #include linux/pm_runtime.h #include linux/delay.h #include linux/usb/omap_control_usb.h +#include linux/phy/phy.h /** * omap_usb2_set_comparator - links the comparator present in the sytem with @@ -119,10 +120,36 @@ static int omap_usb2_suspend(struct usb_phy *x, int suspend) return 0; } +static int omap_usb_power_off(struct phy *x) +{ + struct omap_usb *phy = phy_get_drvdata(x); + + omap_control_usb_phy_power(phy-control_dev, 0); + + return 0; +} + +static int omap_usb_power_on(struct phy *x) +{ + struct omap_usb *phy = phy_get_drvdata(x); + + omap_control_usb_phy_power(phy-control_dev, 1); + + return 0; +} + +static struct phy_ops ops = { + .power_on = omap_usb_power_on, + .power_off = omap_usb_power_off, + .owner = THIS_MODULE, +}; + static int omap_usb2_probe(struct platform_device *pdev) { struct omap_usb *phy; + struct phy *generic_phy; struct usb_otg *otg; + struct phy_provider *phy_provider; phy = devm_kzalloc(pdev-dev, sizeof(*phy), GFP_KERNEL); if (!phy) { @@ -144,6 +171,11 @@ static int omap_usb2_probe(struct platform_device *pdev) phy-phy.otg= otg; phy-phy.type = USB_PHY_TYPE_USB2; + phy_provider = devm_of_phy_provider_register(phy-dev, + of_phy_simple_xlate); + if (IS_ERR(phy_provider)) + return PTR_ERR(phy_provider); + phy-control_dev = omap_get_control_dev(); if (IS_ERR(phy-control_dev)) { dev_dbg(pdev-dev, Failed to get control device\n); @@ -159,6 +191,15 @@ static int omap_usb2_probe(struct platform_device *pdev) otg-start_srp = omap_usb_start_srp; otg-phy= phy-phy; + platform_set_drvdata(pdev, phy); + pm_runtime_enable(phy-dev); + + generic_phy = devm_phy_create(phy-dev, 0, ops, omap-usb2); + if (IS_ERR(generic_phy)) + return PTR_ERR(generic_phy); + + phy_set_drvdata(generic_phy, phy); + phy-wkupclk = devm_clk_get(phy-dev, usb_phy_cm_clk32k); if (IS_ERR(phy-wkupclk)) { dev_err(pdev-dev, unable to get usb_phy_cm_clk32k\n); @@ -174,10 +215,6 @@ static int omap_usb2_probe(struct platform_device *pdev) usb_add_phy_dev(phy-phy); - platform_set_drvdata(pdev, phy); - - pm_runtime_enable(phy-dev); - return 0; } -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 04/15] ARM: OMAP: USB: Add phy binding information
* Kishon Vijay Abraham I kis...@ti.com [130717 23:53]: In order for controllers to get PHY in case of non dt boot, the phy binding information (phy device name) should be added in the platform data of the controller. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com Reviewed-by: Sylwester Nawrocki s.nawro...@samsung.com Acked-by: Felipe Balbi ba...@ti.com --- arch/arm/mach-omap2/usb-musb.c |3 +++ include/linux/usb/musb.h |3 +++ 2 files changed, 6 insertions(+) diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c index 8c4de27..6aa7cbf 100644 --- a/arch/arm/mach-omap2/usb-musb.c +++ b/arch/arm/mach-omap2/usb-musb.c @@ -85,6 +85,9 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data) musb_plat.mode = board_data-mode; musb_plat.extvbus = board_data-extvbus; + if (cpu_is_omap34xx()) + musb_plat.phy_label = twl4030; + if (soc_is_am35xx()) { oh_name = am35x_otg_hs; name = musb-am35x; I don't think there's a USB PHY on non-twl4030 chips, so this should be OK: Acked-by: Tony Lindgren t...@atomide.com diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h index 053c268..596f8c8 100644 --- a/include/linux/usb/musb.h +++ b/include/linux/usb/musb.h @@ -104,6 +104,9 @@ struct musb_hdrc_platform_data { /* for clk_get() */ const char *clock; + /* phy label */ + const char *phy_label; + /* (HOST or OTG) switch VBUS on/off */ int (*set_vbus)(struct device *dev, int is_on); -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 05/15] ARM: dts: omap: update usb_otg_hs data
* Kishon Vijay Abraham I kis...@ti.com [130717 23:53]: Updated the usb_otg_hs dt data to include the *phy* and *phy-names* binding in order for the driver to use the new generic PHY framework. Also updated the Documentation to include the binding information. The PHY binding information can be found at Documentation/devicetree/bindings/phy/phy-bindings.txt Signed-off-by: Kishon Vijay Abraham I kis...@ti.com Acked-by: Felipe Balbi ba...@ti.com Reviewed-by: Sylwester Nawrocki s.nawro...@samsung.com In general the .dts changes should be separate to avoid pointless merge conflicts. But sounds like things will stop working for USB unless we do it like this so: Acked-by: Tony Lindgren t...@atomide.com --- Documentation/devicetree/bindings/usb/omap-usb.txt |5 + Documentation/devicetree/bindings/usb/usb-phy.txt |6 ++ arch/arm/boot/dts/omap3-beagle-xm.dts |2 ++ arch/arm/boot/dts/omap3-evm.dts|2 ++ arch/arm/boot/dts/omap3-overo.dtsi |2 ++ arch/arm/boot/dts/omap4.dtsi |3 +++ arch/arm/boot/dts/twl4030.dtsi |1 + 7 files changed, 21 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/omap-usb.txt b/Documentation/devicetree/bindings/usb/omap-usb.txt index 57e71f6..825790d 100644 --- a/Documentation/devicetree/bindings/usb/omap-usb.txt +++ b/Documentation/devicetree/bindings/usb/omap-usb.txt @@ -19,6 +19,9 @@ OMAP MUSB GLUE - power : Should be 50. This signifies the controller can supply up to 100mA when operating in host mode. - usb-phy : the phandle for the PHY device + - phys : the phandle for the PHY device (used by generic PHY framework) + - phy-names : the names of the PHY corresponding to the PHYs present in the + *phy* phandle. Optional properties: - ctrl-module : phandle of the control module this glue uses to write to @@ -33,6 +36,8 @@ usb_otg_hs: usb_otg_hs@4a0ab000 { num-eps = 16; ram-bits = 12; ctrl-module = omap_control_usb; + phys = usb2_phy; + phy-names = usb2-phy; }; Board specific device node entry diff --git a/Documentation/devicetree/bindings/usb/usb-phy.txt b/Documentation/devicetree/bindings/usb/usb-phy.txt index 61496f5..c0245c8 100644 --- a/Documentation/devicetree/bindings/usb/usb-phy.txt +++ b/Documentation/devicetree/bindings/usb/usb-phy.txt @@ -5,6 +5,8 @@ OMAP USB2 PHY Required properties: - compatible: Should be ti,omap-usb2 - reg : Address and length of the register set for the device. + - #phy-cells: determine the number of cells that should be given in the + phandle while referencing this phy. Optional properties: - ctrl-module : phandle of the control module used by PHY driver to power on @@ -16,6 +18,7 @@ usb2phy@4a0ad080 { compatible = ti,omap-usb2; reg = 0x4a0ad080 0x58; ctrl-module = omap_control_usb; + #phy-cells = 0; }; OMAP USB3 PHY @@ -25,6 +28,8 @@ Required properties: - reg : Address and length of the register set for the device. - reg-names: The names of the register addresses corresponding to the registers filled in reg. + - #phy-cells: determine the number of cells that should be given in the + phandle while referencing this phy. Optional properties: - ctrl-module : phandle of the control module used by PHY driver to power on @@ -39,4 +44,5 @@ usb3phy@4a084400 { 0x4a084c00 0x40; reg-names = phy_rx, phy_tx, pll_ctrl; ctrl-module = omap_control_usb; + #phy-cells = 0; }; diff --git a/arch/arm/boot/dts/omap3-beagle-xm.dts b/arch/arm/boot/dts/omap3-beagle-xm.dts index afdb164..533b2da 100644 --- a/arch/arm/boot/dts/omap3-beagle-xm.dts +++ b/arch/arm/boot/dts/omap3-beagle-xm.dts @@ -144,6 +144,8 @@ usb_otg_hs { interface-type = 0; usb-phy = usb2_phy; + phys = usb2_phy; + phy-names = usb2-phy; mode = 3; power = 50; }; diff --git a/arch/arm/boot/dts/omap3-evm.dts b/arch/arm/boot/dts/omap3-evm.dts index 7d4329d..4134dd0 100644 --- a/arch/arm/boot/dts/omap3-evm.dts +++ b/arch/arm/boot/dts/omap3-evm.dts @@ -70,6 +70,8 @@ usb_otg_hs { interface-type = 0; usb-phy = usb2_phy; + phys = usb2_phy; + phy-names = usb2-phy; mode = 3; power = 50; }; diff --git a/arch/arm/boot/dts/omap3-overo.dtsi b/arch/arm/boot/dts/omap3-overo.dtsi index 8f1abec..a461d2f 100644 --- a/arch/arm/boot/dts/omap3-overo.dtsi +++ b/arch/arm/boot/dts/omap3-overo.dtsi @@ -76,6 +76,8 @@ usb_otg_hs { interface-type = 0; usb-phy = usb2_phy; + phys = usb2_phy; + phy-names = usb2-phy; mode = 3; power = 50; }; diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index 22d9f2b..1e8e2fe 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi @@ -520,6 +520,7 @@
Re: [PATCH 01/15] drivers: phy: add generic PHY framework
On Thu, Jul 18, 2013 at 12:16:10PM +0530, Kishon Vijay Abraham I wrote: +struct phy_provider *__of_phy_provider_register(struct device *dev, + struct module *owner, struct phy * (*of_xlate)(struct device *dev, + struct of_phandle_args *args)); +struct phy_provider *__devm_of_phy_provider_register(struct device *dev, + struct module *owner, struct phy * (*of_xlate)(struct device *dev, + struct of_phandle_args *args)) + +__of_phy_provider_register and __devm_of_phy_provider_register can be used to +register the phy_provider and it takes device, owner and of_xlate as +arguments. For the dt boot case, all PHY providers should use one of the above +2 APIs to register the PHY provider. Why do you have __ for the prefix of a public function? Is that really the way that OF handles this type of thing? --- /dev/null +++ b/drivers/phy/Kconfig @@ -0,0 +1,13 @@ +# +# PHY +# + +menuconfig GENERIC_PHY + tristate PHY Subsystem + help + Generic PHY support. + + This framework is designed to provide a generic interface for PHY + devices present in the kernel. This layer will have the generic + API by which phy drivers can create PHY using the phy framework and + phy users can obtain reference to the PHY. Again, please reverse this. The drivers that use it should select it, not depend on it, which will then enable this option. I will never know if I need to enable it, and based on your follow-on patches, if I don't, drivers that were working just fine, now disappeared from my build, which isn't nice, and a pain to notice and fix up. +/** + * phy_create() - create a new phy + * @dev: device that is creating the new phy + * @id: id of the phy + * @ops: function pointers for performing phy operations + * @label: label given to the phy + * + * Called to create a phy using phy framework. + */ +struct phy *phy_create(struct device *dev, u8 id, const struct phy_ops *ops, + const char *label) +{ + int ret; + struct phy *phy; + + if (!dev) { + dev_WARN(dev, no device provided for PHY\n); + ret = -EINVAL; + goto err0; + } + + phy = kzalloc(sizeof(*phy), GFP_KERNEL); + if (!phy) { + ret = -ENOMEM; + goto err0; + } + + device_initialize(phy-dev); + mutex_init(phy-mutex); + + phy-dev.class = phy_class; + phy-dev.parent = dev; + phy-dev.of_node = dev-of_node; + phy-id = id; + phy-ops = ops; + phy-label = kstrdup(label, GFP_KERNEL); + + ret = dev_set_name(phy-dev, %s.%d, dev_name(dev), id); Your naming is odd, no phy anywhere in it? You rely on the sender to never send a duplicate name.id pair? Why not create your own ids based on the number of phys in the system, like almost all other classes and subsystems do? +static inline int phy_pm_runtime_get(struct phy *phy) +{ + if (WARN(IS_ERR(phy), Invalid PHY reference\n)) + return -EINVAL; Why would phy ever not be valid and a error pointer? And why dump the stack if that happens, that seems really extreme. + + if (!pm_runtime_enabled(phy-dev)) + return -ENOTSUPP; + + return pm_runtime_get(phy-dev); +} This, and the other inline functions in this .h file seem huge, why are they inline and not in the .c file? There's no speed issues, and it should save space overall in the .c file. Please move them. +static inline int phy_init(struct phy *phy) +{ + int ret; + + ret = phy_pm_runtime_get_sync(phy); + if (ret 0 ret != -ENOTSUPP) + return ret; + + mutex_lock(phy-mutex); + if (phy-init_count++ == 0 phy-ops-init) { + ret = phy-ops-init(phy); + if (ret 0) { + dev_err(phy-dev, phy init failed -- %d\n, ret); + goto out; + } + } + +out: + mutex_unlock(phy-mutex); + phy_pm_runtime_put(phy); + return ret; +} + +static inline int phy_exit(struct phy *phy) +{ + int ret; + + ret = phy_pm_runtime_get_sync(phy); + if (ret 0 ret != -ENOTSUPP) + return ret; + + mutex_lock(phy-mutex); + if (--phy-init_count == 0 phy-ops-exit) { + ret = phy-ops-exit(phy); + if (ret 0) { + dev_err(phy-dev, phy exit failed -- %d\n, ret); + goto out; + } + } + +out: + mutex_unlock(phy-mutex); + phy_pm_runtime_put(phy); + return ret; +} + +static inline int phy_power_on(struct phy *phy) +{ + int ret = -ENOTSUPP; + + ret = phy_pm_runtime_get_sync(phy); + if (ret 0 ret != -ENOTSUPP) + return ret; + + mutex_lock(phy-mutex); + if (phy-power_count++ == 0 phy-ops-power_on) { + ret = phy-ops-power_on(phy); + if (ret 0) { + dev_err(phy-dev, phy
Re: [PATCH 02/15] usb: phy: omap-usb2: use the new generic PHY framework
On Thu, Jul 18, 2013 at 12:16:11PM +0530, Kishon Vijay Abraham I wrote: Used the generic PHY framework API to create the PHY. Now the power off and power on are done in omap_usb_power_off and omap_usb_power_on respectively. However using the old USB PHY library cannot be completely removed because OTG is intertwined with PHY and moving to the new framework will break OTG. Once we have a separate OTG state machine, we can get rid of the USB PHY library. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com Reviewed-by: Sylwester Nawrocki s.nawro...@samsung.com Acked-by: Felipe Balbi ba...@ti.com --- drivers/usb/phy/Kconfig |1 + drivers/usb/phy/phy-omap-usb2.c | 45 +++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 3622fff..cc55993 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -75,6 +75,7 @@ config OMAP_CONTROL_USB config OMAP_USB2 tristate OMAP USB2 PHY Driver depends on ARCH_OMAP2PLUS + depends on GENERIC_PHY select OMAP_CONTROL_USB help Enable this to support the transceiver that is part of SOC. This diff --git a/drivers/usb/phy/phy-omap-usb2.c b/drivers/usb/phy/phy-omap-usb2.c index 844ab68..751b30f 100644 --- a/drivers/usb/phy/phy-omap-usb2.c +++ b/drivers/usb/phy/phy-omap-usb2.c @@ -28,6 +28,7 @@ #include linux/pm_runtime.h #include linux/delay.h #include linux/usb/omap_control_usb.h +#include linux/phy/phy.h /** * omap_usb2_set_comparator - links the comparator present in the sytem with @@ -119,10 +120,36 @@ static int omap_usb2_suspend(struct usb_phy *x, int suspend) return 0; } +static int omap_usb_power_off(struct phy *x) +{ + struct omap_usb *phy = phy_get_drvdata(x); + + omap_control_usb_phy_power(phy-control_dev, 0); + + return 0; +} + +static int omap_usb_power_on(struct phy *x) +{ + struct omap_usb *phy = phy_get_drvdata(x); + + omap_control_usb_phy_power(phy-control_dev, 1); + + return 0; +} + +static struct phy_ops ops = { + .power_on = omap_usb_power_on, + .power_off = omap_usb_power_off, + .owner = THIS_MODULE, +}; + static int omap_usb2_probe(struct platform_device *pdev) { struct omap_usb *phy; + struct phy *generic_phy; struct usb_otg *otg; + struct phy_provider *phy_provider; phy = devm_kzalloc(pdev-dev, sizeof(*phy), GFP_KERNEL); if (!phy) { @@ -144,6 +171,11 @@ static int omap_usb2_probe(struct platform_device *pdev) phy-phy.otg= otg; phy-phy.type = USB_PHY_TYPE_USB2; + phy_provider = devm_of_phy_provider_register(phy-dev, + of_phy_simple_xlate); + if (IS_ERR(phy_provider)) + return PTR_ERR(phy_provider); + phy-control_dev = omap_get_control_dev(); if (IS_ERR(phy-control_dev)) { dev_dbg(pdev-dev, Failed to get control device\n); @@ -159,6 +191,15 @@ static int omap_usb2_probe(struct platform_device *pdev) otg-start_srp = omap_usb_start_srp; otg-phy= phy-phy; + platform_set_drvdata(pdev, phy); + pm_runtime_enable(phy-dev); + + generic_phy = devm_phy_create(phy-dev, 0, ops, omap-usb2); + if (IS_ERR(generic_phy)) + return PTR_ERR(generic_phy); So, if I have two of these controllers in my system, I can't create the second phy because the name for it will be identical to the first? That's why the phy core should handle the id, and not rely on the drivers to set it, as they have no idea how many they have in the system. thanks, greg k-h -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/4] pinctrl: Add support for additional dynamic states
* Stephen Warren swar...@wwwdotorg.org [130717 14:21]: On 07/16/2013 03:05 AM, Tony Lindgren wrote: To toggle dynamic states, let's add the optional active state in addition to the static default state. Then if the optional active state is defined, we can require that idle and sleep states cover the same pingroups as the active state. Then let's add pinctrl_check_dynamic() and pinctrl_select_dynamic() to use instead of pinctrl_select() to avoid breaking existing users. With pinctrl_check_dynamic() we can check that idle and sleep states match the active state for pingroups during init, and don't need to do it during runtime. Then with the states pre-validated, pinctrl_select_dynamic() can just toggle between the dynamic states without extra checks. Note that pinctr_select_state() still has valid use cases, such as changing states when the pins can be shared between two drivers and don't necessarily cover the same pingroups. For dynamic runtime toggling of pin states, we should eventually always use just pinctrl_select_dynamic(). diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c @@ -887,6 +887,8 @@ static void pinctrl_free(struct pinctrl *p, bool inlist) list_for_each_entry_safe(setting, n2, state-settings, node) { pinctrl_free_setting(state == p-state[PINCTRL_STATIC], setting); + pinctrl_free_setting(state == p-state[PINCTRL_DYNAMIC], +setting); This will cause pinmux_free_setting() or pinconf_free_setting() to be called twice on the setting object. Right now they don't do anything, but if they start to kfree() some dynamically-allocated data that's stored within the setting, that'll cause problems. I would suggest a loop body something more like: bool disable_setting = state == XXX || state == YYY; pinctrl_free_setting(disable_setting, setting); OK good point, I'll check it. +int pinctrl_check_dynamic(struct device *dev, struct pinctrl_state *st1, + struct pinctrl_state *st2) +{ + struct pinctrl_setting *s1, *s2; + + list_for_each_entry(s1, st1-settings, node) { ... + list_for_each_entry(s2, st2-settings, node) { ... + if (pctldev1 != pctldev2) { + dev_dbg(dev, pctldev must be the same for states\n); + return -EINVAL; + } I don't think we should require that; it's perfectly legal at the moment for some device's pinctrl configuration to include settings from multiple different pin controllers. Yes that's fine for pinctrl_select(), but let's not do that for runtime muxing. Here we want to do a one-time check during init to make sure that if active_state is defined, then the idle_state and sleep_state must match active_state for pins. This way we can avoid checking things over and over again during runtime like pinctrl_select() is currently doing. + for (i = 0; i num_pins1; i++) { + int pin1 = pins1[i]; + + for (j = 0; j num_pins2; j++) { + int pin2 = pins2[j]; + + if (pin1 == pin2) { + found++; + break; + } + } + } + + if (found != num_pins1) { I guess this make sure that every entry in the dynamic state is in the state state, but not vice-versa; the static state can affect more stuff than the dynamic state? If so, shouldn't that check be if (found != num_pins2)? The check is that idle_state and sleep_state pins must match the active_state pins. This is intentionally different from the current pinctrl_select() logic. +int pinctrl_select_dynamic(struct pinctrl *p, struct pinctrl_state *state) The body of this function is rather duplicated with pinctrl_select(). Well we may be able to make pinctrl_select() use this too, I'll take a look. Initially I'd rather not start messing with pinctrl_select() to avoid breaking existing users. @@ -1241,7 +1371,13 @@ static int pinctrl_pm_select_state(struct device *dev, struct pinctrl_state *sta return 0; if (IS_ERR(state)) return 0; /* No such state */ - ret = pinctrl_select_state(pins-p, state); + + /* Configured for proper dynamic muxing? */ I don't think proper is correct here; it's just fine not to have any dynamic configuration. Right, that's the most common case. I'll drop the proper. + if (!IS_ERR(dev-pins-active_state)) + ret = pinctrl_select_dynamic(pins-p, state); + else + ret = pinctrl_select_state(pins-p, state); Hmmm. I'm not quite sure
Re: [PATCH 3/4] pinctrl: Add support for additional dynamic states
* Stephen Warren swar...@wwwdotorg.org [130717 14:30]: On 07/16/2013 03:05 AM, Tony Lindgren wrote: To toggle dynamic states, let's add the optional active state in addition to the static default state. Then if the optional active state is defined, we can require that idle and sleep states cover the same pingroups as the active state. Then let's add pinctrl_check_dynamic() and pinctrl_select_dynamic() to use instead of pinctrl_select() to avoid breaking existing users. With pinctrl_check_dynamic() we can check that idle and sleep states match the active state for pingroups during init, and don't need to do it during runtime. Then with the states pre-validated, pinctrl_select_dynamic() can just toggle between the dynamic states without extra checks. Note that pinctr_select_state() still has valid use cases, such as changing states when the pins can be shared between two drivers and don't necessarily cover the same pingroups. For dynamic runtime toggling of pin states, we should eventually always use just pinctrl_select_dynamic(). Something in this series should edit Documentation/pinctrl.txt to explain the philosophy behind the static/dynamic state split. That philosophy and/or semantics are more important to review than the code... Sure, I'll write up something on that. Related to that, I'm worried that using pinctrl_select_state() and pinctrl_select_dynamic() appear to be mutually-exclusive options here. Not currently, but eventually I think that's a good idea. We should use pinctrl_select_state() only during init time eventually because of the diffing of states it does. Why shouldn't e.g. a pinctrl-based I2C mux also be able to do runtime PM? Does the mux setting select which states are used for runtime PM, or does runtime PM override the basic mux setting, or must the pincrl-I2C mux manually implement custom runtime-PM/pinctrl interaction since there's no generic answer to those questions? How many more custom exceptions will there be? The idea is that runtime PM will never touch the basic mux settings at all. The default state should be considered a static state that is claimed during driver probe, and released when the driver is unloaded. This is typically let's say 90% of the pins for any device. For runtime PM, we can just toggle the PM related pinctrl states as they have been verified to match the active state during init. So I don't see why pinctrl-I2C would have to do anything specific. All that is required is that the pins are grouped for the consumer driver, and we can provide some automated checks on the states for runtime PM. Regards, Tony -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/4] drivers: Add pinctrl handling for dynamic pin states
* Stephen Warren swar...@wwwdotorg.org [130717 14:28]: On 07/16/2013 03:05 AM, Tony Lindgren wrote: We want to have static pin states handled separately from dynamic pin states, so let's add optional state_active. Then if state_active is defined, let's check and make sure state_idle and state_sleep match state_active for the pin groups to avoid checking them during runtime as the active and idle pins may need to be toggled for many devices every time we enter and exit idle. +* Note that if active state is defined, sleep and idle states must +* cover the same pin groups as active state. */ dev-pins-sleep_state = pinctrl_lookup_state(dev-pins-p, PINCTRL_STATE_SLEEP); - if (IS_ERR(dev-pins-sleep_state)) + if (IS_ERR(dev-pins-sleep_state)) { /* Not supplying this state is perfectly legal */ dev_dbg(dev, no sleep pinctrl state\n); + } else if (!IS_ERR(dev-pins-active_state)) { + ret = pinctrl_check_dynamic(dev, dev-pins-active_state, + dev-pins-sleep_state); Oh, I see you're trying to check that the set of pins in the active, sleep, and idle states are identical. Right, that's to avoid any further checking during runtime for runtime PM. But I think that pinctrl_check_dynamic() only checks that one state is a subset of the other, not that the two states are equal. Instead, I think you want to comparison coded in pinctrl_check_dynamic() to be: In pinctrl_check_dynamic() we check that the pins match between the states, and the number of found pins matches the first set. I'll take a look if we check the total pins between the two sets. gen_group_list_of_pinctrl_state(s1, array1); gen_group_list_of_pinctrl_state(s2, array2); mismatch = memcmp(array1, array2, length); Well we could allocate and sort the pins, but the number of pins for runtime PM is typically very small for each pin consumer device. Typically you just need to toggle RX pin to GPIO mode for idle. And this check is only done during consumer driver probe time. So optimizing it for larger sets could be done at any point later on as needed. Regards, Tony -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 2/2] iio: twl6030-gpadc: TWL6030, TWL6032 GPADC driver
Hello Lars, On Wed, Jul 17, 2013 at 9:04 PM, Lars-Peter Clausen l...@metafoo.de wrote: +static int twl6032_calibration(struct twl6030_gpadc_data *gpadc) +{ + int chn, d1 = 0, d2 = 0, temp; + u8 trim_regs[17]; + int ret; + + ret = twl_i2c_read(TWL6030_MODULE_ID2, trim_regs + 1, + TWL6030_GPADC_TRIM1, 16); + if (ret 0) { + dev_err(gpadc-dev, calibration failed\n); + return ret; + } + + /* + * Loop to calculate the value needed for returning voltages from + * GPADC not values. + * + * gain is calculated to 3 decimal places fixed point. + */ + for (chn = 0; chn TWL6032_GPADC_MAX_CHANNELS; chn++) { + + switch (chn) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 11: + case 12: + case 13: + case 14: + /* D1 */ + d1 = (trim_regs[3] 0x1F) 2; + d1 |= (trim_regs[1] 0x06) 1; + if (trim_regs[1] 0x01) + d1 = -d1; + + /* D2 */ + d2 = (trim_regs[4] 0x3F) 2; + d2 |= (trim_regs[2] 0x06) 1; + if (trim_regs[2] 0x01) + d2 = -d2; + break; + case 8: + /* D1 */ + temp = (trim_regs[3] 0x1F) 2; + temp |= (trim_regs[1] 0x06) 1; + if (trim_regs[1] 0x01) + temp = -temp; + + d1 = (trim_regs[8] 0x18) 1; + d1 |= (trim_regs[7] 0x1E) 1; + if (trim_regs[7] 0x01) + d1 = -d1; + + d1 += temp; + + /* D2 */ + temp = (trim_regs[4] 0x3F) 2; + temp |= (trim_regs[2] 0x06) 1; + if (trim_regs[2] 0x01) + temp = -temp; + + d2 = (trim_regs[10] 0x1F) 2; + d2 |= (trim_regs[8] 0x06) 1; + if (trim_regs[8] 0x01) + d2 = -d2; + + d2 += temp; + break; + case 9: + /* D1 */ + temp = (trim_regs[3] 0x1F) 2; + temp |= (trim_regs[1] 0x06) 1; + if (trim_regs[1] 0x01) + temp = -temp; + + d1 = (trim_regs[14] 0x18) 1; + d1 |= (trim_regs[12] 0x1E) 1; + if (trim_regs[12] 0x01) + d1 = -d1; + + d1 += temp; + + /* D2 */ + temp = (trim_regs[4] 0x3F) 2; + temp |= (trim_regs[2] 0x06) 1; + if (trim_regs[2] 0x01) + temp = -temp; + + d2 = (trim_regs[16] 0x1F) 2; + d2 |= (trim_regs[14] 0x06) 1; + if (trim_regs[14] 0x01) + d2 = -d2; + + d2 += temp; + case 10: + /* D1 */ + d1 = (trim_regs[11] 0x0F) 3; + d1 |= (trim_regs[9] 0x0E) 1; + if (trim_regs[9] 0x01) + d1 = -d1; + + /* D2 */ + d2 = (trim_regs[15] 0x0F) 3; + d2 |= (trim_regs[13] 0x0E) 1; + if (trim_regs[13] 0x01) + d2 = -d2; + break; + case 7: + case 18: + /* D1 */ + temp = (trim_regs[3] 0x1F) 2; + temp |= (trim_regs[1] 0x06) 1; + if (trim_regs[1] 0x01) + temp = -temp; + + d1 = (trim_regs[5] 0x7E) 1; + if (trim_regs[5] 0x01) + d1 = -d1; +. + d1 += temp; + + /* D2 */ + temp = (trim_regs[4] 0x3F) 2; + temp |= (trim_regs[2] 0x06) 1; + if (trim_regs[2] 0x01) + temp = -temp; + + d2 = (trim_regs[6] 0xFE) 1; + if (trim_regs[6] 0x01) + d2 = -d2; + + d2 += temp; + break; There is quite a bit of copy paste in here. Putting the bit swizziling into a helper
[PATCH 5/6] ARM: dts: omap3-beagle-xm: Add USB Host support
Provide RESET controller and Power regulator for the USB PHY, the USB Host port mode and the PHY device. Provide pin multiplexer information for USB host pins. We also relocate omap3_pmx_core pin definations so that they are close to omap3_pmx_wkup pin definations. Signed-off-by: Roger Quadros rog...@ti.com --- arch/arm/boot/dts/omap3-beagle-xm.dts | 75 + 1 files changed, 66 insertions(+), 9 deletions(-) diff --git a/arch/arm/boot/dts/omap3-beagle-xm.dts b/arch/arm/boot/dts/omap3-beagle-xm.dts index afdb164..2273c24 100644 --- a/arch/arm/boot/dts/omap3-beagle-xm.dts +++ b/arch/arm/boot/dts/omap3-beagle-xm.dts @@ -69,6 +69,33 @@ }; }; + + /* HS USB Port 2 RESET */ + hsusb2_reset: hsusb2_reset { + compatible = gpio-reset; + reset-gpios = gpio5 19 GPIO_ACTIVE_LOW; /* gpio_147 */ + reset-delay-us = 7; + initially-in-reset; + #reset-cells = 0; + }; + + /* HS USB Port 2 Power */ + hsusb2_power: hsusb2_power_reg { + compatible = regulator-fixed; + regulator-name = hsusb2_vbus; + regulator-min-microvolt = 330; + regulator-max-microvolt = 330; + gpio = twl_gpio 18 0;/* GPIO LEDA */ + startup-delay-us = 7; + }; + + /* HS USB Host PHY on PORT 2 */ + hsusb2_phy: hsusb2_phy { + compatible = usb-nop-xceiv; + resets = hsusb2_reset; + reset-names = reset; + vcc-supply = hsusb2_power; + }; }; omap3_pmx_wkup { @@ -79,6 +106,37 @@ }; }; +omap3_pmx_core { + pinctrl-names = default; + pinctrl-0 = + hsusbb2_pins + ; + + uart3_pins: pinmux_uart3_pins { + pinctrl-single,pins = + 0x16e (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */ + 0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx OUTPUT | MODE0 */ + ; + }; + + hsusbb2_pins: pinmux_hsusbb2_pins { + pinctrl-single,pins = + 0x5c0 (PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */ + 0x5c2 (PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */ + 0x5c4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */ + 0x5c6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */ + 0x5c8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */ + 0x5cA (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */ + 0x1a4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi1_cs3.hsusb2_data2 */ + 0x1a6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_clk.hsusb2_data7 */ + 0x1a8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_simo.hsusb2_data4 */ + 0x1aa (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_somi.hsusb2_data5 */ + 0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs0.hsusb2_data6 */ + 0x1ae (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs1.hsusb2_data3 */ + ; + }; +}; + i2c1 { clock-frequency = 260; @@ -148,15 +206,6 @@ power = 50; }; -omap3_pmx_core { - uart3_pins: pinmux_uart3_pins { - pinctrl-single,pins = - 0x16e (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */ - 0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx OUTPUT | MODE0 */ - ; - }; -}; - uart3 { pinctrl-names = default; pinctrl-0 = uart3_pins; @@ -166,3 +215,11 @@ pinctrl-names = default; pinctrl-0 = gpio1_pins; }; + +usbhshost { + port2-mode = ehci-phy; +}; + +usbhsehci { + phys = 0 hsusb2_phy; +}; -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/6] ARM: dts: omap4-panda: Use reset-gpio driver for hsusb1_reset
We no longer need to model a RESET line as a regulator since we have the reset-gpio driver available. Signed-off-by: Roger Quadros rog...@ti.com --- arch/arm/boot/dts/omap4-panda-common.dtsi | 22 -- 1 files changed, 8 insertions(+), 14 deletions(-) diff --git a/arch/arm/boot/dts/omap4-panda-common.dtsi b/arch/arm/boot/dts/omap4-panda-common.dtsi index faa95b5..e9b0a91 100644 --- a/arch/arm/boot/dts/omap4-panda-common.dtsi +++ b/arch/arm/boot/dts/omap4-panda-common.dtsi @@ -60,20 +60,13 @@ AFMR, Line In; }; - /* -* Temp hack: Need to be replaced with the proper gpio-controlled -* reset driver as soon it will be merged. -* http://thread.gmane.org/gmane.linux.drivers.devicetree/36830 -*/ /* HS USB Port 1 RESET */ - hsusb1_reset: hsusb1_reset_reg { - compatible = regulator-fixed; - regulator-name = hsusb1_reset; - regulator-min-microvolt = 330; - regulator-max-microvolt = 330; - gpio = gpio2 30 0; /* gpio_62 */ - startup-delay-us = 7; - enable-active-high; + hsusb1_reset: hsusb1_reset { + compatible = gpio-reset; + reset-gpios = gpio2 30 GPIO_ACTIVE_LOW; /* gpio_62 */ + reset-delay-us = 7; + initially-in-reset; + #reset-cells = 0; }; /* HS USB Port 1 Power */ @@ -97,7 +90,8 @@ /* HS USB Host PHY on PORT 1 */ hsusb1_phy: hsusb1_phy { compatible = usb-nop-xceiv; - reset-supply = hsusb1_reset; + resets = hsusb1_reset; + reset-names = reset; vcc-supply = hsusb1_power; /** * FIXME: -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: ARM: AM335x: Kernel oops when using EDMA and MMC
On 17/07/13 17:38, Joel Fernandes wrote: On 07/17/2013 10:55 AM, Mark Jackson wrote: I'm trying to get the MMC port working on our custom AM3352 CPU board. I have added MMC entries to out dts file (similar to [1]), and I've enabled CONFIG_TI_EDMA. Our board boots fine without an SD card inserted ... [0.00] Booting Linux on physical CPU 0x0 [0.00] Linux version 3.11.0-rc1-00025-g95b9b72 (mpfj@mpfj-nanobone) (gcc version 4.6.3 (Buildroot 2013.02-dirty) ) #309 Wed Jul 17 16:37:28 BST 2013 ... [2.789028] VFS: Mounted root (ubifs filesystem) on device 0:12. [2.797268] devtmpfs: mounted [2.801032] Freeing unused kernel memory: 200K (c0551000 - c0583000) ... Welcome to Buildroot nanobone login: But when I boot with a card already inserted, I get the following oops ... ... [1.827343] Unable to handle kernel NULL pointer dereference at virtual address 000c [1.835868] pgd = c0004000 [1.838774] [000c] *pgd= [1.842556] Internal error: Oops: 5 [#1] ARM [1.847063] CPU: 0 PID: 6 Comm: kworker/u2:0 Not tainted 3.11.0-rc1-00025-g95b9b72 #309 [1.855511] Workqueue: kmmcd mmc_rescan [1.859556] task: cf06a080 ti: cf072000 task.ti: cf072000 [1.865257] PC is at omap_hsmmc_start_command+0x74/0xf4 [1.870761] LR is at omap_hsmmc_request+0xec/0x4dc [1.875806] pc : [c0305b70]lr : [c0306c64]psr: 6113 [1.875806] sp : cf073ca0 ip : fp : 0008 [1.887885] r10: cf073de8 r9 : 0001 r8 : cf11d918 [1.893382] r7 : 0003 r6 : cf33cc80 r5 : 0001 r4 : 0033 [1.900250] r3 : 0002 r2 : cf073db8 r1 : cf073d84 r0 : cf33cc80 [1.907122] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel [1.914813] Control: 10c5387d Table: 80004019 DAC: 0015 [1.920859] Process kworker/u2:0 (pid: 6, stack limit = 0xcf072238) [1.927454] Stack: (0xcf073ca0 to 0xcf074000) [1.932048] 3ca0: cf33c800 cf073d40 0003 c0076a8c cf073d40 48060220 48060220 [1.940659] 3cc0: 0004 0004 0002 0002 cf073ec8 c0421a9c c051835c cf073d40 [1.949271] 3ce0: cf33c800 0001 0008 0008 0002 cf073db8 cf073ec8 c02f0f28 [1.957882] 3d00: 0200 0064 cf073db8 cf073ec8 cf073d40 cf073d50 [1.966493] 3d20: cf33c800 c02f18a4 cf369800 cf369a80 cf360880 0008 c02f9964 [1.975104] 3d40: cf073d84 cf073db8 0001 0001 dead4ead [1.983717] 3d60: c0af722c c06aa3e4 c04ddadc cf073d74 cf073d74 c02f0dc4 [1.992327] 3d80: 0033 00b5 [2.000938] 3da0: cf073db8 cf073d40 05f5e100 [2.009548] 3dc0: 0008 0001 0200 cf073d40 0001 [2.018159] 3de0: cf073de8 c0cf1c02 0880 0008 8f360880 cf369800 [2.026771] 3e00: cf33c800 cf369800 cf073e4c cf072000 c02f8740 0015 [2.035382] 3e20: 0003 cf33c800 cf369800 cf073e4c cf072000 c02f8b20 [2.043994] 3e40: 0002 c02f25cc 0002 02544d53 41303447 1026c914 2600bbbd c0ff8000 [2.052605] 3e60: c0455884 cf33c800 c0455884 c0455890 cf072000 c02f92bc [2.061217] 3e80: c0455890 00ff8000 0002 cf33cb14 cf33c800 c02f3a28 cf041ac0 cf33cb14 [2.069829] 3ea0: cf050c00 cf051c00 c00507ec 0002 c0050778 c0050f10 [2.078441] 3ec0: c0af7268 c06aa1c4 c0518cd0 cf06a080 cf041ac0 [2.087054] 3ee0: cf050c00 cf072000 cf050c30 cf041ad8 0089 c05d7b5c cf050c00 c0050e4c [2.095665] 3f00: cf072000 6113 cf04dda8 cf041ac0 c0050d08 [2.104276] 3f20: c0056c94 c0429a18 0001 cf041ac0 [2.112888] 3f40: 0001 dead4ead c05ec0a0 [2.121499] 3f60: c04ddadc cf073f64 cf073f64 0001 dead4ead [2.130112] 3f80: c05ec0a0 c04ddadc cf073f90 cf073f90 cf073fac cf04dda8 [2.138724] 3fa0: c0056bf0 c0013588 [2.147334] 3fc0: [2.155946] 3fe0: 0013 57e0c5db 5ffb7d3c [2.164565] [c0305b70] (omap_hsmmc_start_command+0x74/0xf4) from [0003] (0x3) [2.172814] Code: 13a03801 0a1b e590c008 e5914000 (e59cc00c) [2.179314] ---[ end trace 6ec9899a56aef6aa ]--- I have also noticed that when the kernel boots okay (without a card inserted), if I then insert a card, nothing happens (even with CONFIG_MMC_DEBUG=y) ... including no kernel oops. Can anyone shed light on what's
Re: [PATCH 3/3] ARM: dts: omap4-sdp: add dynamic pin states for uart3/4
On 07/18/2013 11:09 AM, Tony Lindgren wrote: * Grygorii Strashko grygorii.stras...@ti.com [130717 09:48]: Hi, On 07/17/2013 06:32 PM, Tony Lindgren wrote: * Grygorii Strashko grygorii.stras...@ti.com [130717 04:49]: Add dynamic active/idle pin states for uart3/4 which will be applied when uart3/4 state is switched from active to idle and back by Runtime PM or during system suspend. This is good for testing code, but should not be merged because omap4 has the iopad wake-ups available for uarts. So those can be always enabled. In this case, 2 IRQ will be received per each UART RX event - one from PRCM and from UART - and that's not good from PM perspective (It will affect on CPUIdle and CPUFreq at least). Oh I see, that's because I accidentally left the debug code enabled to make it easier to test the wake-up events without having to have working off-idle. The wake flags can be kept on always for sure. The patch below should sort out the issue of getting wake-up interrupts during runtime as long as you don't have DEBUG defined. Regards, Tony --- a/drivers/pinctrl/pinctrl-single-omap.c +++ b/drivers/pinctrl/pinctrl-single-omap.c @@ -140,9 +140,17 @@ static irqreturn_t pcs_omap_handle_irq(int irq, void *data) if ((val OMAP_WAKEUP_EVENT_MASK) == OMAP_WAKEUP_EVENT_MASK) generic_handle_irq(wakeirq); } - +#ifdef DEBUG Don't think it's debug code - IO chain need to be rearmed after each PRCM IO IRQ - otherwise IO wakeup events may be lost (at least on OMAP4, OMAP5 requires more complex handling(( ). + /* +* This enables wake-up interrupts during runtime also +* causing duplicate interrupts. But it also makes debugging +* the wake-up events easy as deeper idle states often are +* not working for new devices while the drivers are being +* developed. +*/ if (pcso-reconfigure_io_chain) pcso-reconfigure_io_chain(); +#endif return IRQ_HANDLED; } I didn't pick up your padconf patches yet -seems i need to be in sync :) Below the diff I used to verify IO wake up (It follows old IO daisy chain hanlding models in hwmod before DT): --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -574,7 +574,7 @@ odbs_exit: return ERR_PTR(ret); } - +#include prm44xx.h #ifdef CONFIG_PM_RUNTIME static int _od_runtime_suspend(struct device *dev) { @@ -586,6 +586,7 @@ static int _od_runtime_suspend(struct device *dev) if (!ret) { omap_device_idle(pdev); pinctrl_pm_select_idle_state(dev); + omap44xx_prm_reconfigure_io_chain(); } return ret; @@ -596,6 +597,7 @@ static int _od_runtime_resume(struct device *dev) struct platform_device *pdev = to_platform_device(dev); pinctrl_pm_select_active_state(dev); + omap44xx_prm_reconfigure_io_chain(); omap_device_enable(pdev); diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index 228b850..5db073a 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -79,7 +79,7 @@ static void omap_prcm_events_filter_priority(unsigned long *events, events[i] ^= priority_events[i]; } } - +#include prm44xx.h /* * PRCM Interrupt Handler * @@ -144,6 +144,7 @@ static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc) chip-irq_unmask(desc-irq_data); prcm_irq_setup-ocp_barrier(); /* avoid spurious IRQs */ + omap44xx_prm_reconfigure_io_chain(); } -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/6] usb: phy-nop: Use RESET Controller for managing the reset line
Till now we were modelling the RESET line as a voltage regulator and using the regulator framework to manage it. [1] introduces a GPIO based reset controller driver. We use that to manage the PHY reset line, at least for DT boots. For legacy boots, will still need to use the regulator framework for reset lines. [1] - http://thread.gmane.org/gmane.linux.drivers.devicetree/41348 Signed-off-by: Roger Quadros rog...@ti.com --- .../devicetree/bindings/usb/usb-nop-xceiv.txt | 10 +++-- drivers/usb/phy/Kconfig|1 + drivers/usb/phy/phy-nop.c | 48 +++- 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/usb-nop-xceiv.txt b/Documentation/devicetree/bindings/usb/usb-nop-xceiv.txt index d7e2726..5c3e978 100644 --- a/Documentation/devicetree/bindings/usb/usb-nop-xceiv.txt +++ b/Documentation/devicetree/bindings/usb/usb-nop-xceiv.txt @@ -15,7 +15,9 @@ Optional properties: - vcc-supply: phandle to the regulator that provides RESET to the PHY. -- reset-supply: phandle to the regulator that provides power to the PHY. +- resets: phandle to the reset controller. + +- reset-names: must be reset Example: @@ -25,10 +27,10 @@ Example: clocks = osc 0; clock-names = main_clk; vcc-supply = hsusb1_vcc_regulator; - reset-supply = hsusb1_reset_regulator; + resets = hsusb1_reset; + reset-names = reset }; hsusb1_phy is a NOP USB PHY device that gets its clock from an oscillator and expects that clock to be configured to 19.2MHz by the NOP PHY driver. -hsusb1_vcc_regulator provides power to the PHY and hsusb1_reset_regulator -controls RESET. +hsusb1_vcc_regulator provides power to the PHY and hsusb1_reset controls RESET. diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 3622fff..213b5ad 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -58,6 +58,7 @@ config MV_U3D_PHY config NOP_USB_XCEIV tristate NOP USB Transceiver Driver + depends on RESET_CONTROLLER help This driver is to be used by all the usb transceiver which are either built-in with usb ip or which are autonomous and doesn't require any diff --git a/drivers/usb/phy/phy-nop.c b/drivers/usb/phy/phy-nop.c index 55445e5d..a2cbda5 100644 --- a/drivers/usb/phy/phy-nop.c +++ b/drivers/usb/phy/phy-nop.c @@ -35,13 +35,15 @@ #include linux/clk.h #include linux/regulator/consumer.h #include linux/of.h +#include linux/reset.h struct nop_usb_xceiv { struct usb_phy phy; struct device *dev; struct clk *clk; struct regulator *vcc; - struct regulator *reset; + struct regulator *reset_reg; /* only used for non-DT boot */ + struct reset_control *reset; }; static struct platform_device *pd; @@ -82,9 +84,14 @@ static int nop_init(struct usb_phy *phy) if (!IS_ERR(nop-clk)) clk_enable(nop-clk); + /* De-assert RESET */ + if (!IS_ERR(nop-reset_reg)) { + if (regulator_enable(nop-reset_reg)) + dev_err(phy-dev, Failed to de-assert reset\n); + } + if (!IS_ERR(nop-reset)) { - /* De-assert RESET */ - if (regulator_enable(nop-reset)) + if (reset_control_deassert(nop-reset)) dev_err(phy-dev, Failed to de-assert reset\n); } @@ -95,9 +102,14 @@ static void nop_shutdown(struct usb_phy *phy) { struct nop_usb_xceiv *nop = dev_get_drvdata(phy-dev); + /* Assert RESET */ + if (!IS_ERR(nop-reset_reg)) { + if (regulator_disable(nop-reset_reg)) + dev_err(phy-dev, Failed to assert reset\n); + } + if (!IS_ERR(nop-reset)) { - /* Assert RESET */ - if (regulator_disable(nop-reset)) + if (reset_control_assert(nop-reset)) dev_err(phy-dev, Failed to assert reset\n); } @@ -166,7 +178,7 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev) clk_rate = 0; needs_vcc = of_property_read_bool(node, vcc-supply); - needs_reset = of_property_read_bool(node, reset-supply); + needs_reset = of_property_read_bool(node, resets); } else if (pdata) { type = pdata-type; @@ -205,12 +217,26 @@ static int nop_usb_xceiv_probe(struct platform_device *pdev) return -EPROBE_DEFER; } - nop-reset = devm_regulator_get(pdev-dev, reset); - if (IS_ERR(nop-reset)) { - dev_dbg(pdev-dev, Error getting reset regulator: %ld\n, + nop-reset_reg = ERR_PTR(-EINVAL); + nop-reset = ERR_PTR(-EINVAL); + + if (dev-of_node) { + nop-reset = devm_reset_control_get(dev, reset); +
[PATCH 6/6] ARM: dts: omap3-beagle: Make USB host pin naming consistent
Use a common naming scheme mode0name.modename flags for the USB host pins to be consistent. Signed-off-by: Roger Quadros rog...@ti.com --- arch/arm/boot/dts/omap3-beagle.dts | 24 1 files changed, 12 insertions(+), 12 deletions(-) diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts index 01fbad6..27aed65 100644 --- a/arch/arm/boot/dts/omap3-beagle.dts +++ b/arch/arm/boot/dts/omap3-beagle.dts @@ -100,18 +100,18 @@ hsusbb2_pins: pinmux_hsusbb2_pins { pinctrl-single,pins = - 0x5c0 (PIN_OUTPUT | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_clk */ - 0x5c2 (PIN_OUTPUT | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_stp */ - 0x5c4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dir */ - 0x5c6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_nxt */ - 0x5c8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat0 */ - 0x5cA (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat1 */ - 0x1a4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat2 */ - 0x1a6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat3 */ - 0x1a8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat4 */ - 0x1aa (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat5 */ - 0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat6 */ - 0x1ae (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat7 */ + 0x5c0 (PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */ + 0x5c2 (PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */ + 0x5c4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */ + 0x5c6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */ + 0x5c8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */ + 0x5cA (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */ + 0x1a4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi1_cs3.hsusb2_data2 */ + 0x1a6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_clk.hsusb2_data7 */ + 0x1a8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_simo.hsusb2_data4 */ + 0x1aa (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_somi.hsusb2_data5 */ + 0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs0.hsusb2_data6 */ + 0x1ae (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs1.hsusb2_data3 */ ; }; -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/6] ARM: dts: omap3-beagle: Use reset-gpio driver for hsusb2_reset
We no longer need to model a RESET line as a regulator since we have the reset-gpio driver available. Signed-off-by: Roger Quadros rog...@ti.com --- arch/arm/boot/dts/omap3-beagle.dts | 17 - 1 files changed, 8 insertions(+), 9 deletions(-) diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts index dfd8310..01fbad6 100644 --- a/arch/arm/boot/dts/omap3-beagle.dts +++ b/arch/arm/boot/dts/omap3-beagle.dts @@ -45,14 +45,12 @@ }; /* HS USB Port 2 RESET */ - hsusb2_reset: hsusb2_reset_reg { - compatible = regulator-fixed; - regulator-name = hsusb2_reset; - regulator-min-microvolt = 330; - regulator-max-microvolt = 330; - gpio = gpio5 19 0; /* gpio_147 */ - startup-delay-us = 7; - enable-active-high; + hsusb2_reset: hsusb2_reset { + compatible = gpio-reset; + reset-gpios = gpio5 19 GPIO_ACTIVE_LOW; /* gpio_147 */ + reset-delay-us = 7; + initially-in-reset; + #reset-cells = 0; }; /* HS USB Port 2 Power */ @@ -68,7 +66,8 @@ /* HS USB Host PHY on PORT 2 */ hsusb2_phy: hsusb2_phy { compatible = usb-nop-xceiv; - reset-supply = hsusb2_reset; + resets = hsusb2_reset; + reset-names = reset; vcc-supply = hsusb2_power; }; -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/6] ARM: dts: omap5-uevm: Use reset-gpio driver for hsusb2_reset
We no longer need to model a RESET line as a regulator since we have the reset-gpio driver available. Signed-off-by: Roger Quadros rog...@ti.com --- arch/arm/boot/dts/omap5-uevm.dts | 17 - 1 files changed, 8 insertions(+), 9 deletions(-) diff --git a/arch/arm/boot/dts/omap5-uevm.dts b/arch/arm/boot/dts/omap5-uevm.dts index 08b7267..08650f9 100644 --- a/arch/arm/boot/dts/omap5-uevm.dts +++ b/arch/arm/boot/dts/omap5-uevm.dts @@ -28,20 +28,19 @@ }; /* HS USB Port 2 RESET */ - hsusb2_reset: hsusb2_reset_reg { - compatible = regulator-fixed; - regulator-name = hsusb2_reset; - regulator-min-microvolt = 330; - regulator-max-microvolt = 330; - gpio = gpio3 16 GPIO_ACTIVE_HIGH; /* gpio3_80 HUB_NRESET */ - startup-delay-us = 7; - enable-active-high; + hsusb2_reset: hsusb2_reset { + compatible = gpio-reset; + reset-gpios = gpio2 30 GPIO_ACTIVE_LOW; /* gpio3_80 HUB_NRESET */ + reset-delay-us = 7; + initially-in-reset; + #reset-cells = 0; }; /* HS USB Host PHY on PORT 2 */ hsusb2_phy: hsusb2_phy { compatible = usb-nop-xceiv; - reset-supply = hsusb2_reset; + resets = hsusb2_reset; + reset_names = reset; /** * FIXME * Put the right clock phandle here when available -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/6] USB: phy: phy-nop: Use RESET controller for managing the reset line
Hi, Till now we were modelling the RESET line as a voltage regulator and using the regulator framework to manage it. [1] introduces a GPIO based reset controller driver. We use that to manage the PHY reset line, at least for DT boots. For legacy boots, will still need to use the regulator framework for reset lines. Felipe, The first patch is for you. The Kconfig change might conflict if you apply this on top of my PHY Kconfig cleanup series. Benoit, Patches 2 to 6 are for you. NOTE: All patches depend on [1] which is yet to be merged in. cheers, -roger [1] - http://thread.gmane.org/gmane.linux.drivers.devicetree/41348 Roger Quadros (6): usb: phy-nop: Use RESET Controller for managing the reset line ARM: dts: omap3-beagle: Use reset-gpio driver for hsusb2_reset ARM: dts: omap4-panda: Use reset-gpio driver for hsusb1_reset ARM: dts: omap5-uevm: Use reset-gpio driver for hsusb2_reset ARM: dts: omap3-beagle-xm: Add USB Host support ARM: dts: omap3-beagle: Make USB host pin naming consistent .../devicetree/bindings/usb/usb-nop-xceiv.txt | 10 ++- arch/arm/boot/dts/omap3-beagle-xm.dts | 75 +--- arch/arm/boot/dts/omap3-beagle.dts | 41 +-- arch/arm/boot/dts/omap4-panda-common.dtsi | 22 ++ arch/arm/boot/dts/omap5-uevm.dts | 17 ++--- drivers/usb/phy/Kconfig|1 + drivers/usb/phy/phy-nop.c | 48 ++--- 7 files changed, 146 insertions(+), 68 deletions(-) -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Regression 3.11-rc1: omap4panda: no usb and consequently no ethernet
* Arend van Spriel ar...@broadcom.com [130718 01:47]: We are using the panda board (es variant) for testing our SDIO based chips. For this we have an adapter card connection to expansion connector A. As this adapter is not publicly available we had internally patched board-omap4panda.c. Also we follow the -rc releases and use TFTP to boot the kernel image which requires USB. Moving to 3.11-rc1 I found that the mentioned board file was removed by your commit: commit b42b918194c4791510ac049e3d507169a7de8544 Author: Tony Lindgren t...@atomide.com Date: Thu May 30 12:53:05 2013 -0700 ARM: OMAP2+: Remove board-omap4panda.c As our patches on that file are internal I do not hold it against you. This is no regression and we need to fix it. Right, we need to move on to device tree based booting. Most of it should be pretty trivial configuring of the .dts file and some .config changes so whatever issues are remaining should be out of the way by v3.11. So my first step was to follow the recipe given in that commit. Beside that I noticed a thread about USB issue on LKML so I also applied the following commit: commit 352f573e59050c7a604c35c58b4bbfc51edebbee Author: Roger Quadros rog...@ti.com Date: Tue Jun 18 19:04:47 2013 +0300 ARM: OMAP2+: Provide alias to USB PHY clock The attached kernel log seems to suggest that the device tree is picked up by the kernel, but the USB does not seem very active. No ethernet connectivity. This does seem a regression to me. Is there some other patch that I need to get it going again? There are few .dts related patches missing for USB. Roger can point you to the current versions that Benoit should be queueing for the -rc series. Then for the SDIO with device tree, take a look at the following patches: [PATCH 0/3] WLAN support for omap4 when booted with devicetree http://comments.gmane.org/gmane.linux.ports.arm.omap/97522# The wl12xx .dts changes for pandaboard are still missing too. Then I'll be updating these soonish: [PATCH 0/4] Updated omap_hsmmc SDIO and remuxing patches Those are needed for the SDIO interrupt, SDIO will work also without those. Regards, Tony -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 01/15] drivers: phy: add generic PHY framework
Hi, On Thursday 18 July 2013 12:50 PM, Greg KH wrote: On Thu, Jul 18, 2013 at 12:16:10PM +0530, Kishon Vijay Abraham I wrote: +struct phy_provider *__of_phy_provider_register(struct device *dev, +struct module *owner, struct phy * (*of_xlate)(struct device *dev, +struct of_phandle_args *args)); +struct phy_provider *__devm_of_phy_provider_register(struct device *dev, +struct module *owner, struct phy * (*of_xlate)(struct device *dev, +struct of_phandle_args *args)) + +__of_phy_provider_register and __devm_of_phy_provider_register can be used to +register the phy_provider and it takes device, owner and of_xlate as +arguments. For the dt boot case, all PHY providers should use one of the above +2 APIs to register the PHY provider. Why do you have __ for the prefix of a public function? Is that really the way that OF handles this type of thing? I have a macro of_phy_provider_register/devm_of_phy_provider_register that calls these functions and should be used by the PHY drivers. Probably I should make a mention of it in the Documentation. --- /dev/null +++ b/drivers/phy/Kconfig @@ -0,0 +1,13 @@ +# +# PHY +# + +menuconfig GENERIC_PHY +tristate PHY Subsystem +help + Generic PHY support. + + This framework is designed to provide a generic interface for PHY + devices present in the kernel. This layer will have the generic + API by which phy drivers can create PHY using the phy framework and + phy users can obtain reference to the PHY. Again, please reverse this. The drivers that use it should select it, not depend on it, which will then enable this option. I will never know if I need to enable it, and based on your follow-on patches, if I don't, drivers that were working just fine, now disappeared from my build, which isn't nice, and a pain to notice and fix up. ok. +/** + * phy_create() - create a new phy + * @dev: device that is creating the new phy + * @id: id of the phy + * @ops: function pointers for performing phy operations + * @label: label given to the phy + * + * Called to create a phy using phy framework. + */ +struct phy *phy_create(struct device *dev, u8 id, const struct phy_ops *ops, +const char *label) +{ +int ret; +struct phy *phy; + +if (!dev) { +dev_WARN(dev, no device provided for PHY\n); +ret = -EINVAL; +goto err0; +} + +phy = kzalloc(sizeof(*phy), GFP_KERNEL); +if (!phy) { +ret = -ENOMEM; +goto err0; +} + +device_initialize(phy-dev); +mutex_init(phy-mutex); + +phy-dev.class = phy_class; +phy-dev.parent = dev; +phy-dev.of_node = dev-of_node; +phy-id = id; +phy-ops = ops; +phy-label = kstrdup(label, GFP_KERNEL); + +ret = dev_set_name(phy-dev, %s.%d, dev_name(dev), id); Your naming is odd, no phy anywhere in it? You rely on the sender to never send a duplicate name.id pair? Why not create your own ids based on the number of phys in the system, like almost all other classes and subsystems do? hmm.. some PHY drivers use the id they provide to perform some of their internal operation as in [1] (This is used only if a single PHY provider implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO to give the PHY drivers an option to use auto id. [1] - http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html +static inline int phy_pm_runtime_get(struct phy *phy) +{ +if (WARN(IS_ERR(phy), Invalid PHY reference\n)) +return -EINVAL; Why would phy ever not be valid and a error pointer? And why dump the stack if that happens, that seems really extreme. hmm.. there might be cases where the same controller in one soc needs PHY control and in some other soc does not need PHY control. In such cases, we might get error pointer here. I'll change WARN to dev_err. + +if (!pm_runtime_enabled(phy-dev)) +return -ENOTSUPP; + +return pm_runtime_get(phy-dev); +} This, and the other inline functions in this .h file seem huge, why are they inline and not in the .c file? There's no speed issues, and it should save space overall in the .c file. Please move them. ok +static inline int phy_init(struct phy *phy) +{ +int ret; + +ret = phy_pm_runtime_get_sync(phy); +if (ret 0 ret != -ENOTSUPP) +return ret; + +mutex_lock(phy-mutex); +if (phy-init_count++ == 0 phy-ops-init) { +ret = phy-ops-init(phy); +if (ret 0) { +dev_err(phy-dev, phy init failed -- %d\n, ret); +goto out; +} +} + +out: +mutex_unlock(phy-mutex); +phy_pm_runtime_put(phy); +return ret; +} + +static inline int phy_exit(struct phy *phy) +{ +int ret; + +ret = phy_pm_runtime_get_sync(phy); +if (ret 0 ret != -ENOTSUPP)
Re: [PATCH 02/15] usb: phy: omap-usb2: use the new generic PHY framework
On Thursday 18 July 2013 12:51 PM, Greg KH wrote: On Thu, Jul 18, 2013 at 12:16:11PM +0530, Kishon Vijay Abraham I wrote: Used the generic PHY framework API to create the PHY. Now the power off and power on are done in omap_usb_power_off and omap_usb_power_on respectively. However using the old USB PHY library cannot be completely removed because OTG is intertwined with PHY and moving to the new framework will break OTG. Once we have a separate OTG state machine, we can get rid of the USB PHY library. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com Reviewed-by: Sylwester Nawrocki s.nawro...@samsung.com Acked-by: Felipe Balbi ba...@ti.com --- drivers/usb/phy/Kconfig |1 + drivers/usb/phy/phy-omap-usb2.c | 45 +++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 3622fff..cc55993 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -75,6 +75,7 @@ config OMAP_CONTROL_USB config OMAP_USB2 tristate OMAP USB2 PHY Driver depends on ARCH_OMAP2PLUS +depends on GENERIC_PHY select OMAP_CONTROL_USB help Enable this to support the transceiver that is part of SOC. This diff --git a/drivers/usb/phy/phy-omap-usb2.c b/drivers/usb/phy/phy-omap-usb2.c index 844ab68..751b30f 100644 --- a/drivers/usb/phy/phy-omap-usb2.c +++ b/drivers/usb/phy/phy-omap-usb2.c @@ -28,6 +28,7 @@ #include linux/pm_runtime.h #include linux/delay.h #include linux/usb/omap_control_usb.h +#include linux/phy/phy.h /** * omap_usb2_set_comparator - links the comparator present in the sytem with @@ -119,10 +120,36 @@ static int omap_usb2_suspend(struct usb_phy *x, int suspend) return 0; } +static int omap_usb_power_off(struct phy *x) +{ +struct omap_usb *phy = phy_get_drvdata(x); + +omap_control_usb_phy_power(phy-control_dev, 0); + +return 0; +} + +static int omap_usb_power_on(struct phy *x) +{ +struct omap_usb *phy = phy_get_drvdata(x); + +omap_control_usb_phy_power(phy-control_dev, 1); + +return 0; +} + +static struct phy_ops ops = { +.power_on = omap_usb_power_on, +.power_off = omap_usb_power_off, +.owner = THIS_MODULE, +}; + static int omap_usb2_probe(struct platform_device *pdev) { struct omap_usb *phy; +struct phy *generic_phy; struct usb_otg *otg; +struct phy_provider *phy_provider; phy = devm_kzalloc(pdev-dev, sizeof(*phy), GFP_KERNEL); if (!phy) { @@ -144,6 +171,11 @@ static int omap_usb2_probe(struct platform_device *pdev) phy-phy.otg= otg; phy-phy.type = USB_PHY_TYPE_USB2; +phy_provider = devm_of_phy_provider_register(phy-dev, +of_phy_simple_xlate); +if (IS_ERR(phy_provider)) +return PTR_ERR(phy_provider); + phy-control_dev = omap_get_control_dev(); if (IS_ERR(phy-control_dev)) { dev_dbg(pdev-dev, Failed to get control device\n); @@ -159,6 +191,15 @@ static int omap_usb2_probe(struct platform_device *pdev) otg-start_srp = omap_usb_start_srp; otg-phy= phy-phy; +platform_set_drvdata(pdev, phy); +pm_runtime_enable(phy-dev); + +generic_phy = devm_phy_create(phy-dev, 0, ops, omap-usb2); +if (IS_ERR(generic_phy)) +return PTR_ERR(generic_phy); So, if I have two of these controllers in my system, I can't create the second phy because the name for it will be identical to the first? That's why the phy core should handle the id, and not rely on the drivers to set it, as they have no idea how many they have in the system. hmm.. for such cases I'll have something like PLATFORM_DEVID_AUTO. Thanks Kishon -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/3] ARM: dts: omap4-sdp: add dynamic pin states for uart3/4
* Grygorii Strashko grygorii.stras...@ti.com [130718 02:01]: On 07/18/2013 11:09 AM, Tony Lindgren wrote: Don't think it's debug code - IO chain need to be rearmed after each PRCM IO IRQ - otherwise IO wakeup events may be lost (at least on OMAP4, OMAP5 requires more complex handling(( ). Nope, only after the mux register changes. I've verified it on am3730 with off-idle for both serial and wl12xx. I didn't pick up your padconf patches yet -seems i need to be in sync :) Well you need those for proper wake-up event support.. Below the diff I used to verify IO wake up (It follows old IO daisy chain hanlding models in hwmod before DT): ..then these changes not needed with the pinctrl-single changes. Regards, Tony -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 2/2] iio: twl6030-gpadc: TWL6030, TWL6032 GPADC driver
On 07/18/2013 10:36 AM, Oleksandr Kozaruk wrote: Hello Lars, On Wed, Jul 17, 2013 at 9:04 PM, Lars-Peter Clausen l...@metafoo.de wrote: +static int twl6032_calibration(struct twl6030_gpadc_data *gpadc) +{ + int chn, d1 = 0, d2 = 0, temp; + u8 trim_regs[17]; + int ret; + + ret = twl_i2c_read(TWL6030_MODULE_ID2, trim_regs + 1, + TWL6030_GPADC_TRIM1, 16); + if (ret 0) { + dev_err(gpadc-dev, calibration failed\n); + return ret; + } + + /* + * Loop to calculate the value needed for returning voltages from + * GPADC not values. + * + * gain is calculated to 3 decimal places fixed point. + */ + for (chn = 0; chn TWL6032_GPADC_MAX_CHANNELS; chn++) { + + switch (chn) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 11: + case 12: + case 13: + case 14: + /* D1 */ + d1 = (trim_regs[3] 0x1F) 2; + d1 |= (trim_regs[1] 0x06) 1; + if (trim_regs[1] 0x01) + d1 = -d1; + + /* D2 */ + d2 = (trim_regs[4] 0x3F) 2; + d2 |= (trim_regs[2] 0x06) 1; + if (trim_regs[2] 0x01) + d2 = -d2; + break; + case 8: + /* D1 */ + temp = (trim_regs[3] 0x1F) 2; + temp |= (trim_regs[1] 0x06) 1; + if (trim_regs[1] 0x01) + temp = -temp; + + d1 = (trim_regs[8] 0x18) 1; + d1 |= (trim_regs[7] 0x1E) 1; + if (trim_regs[7] 0x01) + d1 = -d1; + + d1 += temp; + + /* D2 */ + temp = (trim_regs[4] 0x3F) 2; + temp |= (trim_regs[2] 0x06) 1; + if (trim_regs[2] 0x01) + temp = -temp; + + d2 = (trim_regs[10] 0x1F) 2; + d2 |= (trim_regs[8] 0x06) 1; + if (trim_regs[8] 0x01) + d2 = -d2; + + d2 += temp; + break; + case 9: + /* D1 */ + temp = (trim_regs[3] 0x1F) 2; + temp |= (trim_regs[1] 0x06) 1; + if (trim_regs[1] 0x01) + temp = -temp; + + d1 = (trim_regs[14] 0x18) 1; + d1 |= (trim_regs[12] 0x1E) 1; + if (trim_regs[12] 0x01) + d1 = -d1; + + d1 += temp; + + /* D2 */ + temp = (trim_regs[4] 0x3F) 2; + temp |= (trim_regs[2] 0x06) 1; + if (trim_regs[2] 0x01) + temp = -temp; + + d2 = (trim_regs[16] 0x1F) 2; + d2 |= (trim_regs[14] 0x06) 1; + if (trim_regs[14] 0x01) + d2 = -d2; + + d2 += temp; + case 10: + /* D1 */ + d1 = (trim_regs[11] 0x0F) 3; + d1 |= (trim_regs[9] 0x0E) 1; + if (trim_regs[9] 0x01) + d1 = -d1; + + /* D2 */ + d2 = (trim_regs[15] 0x0F) 3; + d2 |= (trim_regs[13] 0x0E) 1; + if (trim_regs[13] 0x01) + d2 = -d2; + break; + case 7: + case 18: + /* D1 */ + temp = (trim_regs[3] 0x1F) 2; + temp |= (trim_regs[1] 0x06) 1; + if (trim_regs[1] 0x01) + temp = -temp; + + d1 = (trim_regs[5] 0x7E) 1; + if (trim_regs[5] 0x01) + d1 = -d1; +. + d1 += temp; + + /* D2 */ + temp = (trim_regs[4] 0x3F) 2; + temp |= (trim_regs[2] 0x06) 1; + if (trim_regs[2] 0x01) + temp = -temp; + + d2 = (trim_regs[6] 0xFE) 1; + if (trim_regs[6] 0x01) + d2 = -d2; + + d2 += temp; + break; There is quite a bit of copy paste in
[PATCH 0/3] spi changes and ti quad spi controller.
Add support for calculating message length in spi framework. Add support for quad spi controller. Patch 2 of this series had been posted before. Sending along with the series along with ather propsed change. Sourav Poddar (3): driver: spi: Modify core to compute the message length drivers: spi: Add qspi flash controller driver: spi: Add quad spi read support Documentation/devicetree/bindings/spi/ti_qspi.txt | 22 + drivers/spi/Kconfig |8 + drivers/spi/Makefile |1 + drivers/spi/spi-ti-qspi.c | 550 + drivers/spi/spi.c |1 + include/linux/spi/spi.h |1 + 6 files changed, 583 insertions(+), 0 deletions(-) create mode 100644 Documentation/devicetree/bindings/spi/ti_qspi.txt create mode 100644 drivers/spi/spi-ti-qspi.c -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCHv2 1/3] driver: spi: Modify core to compute the message length
Make spi core calculate the message length while populating the other transfer parameters. Usecase, driver can use it to populate framelength filed in their controller. Signed-off-by: Sourav Poddar sourav.pod...@ti.com --- drivers/spi/spi.c |1 + include/linux/spi/spi.h |1 + 2 files changed, 2 insertions(+), 0 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 32b7bb1..6a05b3c 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1375,6 +1375,7 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message) * it is not set for this transfer. */ list_for_each_entry(xfer, message-transfers, transfer_list) { + message-frame_length += xfer-len; if (!xfer-bits_per_word) xfer-bits_per_word = spi-bits_per_word; if (!xfer-speed_hz) diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 6ff26c8..d83841e 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -575,6 +575,7 @@ struct spi_message { /* completion is reported through a callback */ void(*complete)(void *context); void*context; + unsignedframe_length; unsignedactual_length; int status; -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv4 2/3] drivers: spi: Add qspi flash controller
The patch add basic support for the quad spi controller. QSPI is a kind of spi module that allows single, dual and quad read access to external spi devices. The module has a memory mapped interface which provide direct interface for accessing data form external spi devices. The patch will configure controller clocks, device control register and for defining low level transfer apis which will be used by the spi framework to transfer data to the slave spi device(flash in this case). Signed-off-by: Sourav Poddar sourav.pod...@ti.com --- v3-v4 - Did miscellaneous cleanup - Added power management support. Documentation/devicetree/bindings/spi/ti_qspi.txt | 22 + drivers/spi/Kconfig |8 + drivers/spi/Makefile |1 + drivers/spi/spi-ti-qspi.c | 537 + 4 files changed, 568 insertions(+), 0 deletions(-) create mode 100644 Documentation/devicetree/bindings/spi/ti_qspi.txt create mode 100644 drivers/spi/spi-ti-qspi.c diff --git a/Documentation/devicetree/bindings/spi/ti_qspi.txt b/Documentation/devicetree/bindings/spi/ti_qspi.txt new file mode 100644 index 000..398ef59 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/ti_qspi.txt @@ -0,0 +1,22 @@ +TI QSPI controller. + +Required properties: +- compatible : should be ti,dra7xxx-qspi. +- reg: Should contain QSPI registers location and length. +- #address-cells, #size-cells : Must be present if the device has sub-nodes +- ti,hwmods: Name of the hwmod associated to the QSPI + +Recommended properties: +- spi-max-frequency: Definition as per + Documentation/devicetree/bindings/spi/spi-bus.txt + +Example: + +qspi: qspi@4b30 { + compatible = ti,dra7xxx-qspi; + reg = 0x4b30 0x100; + #address-cells = 1; + #size-cells = 0; + spi-max-frequency = 2500; + ti,hwmods = qspi; +}; diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 92a9345..e594fdb 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -285,6 +285,14 @@ config SPI_OMAP24XX SPI master controller for OMAP24XX and later Multichannel SPI (McSPI) modules. +config QSPI_DRA7xxx + tristate DRA7xxx QSPI controller support + depends on ARCH_OMAP2PLUS || COMPILE_TEST + help + QSPI master controller for DRA7xxx used for flash devices. + This device supports single, dual and quad read support, while + it only supports single write mode. + config SPI_OMAP_100K tristate OMAP SPI 100K depends on ARCH_OMAP850 || ARCH_OMAP730 diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 33f9c09..b3b4857 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_SPI_OCTEON) += spi-octeon.o obj-$(CONFIG_SPI_OMAP_UWIRE) += spi-omap-uwire.o obj-$(CONFIG_SPI_OMAP_100K)+= spi-omap-100k.o obj-$(CONFIG_SPI_OMAP24XX) += spi-omap2-mcspi.o +obj-$(CONFIG_QSPI_DRA7xxx) += spi-ti-qspi.o obj-$(CONFIG_SPI_ORION)+= spi-orion.o obj-$(CONFIG_SPI_PL022)+= spi-pl022.o obj-$(CONFIG_SPI_PPC4xx) += spi-ppc4xx.o diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c new file mode 100644 index 000..3cae731 --- /dev/null +++ b/drivers/spi/spi-ti-qspi.c @@ -0,0 +1,537 @@ +/* + * TI QSPI driver + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * Author: Sourav Poddar sourav.pod...@ti.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GPLv2. + * + * 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/kernel.h +#include linux/init.h +#include linux/interrupt.h +#include linux/module.h +#include linux/device.h +#include linux/delay.h +#include linux/dma-mapping.h +#include linux/dmaengine.h +#include linux/omap-dma.h +#include linux/platform_device.h +#include linux/err.h +#include linux/clk.h +#include linux/io.h +#include linux/slab.h +#include linux/pm_runtime.h +#include linux/of.h +#include linux/of_device.h +#include linux/pinctrl/consumer.h + +#include linux/spi/spi.h + +struct ti_qspi_regs { + u32 clkctrl; +}; + +struct ti_qspi { + spinlock_t lock; /* IRQ synchronization */ + struct spi_master *master; + void __iomem*base; + struct device *dev; + struct completion transfer_complete; + struct clk *fclk; + struct ti_qspi_regs ctx_reg; + int device_type; + u32 spi_max_frequency; + u32 cmd; + u32 dc; +}; + +#define QSPI_PID (0x0) +#define
[RFC/PATCHv2 3/3] driver: spi: Add quad spi read support
Since, qspi controller uses quad read. Configuring the command register, if the transfer of data needs dual or quad lines. This patch has been done on top of the following patch[1], which is just the basic idea of adding dual/quad support in spi framework. $subject patch will undergo changes as the parent patch goes[1] [1]: http://comments.gmane.org/gmane.linux.kernel.spi.devel/14047 Signed-off-by: Sourav Poddar sourav.pod...@ti.com --- v1-v2 Added support for dual also. drivers/spi/spi-ti-qspi.c | 17 +++-- 1 files changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index 3cae731..3a5c56d 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -86,6 +86,7 @@ struct ti_qspi { #define QSPI_3_PIN (1 18) #define QSPI_RD_SNGL (1 16) #define QSPI_WR_SNGL (2 16) +#defineQSPI_RD_DUAL(3 16) #define QSPI_RD_QUAD (7 16) #define QSPI_INVAL (4 16) #define QSPI_WC_CMD_INT_EN (1 14) @@ -280,6 +281,7 @@ static void qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t) { u8 *rxbuf; int wlen, count; + unsigned cmd = qspi-cmd; count = t-len; rxbuf = t-rx_buf; @@ -289,8 +291,19 @@ static void qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t) dev_dbg(qspi-dev, rx cmd %08x dc %08x\n, qspi-cmd | QSPI_RD_SNGL, qspi-dc); ti_qspi_writel(qspi, qspi-dc, QSPI_SPI_DC_REG); - ti_qspi_writel(qspi, qspi-cmd | QSPI_RD_SNGL, - QSPI_SPI_CMD_REG); + switch (t-bitwidth) { + case SPI_BITWIDTH_QUAD: + cmd |= QSPI_RD_QUAD; + break; + case SPI_BITWIDTH_DUAL: + cmd |= QSPI_RD_DUAL; + break; + case SPI_BITWIDTH_SINGLE: + default: + cmd |= QSPI_RD_SNGL; + } + + ti_qspi_writel(qspi, cmd, QSPI_SPI_CMD_REG); ti_qspi_writel(qspi, QSPI_WC_INT_EN, QSPI_INTR_ENABLE_SET_REG); wait_for_completion(qspi-transfer_complete); *rxbuf++ = ti_qspi_readl_data(qspi, QSPI_SPI_DATA_REG, wlen); -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Regression 3.11-rc1: omap4panda: no usb and consequently no ethernet
On 07/18/2013 10:59 AM, Tony Lindgren wrote: * Arend van Spriel ar...@broadcom.com [130718 01:47]: So my first step was to follow the recipe given in that commit. Beside that I noticed a thread about USB issue on LKML so I also applied the following commit: commit 352f573e59050c7a604c35c58b4bbfc51edebbee Author: Roger Quadros rog...@ti.com Date: Tue Jun 18 19:04:47 2013 +0300 ARM: OMAP2+: Provide alias to USB PHY clock The attached kernel log seems to suggest that the device tree is picked up by the kernel, but the USB does not seem very active. No ethernet connectivity. This does seem a regression to me. Is there some other patch that I need to get it going again? There are few .dts related patches missing for USB. Roger can point you to the current versions that Benoit should be queueing for the -rc series. Hope Roger or Benoit will chime in. Then for the SDIO with device tree, take a look at the following patches: [PATCH 0/3] WLAN support for omap4 when booted with devicetree http://comments.gmane.org/gmane.linux.ports.arm.omap/97522# The wl12xx .dts changes for pandaboard are still missing too. Then I'll be updating these soonish: [PATCH 0/4] Updated omap_hsmmc SDIO and remuxing patches Those are needed for the SDIO interrupt, SDIO will work also without those. Thanks for the pointers, Arend -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv4 2/3] drivers: spi: Add qspi flash controller
Hi, it might be just me, but ... On Thu, Jul 18, 2013 at 03:31:26PM +0530, Sourav Poddar wrote: +static inline unsigned long ti_qspi_readl_data(struct ti_qspi *qspi, + unsigned long reg, int wlen) +{ + switch (wlen) { + case 8: + return readw(qspi-base + reg); + break; + case 16: + return readb(qspi-base + reg); + break; + case 32: + return readl(qspi-base + reg); + break; + default: + return -EINVAL; + } +} + +static inline void ti_qspi_writel_data(struct ti_qspi *qspi, + unsigned long val, unsigned long reg, int wlen) +{ + switch (wlen) { + case 8: + writew(val, qspi-base + reg); + break; + case 16: + writeb(val, qspi-base + reg); + break; + case 32: + writeb(val, qspi-base + reg); + break; + default: + dev_dbg(qspi-dev, word lenght out of range); + break; + } +} because of these two functions you have the hability to read/write *more* than one byte, and yet ... +static void qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t) +{ + const u8 *txbuf; + int wlen, count; + + count = t-len; + txbuf = t-tx_buf; + wlen = t-bits_per_word; + + while (count--) { + dev_dbg(qspi-dev, tx cmd %08x dc %08x data %02x\n, + qspi-cmd | QSPI_WR_SNGL, qspi-dc, *txbuf); + ti_qspi_writel_data(qspi, *txbuf++, QSPI_SPI_DATA_REG, wlen); you always increment by each byte. Here, if you used writel(), you wrote 4 bytes and should increment txbuf by 4. Same goes for read_data(), below. Another thing. Even though your wlen might be 8 bits, if you write 4 bytes to write, you can save a few CPU cycles by using writel(). You only use writew() if you have exactly 2 bytes to write and writeb() if you have exactly 1 byte to write. 3 bytes we'll be left as an exercise. +static int ti_qspi_start_transfer_one(struct spi_master *master, + struct spi_message *m) +{ + struct ti_qspi *qspi = spi_master_get_devdata(master); + struct spi_device *spi = m-spi; + struct spi_transfer *t; + int status = 0, ret; + int frame_length; + + /* setup device control reg */ + qspi-dc = 0; + + if (spi-mode SPI_CPHA) + qspi-dc |= QSPI_CKPHA(spi-chip_select); + if (spi-mode SPI_CPOL) + qspi-dc |= QSPI_CKPOL(spi-chip_select); + if (spi-mode SPI_CS_HIGH) + qspi-dc |= QSPI_CSPOL(spi-chip_select); + + frame_length = DIV_ROUND_UP(m-frame_length * spi-bits_per_word, + spi-bits_per_word); this calculation doesn't look correct. (m-frame_length * spi-bits_per_word) / spi-bits_per_word = m-frame_length What are you trying to achieve here ? frame_length should be counted in words right ? And we get that value in bytes. So what's the best calculation to convert bytes into words ? If you have 8 bits_per_word you don't need any calculation, but if you have 32 bits_per_word, you _do_ need something. How will you achieve the number you want ? (hint: 1 byte == 8 bits) And btw, all of these mistakes pretty much tell me that this driver hasn't been tested. How have you tested this driver ? Is your spansion memory accessed with 8 bits_per_word only ? Is there anyway to use 32 bits_per_word with that device ? That would uncover quite a few mistakes in $subject. -- balbi signature.asc Description: Digital signature
Re: [PATCHv4 2/3] drivers: spi: Add qspi flash controller
On Thu, Jul 18, 2013 at 03:31:26PM +0530, Sourav Poddar wrote: QSPI is a kind of spi module that allows single, dual and quad read access to external spi devices. The module has a memory mapped interface which provide direct interface for accessing data form external spi devices. Have you seen the ongoing thread about SPI buses with extra data lines? How does this driver fit in with that? --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_SPI_OCTEON)+= spi-octeon.o obj-$(CONFIG_SPI_OMAP_UWIRE) += spi-omap-uwire.o obj-$(CONFIG_SPI_OMAP_100K) += spi-omap-100k.o obj-$(CONFIG_SPI_OMAP24XX) += spi-omap2-mcspi.o +obj-$(CONFIG_QSPI_DRA7xxx) += spi-ti-qspi.o obj-$(CONFIG_SPI_ORION) += spi-orion.o obj-$(CONFIG_SPI_PL022) += spi-pl022.o obj-$(CONFIG_SPI_PPC4xx) += spi-ppc4xx.o Please use SPI_ like the other drivers. +static int ti_qspi_prepare_xfer(struct spi_master *master) +{ + struct ti_qspi *qspi = spi_master_get_devdata(master); + int ret; + + ret = pm_runtime_get_sync(qspi-dev); + if (ret 0) { + dev_err(qspi-dev, pm_runtime_get_sync() failed\n); + return ret; + } + + return 0; +} This is a very common pattern, it should probably be factored out into the core, probably not even as ops but rather as an actual feature. + list_for_each_entry(t, m-transfers, transfer_list) { + qspi-cmd |= QSPI_WLEN(t-bits_per_word); + qspi-cmd |= QSPI_WC_CMD_INT_EN; + + ret = qspi_transfer_msg(qspi, t); + if (ret) { + dev_dbg(qspi-dev, transfer message failed\n); + return -EINVAL; + } + + m-actual_length += t-len; + + if (list_is_last(t-transfer_list, m-transfers)) + goto out; + } The use of list_is_last() here is *realy* strange - what's going on there? +static irqreturn_t ti_qspi_isr(int irq, void *dev_id) +{ + struct ti_qspi *qspi = dev_id; + u16 mask, stat; + + irqreturn_t ret = IRQ_HANDLED; + + spin_lock(qspi-lock); + + stat = ti_qspi_readl(qspi, QSPI_SPI_STATUS_REG); + mask = ti_qspi_readl(qspi, QSPI_INTR_ENABLE_SET_REG); + + if (stat mask) + ret = IRQ_WAKE_THREAD; + + spin_unlock(qspi-lock); + + return ret; According to the above code we might interrupt for masked events... that's a bit worrying isn't it? + ret = devm_request_threaded_irq(pdev-dev, irq, ti_qspi_isr, + ti_qspi_threaded_isr, IRQF_NO_SUSPEND | IRQF_ONESHOT, + dev_name(pdev-dev), qspi); + if (ret 0) { + dev_err(pdev-dev, Failed to register ISR for IRQ %d\n, + irq); + goto free_master; + } Standard question about devm_request_threaded_irq() - how can we be certain it's safe to use during removal? signature.asc Description: Digital signature
Re: [RFC/PATCHv2 3/3] driver: spi: Add quad spi read support
On Thu, Jul 18, 2013 at 03:31:27PM +0530, Sourav Poddar wrote: Since, qspi controller uses quad read. Configuring the command register, if the transfer of data needs dual or quad lines. This patch has been done on top of the following patch[1], which is just the basic idea of adding dual/quad support in spi framework. $subject patch will undergo changes as the parent patch goes[1] [1]: http://comments.gmane.org/gmane.linux.kernel.spi.devel/14047 Just as with commit IDs you should include a plain text description of anything you link to so that people reading your e-mail can tell what you're talking about without going on line. signature.asc Description: Digital signature
Re: [PATCH 3/4] pinctrl: Add support for additional dynamic states
* Tony Lindgren t...@atomide.com [130718 00:31]: * Stephen Warren swar...@wwwdotorg.org [130717 14:21]: On 07/16/2013 03:05 AM, Tony Lindgren wrote: +int pinctrl_check_dynamic(struct device *dev, struct pinctrl_state *st1, + struct pinctrl_state *st2) +{ + struct pinctrl_setting *s1, *s2; + + list_for_each_entry(s1, st1-settings, node) { ... + list_for_each_entry(s2, st2-settings, node) { ... + if (pctldev1 != pctldev2) { + dev_dbg(dev, pctldev must be the same for states\n); + return -EINVAL; + } I don't think we should require that; it's perfectly legal at the moment for some device's pinctrl configuration to include settings from multiple different pin controllers. Yes that's fine for pinctrl_select(), but let's not do that for runtime muxing. Hmm reading this again, you're right, there should not be anything preventing mixing multiple controllers as long as the states match. + for (i = 0; i num_pins1; i++) { + int pin1 = pins1[i]; + + for (j = 0; j num_pins2; j++) { + int pin2 = pins2[j]; + + if (pin1 == pin2) { + found++; + break; + } + } + } + + if (found != num_pins1) { I guess this make sure that every entry in the dynamic state is in the state state, but not vice-versa; the static state can affect more stuff than the dynamic state? If so, shouldn't that check be if (found != num_pins2)? The check is that idle_state and sleep_state pins must match the active_state pins. This is intentionally different from the current pinctrl_select() logic. And here things will get messed up if the order of settings is diffrent.. So yes, pinctrl_check_dynamic() needs more work. Regards, Tony -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH RFC 00/13] ARM: OMAP2+: AM43x PRCM support
Hi Tony, Paul, On 7/11/2013 12:03 PM, Afzal Mohammed wrote: AM43x PRCM support (excluding clock tree) is being added with this series. AM43x reuses most of the IP's from AM335x, as that is the case, it was felt that reusing AM335x code as much as possible for AM43x is better - it also helps to keep LOC less. Major reuse has been with hwmod database of AM335x, moving common elements to a new array and keeping separate arrays for elements that are specific only to either one of AM335x or AM43x. And in the cases where relevant IP is present in both that has difference in details like CLKCTRL register offsets, it is being updated at runtime based on the SoC detected. This series is being developed with additional clock tree changes that would be DT'fied. Additional DTS changes are also required for hwmod to get register target address space as most of AM335x hwmod address space details has been recently cleaned up and moved to DTS. This RFC is being posted to get an early feedback on approach taken here mainly w.r.t reusing AM335x hwmod database for AM43x. Please let me know your comments on this series. Most of the IP's in AM335x is reused on AM43x and hence out of the existing 77 hwmod ocpif entries on AM335x, 73 are reused on AM43x by moving to a common array (only 4 is left AM335x specific). Even the address space of those peripherals that are common between AM335x AM43x is same. And AM43x has only a few newer IP's as compared to AM335x. Regards Afzal -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv4 2/3] drivers: spi: Add qspi flash controller
Hi Felipe, On Thursday 18 July 2013 03:54 PM, Felipe Balbi wrote: Hi, it might be just me, but ... On Thu, Jul 18, 2013 at 03:31:26PM +0530, Sourav Poddar wrote: +static inline unsigned long ti_qspi_readl_data(struct ti_qspi *qspi, + unsigned long reg, int wlen) +{ + switch (wlen) { + case 8: + return readw(qspi-base + reg); + break; + case 16: + return readb(qspi-base + reg); + break; + case 32: + return readl(qspi-base + reg); + break; + default: + return -EINVAL; + } +} + +static inline void ti_qspi_writel_data(struct ti_qspi *qspi, + unsigned long val, unsigned long reg, int wlen) +{ + switch (wlen) { + case 8: + writew(val, qspi-base + reg); + break; + case 16: + writeb(val, qspi-base + reg); + break; + case 32: + writeb(val, qspi-base + reg); + break; + default: + dev_dbg(qspi-dev, word lenght out of range); + break; + } +} because of these two functions you have the hability to read/write *more* than one byte, and yet ... +static void qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t) +{ + const u8 *txbuf; + int wlen, count; + + count = t-len; + txbuf = t-tx_buf; + wlen = t-bits_per_word; + + while (count--) { + dev_dbg(qspi-dev, tx cmd %08x dc %08x data %02x\n, + qspi-cmd | QSPI_WR_SNGL, qspi-dc, *txbuf); + ti_qspi_writel_data(qspi, *txbuf++, QSPI_SPI_DATA_REG, wlen); you always increment by each byte. Here, if you used writel(), you wrote 4 bytes and should increment txbuf by 4. hmm..got this point. Yes, my mistake, here I agree if wlen is not 8 bits txbuf++ is not valid. Same goes for read_data(), below. Another thing. Even though your wlen might be 8 bits, if you write 4 bytes to write, you can save a few CPU cycles by using writel(). Do you mean 4 words of 8 bits? You only use writew() if you have exactly 2 bytes to write and writeb() if you have exactly 1 byte to write. 3 bytes we'll be left as an exercise. hmm..yes. +static int ti_qspi_start_transfer_one(struct spi_master *master, + struct spi_message *m) +{ + struct ti_qspi *qspi = spi_master_get_devdata(master); + struct spi_device *spi = m-spi; + struct spi_transfer *t; + int status = 0, ret; + int frame_length; + + /* setup device control reg */ + qspi-dc = 0; + + if (spi-mode SPI_CPHA) + qspi-dc |= QSPI_CKPHA(spi-chip_select); + if (spi-mode SPI_CPOL) + qspi-dc |= QSPI_CKPOL(spi-chip_select); + if (spi-mode SPI_CS_HIGH) + qspi-dc |= QSPI_CSPOL(spi-chip_select); + + frame_length = DIV_ROUND_UP(m-frame_length * spi-bits_per_word, + spi-bits_per_word); this calculation doesn't look correct. (m-frame_length * spi-bits_per_word) / spi-bits_per_word = m-frame_length What are you trying to achieve here ? frame_length should be counted in words right ? And we get that value in bytes. So what's the best calculation to convert bytes into words ? If you have 8 bits_per_word you don't need any calculation, but if you have 32 bits_per_word, you _do_ need something. Yes, just derive this formulae with 8 bits per word in mind. Will change. It should be (m-frame_length * 8) / spi-bits_per_word How will you achieve the number you want ? (hint: 1 byte == 8 bits) And btw, all of these mistakes pretty much tell me that this driver hasn't been tested. How have you tested this driver ? After bootup, I checked for deive detting enumerated as /proc/mtd. After which I am using mtdutils(erase, dump and write utilied to check for the communication with the flash device.) Is your spansion memory accessed with 8 bits_per_word only ? Yes, most of the places is like that and data is sapmled in 8 bits. For some opcodes, we need to send 3 bytes addresses after instruction to the flash chip. Is there anyway to use 32 bits_per_word with that device ? That would uncover quite a few mistakes in $subject. -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Regression 3.11-rc1: omap4panda: no usb and consequently no ethernet
Hi Arend, On 07/18/2013 11:41 AM, Arend van Spriel wrote: Hi Tony, We are using the panda board (es variant) for testing our SDIO based chips. For this we have an adapter card connection to expansion connector A. As this adapter is not publicly available we had internally patched board-omap4panda.c. Also we follow the -rc releases and use TFTP to boot the kernel image which requires USB. Moving to 3.11-rc1 I found that the mentioned board file was removed by your commit: commit b42b918194c4791510ac049e3d507169a7de8544 Author: Tony Lindgren t...@atomide.com Date: Thu May 30 12:53:05 2013 -0700 ARM: OMAP2+: Remove board-omap4panda.c As our patches on that file are internal I do not hold it against you. This is no regression and we need to fix it. So my first step was to follow the recipe given in that commit. Beside that I noticed a thread about USB issue on LKML so I also applied the following commit: commit 352f573e59050c7a604c35c58b4bbfc51edebbee Author: Roger Quadros rog...@ti.com Date: Tue Jun 18 19:04:47 2013 +0300 ARM: OMAP2+: Provide alias to USB PHY clock The attached kernel log seems to suggest that the device tree is picked up by the kernel, but the USB does not seem very active. No ethernet connectivity. This does seem a regression to me. Is there some other patch that I need to get it going again? I tried with your config and 3.11-rc1 kernel with the above commit on top and ethernet seems to work for me. My boot log is attached. Are you sure that you are building the DTB for panda-es and the bootloader is picking up the right file and not an outdated one? Why is the version of SPL loader and u-boot different in your log? You need to use the MLO file generated by the u-boot build along with the uImage. Just to be sure we are on the same setup could you please try with latest u-boot release (2013-04). Thanks. cheers, -roger U-Boot SPL 2013.04 (Jul 18 2013 - 14:04:55) OMAP4460 ES1.1 OMAP SD/MMC: 0 reading u-boot.img reading u-boot.img U-Boot 2013.04 (Jul 18 2013 - 14:04:55) CPU : OMAP4460 ES1.1 Board: OMAP4 Panda I2C: ready DRAM: 1 GiB MMC: OMAP SD/MMC: 0 Using default environment In:serial Out: serial Err: serial Net: No ethernet found. Hit any key to stop autoboot: 0 mmc0 is current device SD/MMC found on device 0 reading boot.scr 409 bytes read in 3 ms (132.8 KiB/s) Running bootscript from mmc0 ... ## Executing script at 8200 reading omap4-panda.dtb 18588 bytes read in 6 ms (3 MiB/s) reading uImage 3947784 bytes read in 189 ms (19.9 MiB/s) ## Booting kernel from Legacy Image at 8030 ... Image Name: Linux-3.11.0-rc1-1-g4861de4 Image Type: ARM Linux Kernel Image (uncompressed) Data Size:3947720 Bytes = 3.8 MiB Load Address: 80008000 Entry Point: 80008000 Verifying Checksum ... OK ## Flattened Device Tree blob at 825f Booting using the fdt blob at 0x825f Loading Kernel Image ... OK OK Using Device Tree in place at 825f, end 825f789b Starting kernel ... [0.00] Booting Linux on physical CPU 0x0 [0.00] Linux version 3.11.0-rc1-1-g4861de4 (roger@rockdesk) (gcc version 4.7.1 20120531 (prerelease) (crosstool-NG linaro-1.13.1-2012.06-20120625 - Linaro GCC 2012.06) ) #862 SMP Thu Jul 18 14:10:14 EEST 2013 [0.00] CPU: ARMv7 Processor [412fc09a] revision 10 (ARMv7), cr=10c5387d [0.00] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache [0.00] Machine: Generic OMAP4 (Flattened Device Tree), model: TI OMAP4 PandaBoard [0.00] Memory policy: ECC disabled, Data cache writealloc [0.00] On node 0 totalpages: 261888 [0.00] free_area_init_node: node 0, pgdat c07b9500, node_mem_map c0d21000 [0.00] Normal zone: 1520 pages used for memmap [0.00] Normal zone: 0 pages reserved [0.00] Normal zone: 194560 pages, LIFO batch:31 [0.00] HighMem zone: 528 pages used for memmap [0.00] HighMem zone: 67328 pages, LIFO batch:15 [0.00] OMAP4460 ES1.1 [0.00] PERCPU: Embedded 9 pages/cpu @c153b000 s14208 r8192 d14464 u36864 [0.00] pcpu-alloc: s14208 r8192 d14464 u36864 alloc=9*4096 [0.00] pcpu-alloc: [0] 0 [0] 1 [0.00] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 260368 [0.00] Kernel command line: console=ttyO2,115200n8 mem=1G@0x8000 root=/dev/mmcblk0p2 rootwait debug earlyprintk loglevel=8 [0.00] PID hash table entries: 4096 (order: 2, 16384 bytes) [0.00] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes) [0.00] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes) [0.00] Memory: 1024916K/1047552K available (5122K kernel code, 558K rwdata, 1860K rodata, 345K init, 5515K bss, 22636K reserved, 269312K highmem) [0.00] Virtual kernel memory layout: [0.00] vector : 0x - 0x1000
Re: [PATCH 2/3] ARM: OMAP2+: omap_device: add pinctrl handling
On 07/18/2013 11:14 AM, Tony Lindgren wrote: * Grygorii Strashko grygorii.stras...@ti.com [130717 10:11]: On 07/17/2013 06:38 PM, Tony Lindgren wrote: * Grygorii Strashko grygorii.stras...@ti.com [130717 04:49]: Before switching to DT pinctrl states of OMAP IPs have been handled by hwmod framework. After switching to DT-boot the pinctrl handling was dropped from hwmod framework and, as it was recommended, OMAP IP's drivers have to be updated to handle pinctrl states by itself using pinctrl_pm_select_xx() helpers (see http://lists.infradead.org/pipermail/linux-arm-kernel/2013-June/173514.html) But this is not right for OMAP2+ SoC where real IPs state is controlled by omap_device core which enables/disables modules clocks actually. I'm not convinced we should try to handle this in a generic way as only some devices need dynamic remuxing of some pins. For example, if OMAP I2C driver will handle pinctrl state during system wide suspend the following issue may occure: - suspend_noirq - I2C device can be still active because of PM auto-suspend |-_od_suspend_noirq |- omap_i2c_suspend_noirq |- PINs state set to SLEEP |- pm_generic_runtime_suspend |- omap_i2c_runtime_suspend() |- PINs state set to IDLE --- *oops* PINs state is IDLE and not SLEEP |- omap_device_idle() |- omap_hwmod_idle() |- _idle() |- disbale module (syscclocks) Above call sequence explains what's going on when .suspend_noirq() is called - .suspend_noirq() handler == _od_suspend_noirq() and it's set for all OMAP2+ devices. And in this example you are assuming that you need separate idle and sleep states, which is not true at least for most cases I've seen. I don't need both states (at least right now) :), but - if any OMAP2+ driver will have two states defined: idle and sleep - and if it will try to manage them from drivers callbacks only using pure calls to pinctrl_pm_select_xx() helpers the idle state will be selected during suspend and *not* sleep. But the drivers have separate calls for runtime PM and suspend/resume? Yes, but for OMAP2+ everything is handled by OMAP device framework :) It is possible that am33xx needs separate idle and sleep states, but most likely only for some pins. For omap[345] we can get away with just the default state for most cases. In case, if only default state is defined for device - nothing will be done by OMAP device framework for it (I mean any call to pinctrl_pm_select_xx() will do nothing - it just checks that there is no state and returns 0). If we want to automate something, it should be done at Linux generic level rather than at omap bus level. That sort of relates to drivers needing to know when they've lost context too, which should be implemented in Linux generic way. Regards, Tony -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Regression 3.11-rc1: omap4panda: no usb and consequently no ethernet
On 07/18/2013 01:18 PM, Roger Quadros wrote: Hi Arend, On 07/18/2013 11:41 AM, Arend van Spriel wrote: Hi Tony, We are using the panda board (es variant) for testing our SDIO based chips. For this we have an adapter card connection to expansion connector A. As this adapter is not publicly available we had internally patched board-omap4panda.c. Also we follow the -rc releases and use TFTP to boot the kernel image which requires USB. Moving to 3.11-rc1 I found that the mentioned board file was removed by your commit: commit b42b918194c4791510ac049e3d507169a7de8544 Author: Tony Lindgren t...@atomide.com Date: Thu May 30 12:53:05 2013 -0700 ARM: OMAP2+: Remove board-omap4panda.c As our patches on that file are internal I do not hold it against you. This is no regression and we need to fix it. So my first step was to follow the recipe given in that commit. Beside that I noticed a thread about USB issue on LKML so I also applied the following commit: commit 352f573e59050c7a604c35c58b4bbfc51edebbee Author: Roger Quadros rog...@ti.com Date: Tue Jun 18 19:04:47 2013 +0300 ARM: OMAP2+: Provide alias to USB PHY clock The attached kernel log seems to suggest that the device tree is picked up by the kernel, but the USB does not seem very active. No ethernet connectivity. This does seem a regression to me. Is there some other patch that I need to get it going again? I tried with your config and 3.11-rc1 kernel with the above commit on top and ethernet seems to work for me. My boot log is attached. Are you sure that you are building the DTB for panda-es and the bootloader is picking up the right file and not an outdated one? I appended the DTB to the kernel image thus avoiding the need to update u-boot (at least that is what I understood from Tony's commit). Why is the version of SPL loader and u-boot different in your log? You need to use the MLO file generated by the u-boot build along with the uImage. Just to be sure we are on the same setup could you please try with latest u-boot release (2013-04). Thanks. I recall having difficulty with TFTP boot using a 2013 u-boot release, but that hurdle is for later. I will try. cheers, -roger Thanks, Arend -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv4 2/3] drivers: spi: Add qspi flash controller
On Thu, Jul 18, 2013 at 04:48:41PM +0530, Sourav Poddar wrote: +static void qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t) +{ + const u8 *txbuf; + int wlen, count; + + count = t-len; + txbuf = t-tx_buf; + wlen = t-bits_per_word; + + while (count--) { + dev_dbg(qspi-dev, tx cmd %08x dc %08x data %02x\n, + qspi-cmd | QSPI_WR_SNGL, qspi-dc, *txbuf); + ti_qspi_writel_data(qspi, *txbuf++, QSPI_SPI_DATA_REG, wlen); you always increment by each byte. Here, if you used writel(), you wrote 4 bytes and should increment txbuf by 4. hmm..got this point. Yes, my mistake, here I agree if wlen is not 8 bits txbuf++ is not valid. Same goes for read_data(), below. Another thing. Even though your wlen might be 8 bits, if you write 4 bytes to write, you can save a few CPU cycles by using writel(). Do you mean 4 words of 8 bits? yeah. Say you have wlen = 8 but the transfer length is 8 bytes (64 bits). If you use writeb(), you will do 8 writes, if you use writel() you'll do 2 writes. +static int ti_qspi_start_transfer_one(struct spi_master *master, + struct spi_message *m) +{ + struct ti_qspi *qspi = spi_master_get_devdata(master); + struct spi_device *spi = m-spi; + struct spi_transfer *t; + int status = 0, ret; + int frame_length; + + /* setup device control reg */ + qspi-dc = 0; + + if (spi-mode SPI_CPHA) + qspi-dc |= QSPI_CKPHA(spi-chip_select); + if (spi-mode SPI_CPOL) + qspi-dc |= QSPI_CKPOL(spi-chip_select); + if (spi-mode SPI_CS_HIGH) + qspi-dc |= QSPI_CSPOL(spi-chip_select); + + frame_length = DIV_ROUND_UP(m-frame_length * spi-bits_per_word, + spi-bits_per_word); this calculation doesn't look correct. (m-frame_length * spi-bits_per_word) / spi-bits_per_word = m-frame_length What are you trying to achieve here ? frame_length should be counted in words right ? And we get that value in bytes. So what's the best calculation to convert bytes into words ? If you have 8 bits_per_word you don't need any calculation, but if you have 32 bits_per_word, you _do_ need something. Yes, just derive this formulae with 8 bits per word in mind. Will change. It should be (m-frame_length * 8) / spi-bits_per_word right on. To make sure this will execute a little faster (you never know what several different versions of GCC will do), instead of multiplying by 8, left shift by 3. How will you achieve the number you want ? (hint: 1 byte == 8 bits) And btw, all of these mistakes pretty much tell me that this driver hasn't been tested. How have you tested this driver ? After bootup, I checked for deive detting enumerated as /proc/mtd. After which I am using mtdutils(erase, dump and write utilied to check for the communication with the flash device.) alright, make that clear in your commit log. -- balbi signature.asc Description: Digital signature
Re: Regression 3.11-rc1: omap4panda: no usb and consequently no ethernet
On 07/18/2013 02:24 PM, Arend van Spriel wrote: On 07/18/2013 01:18 PM, Roger Quadros wrote: Hi Arend, On 07/18/2013 11:41 AM, Arend van Spriel wrote: Hi Tony, We are using the panda board (es variant) for testing our SDIO based chips. For this we have an adapter card connection to expansion connector A. As this adapter is not publicly available we had internally patched board-omap4panda.c. Also we follow the -rc releases and use TFTP to boot the kernel image which requires USB. Moving to 3.11-rc1 I found that the mentioned board file was removed by your commit: commit b42b918194c4791510ac049e3d507169a7de8544 Author: Tony Lindgren t...@atomide.com Date: Thu May 30 12:53:05 2013 -0700 ARM: OMAP2+: Remove board-omap4panda.c As our patches on that file are internal I do not hold it against you. This is no regression and we need to fix it. So my first step was to follow the recipe given in that commit. Beside that I noticed a thread about USB issue on LKML so I also applied the following commit: commit 352f573e59050c7a604c35c58b4bbfc51edebbee Author: Roger Quadros rog...@ti.com Date: Tue Jun 18 19:04:47 2013 +0300 ARM: OMAP2+: Provide alias to USB PHY clock The attached kernel log seems to suggest that the device tree is picked up by the kernel, but the USB does not seem very active. No ethernet connectivity. This does seem a regression to me. Is there some other patch that I need to get it going again? I tried with your config and 3.11-rc1 kernel with the above commit on top and ethernet seems to work for me. My boot log is attached. Are you sure that you are building the DTB for panda-es and the bootloader is picking up the right file and not an outdated one? I appended the DTB to the kernel image thus avoiding the need to update u-boot (at least that is what I understood from Tony's commit). I understand this can be a little tedious at first. This is my u-boot boot.txt fatload mmc 0:1 0x825f omap4-panda-es.dtb fatload mmc 0:1 0x8030 uImage set fdt_high 0x setenv bootargs console=ttyO2,115200n8 mem=1G@0x8000 root=/dev/mmcblk0p2 rootwait bootm 0x8030 - 0x825f You need to generate boot.scr from the above boot.txt and place it in SD card boot partition. mkimage -A arm -T script -C none -n Boot Image -d boot.txt boot.scr And of course copy the omap4-panda-es.dtb to SD card boot partition. hope this helps. Why is the version of SPL loader and u-boot different in your log? You need to use the MLO file generated by the u-boot build along with the uImage. Just to be sure we are on the same setup could you please try with latest u-boot release (2013-04). Thanks. I recall having difficulty with TFTP boot using a 2013 u-boot release, but that hurdle is for later. I will try. OK. We can figure this out as well. cheers, -roger -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv4 2/3] drivers: spi: Add qspi flash controller
On Thursday 18 July 2013 04:12 PM, Mark Brown wrote: On Thu, Jul 18, 2013 at 03:31:26PM +0530, Sourav Poddar wrote: QSPI is a kind of spi module that allows single, dual and quad read access to external spi devices. The module has a memory mapped interface which provide direct interface for accessing data form external spi devices. Have you seen the ongoing thread about SPI buses with extra data lines? How does this driver fit in with that? I have tried using it in my patch3 of this series.. --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_SPI_OCTEON) += spi-octeon.o obj-$(CONFIG_SPI_OMAP_UWIRE) += spi-omap-uwire.o obj-$(CONFIG_SPI_OMAP_100K) += spi-omap-100k.o obj-$(CONFIG_SPI_OMAP24XX)+= spi-omap2-mcspi.o +obj-$(CONFIG_QSPI_DRA7xxx) += spi-ti-qspi.o obj-$(CONFIG_SPI_ORION) += spi-orion.o obj-$(CONFIG_SPI_PL022) += spi-pl022.o obj-$(CONFIG_SPI_PPC4xx) += spi-ppc4xx.o Please use SPI_ like the other drivers. Ok. +static int ti_qspi_prepare_xfer(struct spi_master *master) +{ + struct ti_qspi *qspi = spi_master_get_devdata(master); + int ret; + + ret = pm_runtime_get_sync(qspi-dev); + if (ret 0) { + dev_err(qspi-dev, pm_runtime_get_sync() failed\n); + return ret; + } + + return 0; +} This is a very common pattern, it should probably be factored out into the core, probably not even as ops but rather as an actual feature. May be yes. + list_for_each_entry(t,m-transfers, transfer_list) { + qspi-cmd |= QSPI_WLEN(t-bits_per_word); + qspi-cmd |= QSPI_WC_CMD_INT_EN; + + ret = qspi_transfer_msg(qspi, t); + if (ret) { + dev_dbg(qspi-dev, transfer message failed\n); + return -EINVAL; + } + + m-actual_length += t-len; + + if (list_is_last(t-transfer_list,m-transfers)) + goto out; + } The use of list_is_last() here is *realy* strange - what's going on there? We are checking if there is any transfer left, if no we are signalling the flash device about the end of transfer. +static irqreturn_t ti_qspi_isr(int irq, void *dev_id) +{ + struct ti_qspi *qspi = dev_id; + u16 mask, stat; + + irqreturn_t ret = IRQ_HANDLED; + + spin_lock(qspi-lock); + + stat = ti_qspi_readl(qspi, QSPI_SPI_STATUS_REG); + mask = ti_qspi_readl(qspi, QSPI_INTR_ENABLE_SET_REG); + + if (stat mask) + ret = IRQ_WAKE_THREAD; + + spin_unlock(qspi-lock); + + return ret; According to the above code we might interrupt for masked events... that's a bit worrying isn't it? Yes, there is WC interrupt enable bit which enables the interrupt. This interrupt gets disabled by writing to the CLEAR reg in the threaded irq. + ret = devm_request_threaded_irq(pdev-dev, irq, ti_qspi_isr, + ti_qspi_threaded_isr, IRQF_NO_SUSPEND | IRQF_ONESHOT, + dev_name(pdev-dev), qspi); + if (ret 0) { + dev_err(pdev-dev, Failed to register ISR for IRQ %d\n, + irq); + goto free_master; + } Standard question about devm_request_threaded_irq() - how can we be certain it's safe to use during removal? I am not sure about the exact flow. If we see the api description, it says about irq getting freed automatically. Practically, I will check that on removing the driver, cat /proc/interrupts should not show the required interrupt getting registered. Though, I see an api also existing devm_free_irq, which explicitly un allocate your irq requested through devm_* variants. -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC/PATCHv2 3/3] driver: spi: Add quad spi read support
On Thursday 18 July 2013 04:14 PM, Mark Brown wrote: On Thu, Jul 18, 2013 at 03:31:27PM +0530, Sourav Poddar wrote: Since, qspi controller uses quad read. Configuring the command register, if the transfer of data needs dual or quad lines. This patch has been done on top of the following patch[1], which is just the basic idea of adding dual/quad support in spi framework. $subject patch will undergo changes as the parent patch goes[1] [1]: http://comments.gmane.org/gmane.linux.kernel.spi.devel/14047 Just as with commit IDs you should include a plain text description of anything you link to so that people reading your e-mail can tell what you're talking about without going on line. Ok, will keep that in mind for future. Just to give you a brief description here, Requirement is to have a dual/quad support in spi frameowrk, so that drivers can use multiple lines for data transfers. What patch[1] tries to does, is [1]: http://comments.gmane.org/gmane.linux.kernel.spi.devel/14047 is to add to each transfer the bitwidth it supports, so that that bitwidth information can be parsed in controller driver and can be used for respective read/writes. A typical usecase on my side is, I have a spansion flash connected to qspi. Flash device supports quad read with a certain read opcode(QUAD_READ). So, Whenever the opcode send is QUAD_READ, we will append that information as a bitwidth to the spi transfer. This information will be parsed by the controller driver and will be used to configure the cmd reg to do the particular type of reads. -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv4 2/3] drivers: spi: Add qspi flash controller
Hi, On Thu, Jul 18, 2013 at 05:15:45PM +0530, Sourav Poddar wrote: + list_for_each_entry(t,m-transfers, transfer_list) { + qspi-cmd |= QSPI_WLEN(t-bits_per_word); + qspi-cmd |= QSPI_WC_CMD_INT_EN; + + ret = qspi_transfer_msg(qspi, t); + if (ret) { + dev_dbg(qspi-dev, transfer message failed\n); + return -EINVAL; + } + + m-actual_length += t-len; + + if (list_is_last(t-transfer_list,m-transfers)) + goto out; + } The use of list_is_last() here is *realy* strange - what's going on there? We are checking if there is any transfer left, if no we are signalling the flash device about the end of transfer. I'll quote your diff below because I wanted to show where your 'out' label lies: + list_for_each_entry(t, m-transfers, transfer_list) { + qspi-cmd |= QSPI_WLEN(t-bits_per_word); + qspi-cmd |= QSPI_WC_CMD_INT_EN; + + ret = qspi_transfer_msg(qspi, t); + if (ret) { + dev_dbg(qspi-dev, transfer message failed\n); + return -EINVAL; + } + + m-actual_length += t-len; + + if (list_is_last(t-transfer_list, m-transfers)) + goto out; + } + +out: + m-status = status; + spi_finalize_current_message(master); see how it's place right after the closing curly brackets ? In that case, why do you need it ? list_for_each_entry() will do exactly what it says: iterate over each entry on the entry. When it reaches the last one, the loop will end. This renders your list_is_last() check useless. In fact, you could've figured that out if you just spent the time to read list_for_each_entry() carefully. -- balbi signature.asc Description: Digital signature
Re: [PATCH 3/3] ARM: dts: omap4-sdp: add dynamic pin states for uart3/4
Hi Tony, On 07/18/2013 12:04 PM, Tony Lindgren wrote: * Grygorii Strashko grygorii.stras...@ti.com [130718 02:01]: On 07/18/2013 11:09 AM, Tony Lindgren wrote: Don't think it's debug code - IO chain need to be rearmed after each PRCM IO IRQ - otherwise IO wakeup events may be lost (at least on OMAP4, OMAP5 requires more complex handling(( ). Nope, only after the mux register changes. I've verified it on am3730 with off-idle for both serial and wl12xx. Unfortunately, there is a possibility to lose wake up events in case if IO daisy chain will be rearmed (this will clean up all WAKEUPEVENT bits) while there is some pending WAKEUP event present. In this case, pcs_omap_handle_irq() will not call generic_handle_irq(wakeirq). The below patch contains explanation of such kind of issue we've solved in K3.4 http://git.omapzoom.org/?p=kernel/omap.git;a=commit;h=5ff316db224a2c3c23bfe44261275d520b4f78bb Currently, in Mainline the same is possible on OMAP4 (which is SMP) if some Device will be switched to idle and rearm IO chain while there is pending WAKEUP event form USB for example. So, IO rearming need to be delayed until PRCM irq will be served served and PRCM irq handler should finally rearm IO daisy chain. I didn't pick up your padconf patches yet -seems i need to be in sync :) Well you need those for proper wake-up event support.. Below the diff I used to verify IO wake up (It follows old IO daisy chain hanlding models in hwmod before DT): ..then these changes not needed with the pinctrl-single changes. Regards, Tony -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv4 2/3] drivers: spi: Add qspi flash controller
On Thursday 18 July 2013 04:54 PM, Felipe Balbi wrote: On Thu, Jul 18, 2013 at 04:48:41PM +0530, Sourav Poddar wrote: +static void qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t) +{ + const u8 *txbuf; + int wlen, count; + + count = t-len; + txbuf = t-tx_buf; + wlen = t-bits_per_word; + + while (count--) { + dev_dbg(qspi-dev, tx cmd %08x dc %08x data %02x\n, + qspi-cmd | QSPI_WR_SNGL, qspi-dc, *txbuf); + ti_qspi_writel_data(qspi, *txbuf++, QSPI_SPI_DATA_REG, wlen); you always increment by each byte. Here, if you used writel(), you wrote 4 bytes and should increment txbuf by 4. hmm..got this point. Yes, my mistake, here I agree if wlen is not 8 bits txbuf++ is not valid. Same goes for read_data(), below. Another thing. Even though your wlen might be 8 bits, if you write 4 bytes to write, you can save a few CPU cycles by using writel(). Do you mean 4 words of 8 bits? yeah. Say you have wlen = 8 but the transfer length is 8 bytes (64 bits). If you use writeb(), you will do 8 writes, if you use writel() you'll do 2 writes. hmm.. I will check this out. If our wlen is 8, after every 8 bits there will be an interrupt. Will check that out, how that interrupt should be tackled if we desired to read 4 bytes in a single writel/readl. +static int ti_qspi_start_transfer_one(struct spi_master *master, + struct spi_message *m) +{ + struct ti_qspi *qspi = spi_master_get_devdata(master); + struct spi_device *spi = m-spi; + struct spi_transfer *t; + int status = 0, ret; + int frame_length; + + /* setup device control reg */ + qspi-dc = 0; + + if (spi-mode SPI_CPHA) + qspi-dc |= QSPI_CKPHA(spi-chip_select); + if (spi-mode SPI_CPOL) + qspi-dc |= QSPI_CKPOL(spi-chip_select); + if (spi-mode SPI_CS_HIGH) + qspi-dc |= QSPI_CSPOL(spi-chip_select); + + frame_length = DIV_ROUND_UP(m-frame_length * spi-bits_per_word, + spi-bits_per_word); this calculation doesn't look correct. (m-frame_length * spi-bits_per_word) / spi-bits_per_word = m-frame_length What are you trying to achieve here ? frame_length should be counted in words right ? And we get that value in bytes. So what's the best calculation to convert bytes into words ? If you have 8 bits_per_word you don't need any calculation, but if you have 32 bits_per_word, you _do_ need something. Yes, just derive this formulae with 8 bits per word in mind. Will change. It should be (m-frame_length * 8) / spi-bits_per_word right on. To make sure this will execute a little faster (you never know what several different versions of GCC will do), instead of multiplying by 8, left shift by 3. Ok. Will do. How will you achieve the number you want ? (hint: 1 byte == 8 bits) And btw, all of these mistakes pretty much tell me that this driver hasn't been tested. How have you tested this driver ? After bootup, I checked for deive detting enumerated as /proc/mtd. After which I am using mtdutils(erase, dump and write utilied to check for the communication with the flash device.) alright, make that clear in your commit log. Ok. -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Regression 3.11-rc1: omap4panda: no usb and consequently no ethernet
On 07/18/2013 01:30 PM, Roger Quadros wrote: On 07/18/2013 02:24 PM, Arend van Spriel wrote: On 07/18/2013 01:18 PM, Roger Quadros wrote: Hi Arend, On 07/18/2013 11:41 AM, Arend van Spriel wrote: Hi Tony, We are using the panda board (es variant) for testing our SDIO based chips. For this we have an adapter card connection to expansion connector A. As this adapter is not publicly available we had internally patched board-omap4panda.c. Also we follow the -rc releases and use TFTP to boot the kernel image which requires USB. Moving to 3.11-rc1 I found that the mentioned board file was removed by your commit: commit b42b918194c4791510ac049e3d507169a7de8544 Author: Tony Lindgren t...@atomide.com Date: Thu May 30 12:53:05 2013 -0700 ARM: OMAP2+: Remove board-omap4panda.c As our patches on that file are internal I do not hold it against you. This is no regression and we need to fix it. So my first step was to follow the recipe given in that commit. Beside that I noticed a thread about USB issue on LKML so I also applied the following commit: commit 352f573e59050c7a604c35c58b4bbfc51edebbee Author: Roger Quadros rog...@ti.com Date: Tue Jun 18 19:04:47 2013 +0300 ARM: OMAP2+: Provide alias to USB PHY clock The attached kernel log seems to suggest that the device tree is picked up by the kernel, but the USB does not seem very active. No ethernet connectivity. This does seem a regression to me. Is there some other patch that I need to get it going again? I tried with your config and 3.11-rc1 kernel with the above commit on top and ethernet seems to work for me. My boot log is attached. Are you sure that you are building the DTB for panda-es and the bootloader is picking up the right file and not an outdated one? I appended the DTB to the kernel image thus avoiding the need to update u-boot (at least that is what I understood from Tony's commit). I understand this can be a little tedious at first. This is my u-boot boot.txt fatload mmc 0:1 0x825f omap4-panda-es.dtb fatload mmc 0:1 0x8030 uImage set fdt_high 0x setenv bootargs console=ttyO2,115200n8 mem=1G@0x8000 root=/dev/mmcblk0p2 rootwait bootm 0x8030 - 0x825f You need to generate boot.scr from the above boot.txt and place it in SD card boot partition. mkimage -A arm -T script -C none -n Boot Image -d boot.txt boot.scr And of course copy the omap4-panda-es.dtb to SD card boot partition. hope this helps. Thanks for sharing this. Why is the version of SPL loader and u-boot different in your log? You need to use the MLO file generated by the u-boot build along with the uImage. Just to be sure we are on the same setup could you please try with latest u-boot release (2013-04). Thanks. I recall having difficulty with TFTP boot using a 2013 u-boot release, but that hurdle is for later. I will try. OK. We can figure this out as well. I tried with same SPL and u-boot version, but that did not work out. So I moved to v2013.04 and the log looks better. I was especially interested in this: [2.807434] usb 1-1.1: new high-speed USB device number 3 using ehci-omap [2.932495] usb 1-1.1: New USB device found, idVendor=0424, idProduct=ec00 [2.932495] usb 1-1.1: New USB device strings: Mfr=0, Product=0, SerialNumbe0 [2.958770] smsc95xx v1.0.4 Starting logging: OK Initializing random number generator... [3.045806] smsc95xx 1-1.1:1.0 eth0 Regards, Arend -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Regression 3.11-rc1: omap4panda: no usb and consequently no ethernet
On 07/18/2013 03:38 PM, Arend van Spriel wrote: On 07/18/2013 01:30 PM, Roger Quadros wrote: On 07/18/2013 02:24 PM, Arend van Spriel wrote: On 07/18/2013 01:18 PM, Roger Quadros wrote: Hi Arend, On 07/18/2013 11:41 AM, Arend van Spriel wrote: Hi Tony, We are using the panda board (es variant) for testing our SDIO based chips. For this we have an adapter card connection to expansion connector A. As this adapter is not publicly available we had internally patched board-omap4panda.c. Also we follow the -rc releases and use TFTP to boot the kernel image which requires USB. Moving to 3.11-rc1 I found that the mentioned board file was removed by your commit: commit b42b918194c4791510ac049e3d507169a7de8544 Author: Tony Lindgren t...@atomide.com Date: Thu May 30 12:53:05 2013 -0700 ARM: OMAP2+: Remove board-omap4panda.c As our patches on that file are internal I do not hold it against you. This is no regression and we need to fix it. So my first step was to follow the recipe given in that commit. Beside that I noticed a thread about USB issue on LKML so I also applied the following commit: commit 352f573e59050c7a604c35c58b4bbfc51edebbee Author: Roger Quadros rog...@ti.com Date: Tue Jun 18 19:04:47 2013 +0300 ARM: OMAP2+: Provide alias to USB PHY clock The attached kernel log seems to suggest that the device tree is picked up by the kernel, but the USB does not seem very active. No ethernet connectivity. This does seem a regression to me. Is there some other patch that I need to get it going again? I tried with your config and 3.11-rc1 kernel with the above commit on top and ethernet seems to work for me. My boot log is attached. Are you sure that you are building the DTB for panda-es and the bootloader is picking up the right file and not an outdated one? I appended the DTB to the kernel image thus avoiding the need to update u-boot (at least that is what I understood from Tony's commit). I understand this can be a little tedious at first. This is my u-boot boot.txt fatload mmc 0:1 0x825f omap4-panda-es.dtb fatload mmc 0:1 0x8030 uImage set fdt_high 0x setenv bootargs console=ttyO2,115200n8 mem=1G@0x8000 root=/dev/mmcblk0p2 rootwait bootm 0x8030 - 0x825f You need to generate boot.scr from the above boot.txt and place it in SD card boot partition. mkimage -A arm -T script -C none -n Boot Image -d boot.txt boot.scr And of course copy the omap4-panda-es.dtb to SD card boot partition. hope this helps. Thanks for sharing this. Why is the version of SPL loader and u-boot different in your log? You need to use the MLO file generated by the u-boot build along with the uImage. Just to be sure we are on the same setup could you please try with latest u-boot release (2013-04). Thanks. I recall having difficulty with TFTP boot using a 2013 u-boot release, but that hurdle is for later. I will try. OK. We can figure this out as well. I tried with same SPL and u-boot version, but that did not work out. So I moved to v2013.04 and the log looks better. I was especially interested in this: [2.807434] usb 1-1.1: new high-speed USB device number 3 using ehci-omap [2.932495] usb 1-1.1: New USB device found, idVendor=0424, idProduct=ec00 [2.932495] usb 1-1.1: New USB device strings: Mfr=0, Product=0, SerialNumbe0 [2.958770] smsc95xx v1.0.4 Starting logging: OK Initializing random number generator... [3.045806] smsc95xx 1-1.1:1.0 eth0 Cool! :). FYI. I also tested tftpboot from u-boot and NFS root file system and it works fine. cheers, -roger -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv4 2/3] drivers: spi: Add qspi flash controller
On Thu, Jul 18, 2013 at 05:15:45PM +0530, Sourav Poddar wrote: On Thursday 18 July 2013 04:12 PM, Mark Brown wrote: + list_for_each_entry(t,m-transfers, transfer_list) { + qspi-cmd |= QSPI_WLEN(t-bits_per_word); + qspi-cmd |= QSPI_WC_CMD_INT_EN; + + ret = qspi_transfer_msg(qspi, t); + if (ret) { + dev_dbg(qspi-dev, transfer message failed\n); + return -EINVAL; + } + + m-actual_length += t-len; + + if (list_is_last(t-transfer_list,m-transfers)) + goto out; + } The use of list_is_last() here is *realy* strange - what's going on there? We are checking if there is any transfer left, if no we are signalling the flash device about the end of transfer. Please be more specific. How will you ever reach the end of the transfer list in a way which wouldn't cause the for loop to terminate? +static irqreturn_t ti_qspi_isr(int irq, void *dev_id) +{ + struct ti_qspi *qspi = dev_id; + u16 mask, stat; + + irqreturn_t ret = IRQ_HANDLED; + + spin_lock(qspi-lock); + + stat = ti_qspi_readl(qspi, QSPI_SPI_STATUS_REG); + mask = ti_qspi_readl(qspi, QSPI_INTR_ENABLE_SET_REG); + + if (stat mask) + ret = IRQ_WAKE_THREAD; + + spin_unlock(qspi-lock); + + return ret; According to the above code we might interrupt for masked events... that's a bit worrying isn't it? Yes, there is WC interrupt enable bit which enables the interrupt. This interrupt gets disabled by writing to the CLEAR reg in the threaded irq. So why do we report that we handled the interrupt then? Shouldn't we at least warn if we're getting spurious IRQs? + ret = devm_request_threaded_irq(pdev-dev, irq, ti_qspi_isr, + ti_qspi_threaded_isr, IRQF_NO_SUSPEND | IRQF_ONESHOT, + dev_name(pdev-dev), qspi); + if (ret 0) { + dev_err(pdev-dev, Failed to register ISR for IRQ %d\n, + irq); + goto free_master; + } Standard question about devm_request_threaded_irq() - how can we be certain it's safe to use during removal? I am not sure about the exact flow. If we see the api description, it says about irq getting freed automatically. Practically, I will check that on removing the driver, cat /proc/interrupts should not show the required interrupt getting registered. Though, I see an api also existing devm_free_irq, which explicitly un allocate your irq requested through devm_* variants. You're missing the point here - how can you be sure that the interrupt can't fire? signature.asc Description: Digital signature
Re: [PATCHv4 2/3] drivers: spi: Add qspi flash controller
Hi, On Thu, Jul 18, 2013 at 02:18:22PM +0100, Mark Brown wrote: +static irqreturn_t ti_qspi_isr(int irq, void *dev_id) +{ + struct ti_qspi *qspi = dev_id; + u16 mask, stat; + + irqreturn_t ret = IRQ_HANDLED; + + spin_lock(qspi-lock); + + stat = ti_qspi_readl(qspi, QSPI_SPI_STATUS_REG); + mask = ti_qspi_readl(qspi, QSPI_INTR_ENABLE_SET_REG); + + if (stat mask) + ret = IRQ_WAKE_THREAD; + + spin_unlock(qspi-lock); + + return ret; According to the above code we might interrupt for masked events... that's a bit worrying isn't it? Yes, there is WC interrupt enable bit which enables the interrupt. This interrupt gets disabled by writing to the CLEAR reg in the threaded irq. So why do we report that we handled the interrupt then? Shouldn't we at least warn if we're getting spurious IRQs? not spurious. OMAP has two sets of IRQ status registers. One is call IRQSTATUS$n (n = 0, 1, ...) and IRQSTATUS_RAW$n. IRQSTATUS$n will only enable the bits which fired IRQs and aren't masked while IRQSTATUS_RAW$n will also enable the bits which are masked. I could never come up with a use case where we would need to handle IRQs which we decided to mask, but perhaps there might be some cases, I don't know. Based on that, I believe Sourav is reading IRQSTATUS_RAW$n, then he need to clear the masked bits. -- balbi signature.asc Description: Digital signature
Re: [PATCH 4/4] drivers: Add pinctrl handling for dynamic pin states
* Tony Lindgren t...@atomide.com [130718 00:57]: * Stephen Warren swar...@wwwdotorg.org [130717 14:28]: Oh, I see you're trying to check that the set of pins in the active, sleep, and idle states are identical. Right, that's to avoid any further checking during runtime for runtime PM. But I think that pinctrl_check_dynamic() only checks that one state is a subset of the other, not that the two states are equal. Instead, I think you want to comparison coded in pinctrl_check_dynamic() to be: In pinctrl_check_dynamic() we check that the pins match between the states, and the number of found pins matches the first set. I'll take a look if we check the total pins between the two sets. That that is a bit painful right now to check properly as we don't have any sorting, and we could use that elsewhere too for checks probably.. gen_group_list_of_pinctrl_state(s1, array1); gen_group_list_of_pinctrl_state(s2, array2); mismatch = memcmp(array1, array2, length); Well we could allocate and sort the pins, but the number of pins for runtime PM is typically very small for each pin consumer device. Typically you just need to toggle RX pin to GPIO mode for idle. And this check is only done during consumer driver probe time. So optimizing it for larger sets could be done at any point later on as needed. ..so for now, let's just check the total number of pins for the sets like Felipe suggested. I think we're better off improving the pinctrl data first to make various checks easier. What you're suggesting with the mepcmp() can be done easily if we add something like device_get_pins() and have the pins sorted for the various states for a device at the device probe time. Regards, Tony -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv4 2/3] drivers: spi: Add qspi flash controller
On Thu, Jul 18, 2013 at 04:31:58PM +0300, Felipe Balbi wrote: On Thu, Jul 18, 2013 at 02:18:22PM +0100, Mark Brown wrote: So why do we report that we handled the interrupt then? Shouldn't we at least warn if we're getting spurious IRQs? not spurious. OMAP has two sets of IRQ status registers. One is call IRQSTATUS$n (n = 0, 1, ...) and IRQSTATUS_RAW$n. IRQSTATUS$n will only enable the bits which fired IRQs and aren't masked while IRQSTATUS_RAW$n will also enable the bits which are masked. I could never come up with a use case where we would need to handle IRQs which we decided to mask, but perhaps there might be some cases, I don't know. Based on that, I believe Sourav is reading IRQSTATUS_RAW$n, then he need to clear the masked bits. That's not the issue - the issue is that if none of the unmasked interrupts are being asserted we shouldn't be in the interrupt handler in the first place but the driver silently accepts that and reports that it handled the interrupt. signature.asc Description: Digital signature
Re: [PATCHv4 2/3] drivers: spi: Add qspi flash controller
Hi Mark, On Thursday 18 July 2013 08:12 PM, Mark Brown wrote: On Thu, Jul 18, 2013 at 04:31:58PM +0300, Felipe Balbi wrote: On Thu, Jul 18, 2013 at 02:18:22PM +0100, Mark Brown wrote: So why do we report that we handled the interrupt then? Shouldn't we at least warn if we're getting spurious IRQs? not spurious. OMAP has two sets of IRQ status registers. One is call IRQSTATUS$n (n = 0, 1, ...) and IRQSTATUS_RAW$n. IRQSTATUS$n will only enable the bits which fired IRQs and aren't masked while IRQSTATUS_RAW$n will also enable the bits which are masked. I could never come up with a use case where we would need to handle IRQs which we decided to mask, but perhaps there might be some cases, I don't know. Based on that, I believe Sourav is reading IRQSTATUS_RAW$n, then he need to clear the masked bits. That's not the issue - the issue is that if none of the unmasked interrupts are being asserted we shouldn't be in the interrupt handler in the first place but the driver silently accepts that and reports that it handled the interrupt. I believe this is what you hinted at doing.. there is a QSPI_INTR_STATUS_ENABLED_CLEAR register, which indicated the interrupt status. if nothing is set in the above register, I should return IRQ_NONE. -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 0/4] improved support for runtime muxing for pinctrl
Hi all, Here's this series again with hopefully all the comments addressed. As discussed earlier, the pinctrl support for changing some of the consumer device pins during runtime needs some improvment. Regards, Tony --- Tony Lindgren (4): pinctrl: Remove duplicate code in pinctrl_pm_select_state functions pinctrl: Allow pinctrl to have multiple active states pinctrl: Add support for additional dynamic states drivers: Add pinctrl handling for dynamic pin states Documentation/pinctrl.txt | 77 - drivers/base/pinctrl.c| 39 drivers/pinctrl/core.c| 291 +++-- drivers/pinctrl/core.h| 10 + include/linux/pinctrl/consumer.h | 46 + include/linux/pinctrl/devinfo.h |4 include/linux/pinctrl/pinctrl-state.h | 15 +- 7 files changed, 420 insertions(+), 62 deletions(-) -- Signature -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/4] pinctrl: Allow pinctrl to have multiple active states
It's quite common that we need to dynamically change some pins for a device for runtime PM, or toggle a pin between rx and tx. Changing all the pins for a device is not efficient way of doing it. So let's allow setting up multiple active states for pinctrl. Currently we only need PINCTRL_STATIC and PINCTRL_DYNAMIC, where PINCTRL_STATIC covers the current default pins, and PINCTRL_DYNAMIC holds the dynamic pins that need to be toggled. Cc: Felipe Balbi ba...@ti.com Cc: Grygorii Strashko grygorii.stras...@ti.com Cc: Stephen Warren swar...@wwwdotorg.org Signed-off-by: Tony Lindgren t...@atomide.com --- drivers/pinctrl/core.c | 18 ++ drivers/pinctrl/core.h | 10 -- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index a97b717..c9b709b 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -885,7 +885,8 @@ static void pinctrl_free(struct pinctrl *p, bool inlist) mutex_lock(pinctrl_list_mutex); list_for_each_entry_safe(state, n1, p-states, node) { list_for_each_entry_safe(setting, n2, state-settings, node) { - pinctrl_free_setting(state == p-state, setting); + pinctrl_free_setting(state == p-state[PINCTRL_STATIC], +setting); list_del(setting-node); kfree(setting); } @@ -955,13 +956,13 @@ EXPORT_SYMBOL_GPL(pinctrl_lookup_state); int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state) { struct pinctrl_setting *setting, *setting2; - struct pinctrl_state *old_state = p-state; + struct pinctrl_state *old_state = p-state[PINCTRL_STATIC]; int ret; - if (p-state == state) + if (old_state == state) return 0; - if (p-state) { + if (old_state) { /* * The set of groups with a mux configuration in the old state * may not be identical to the set of groups with a mux setting @@ -971,7 +972,7 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state) * but not in the new state, this code puts that group into a * safe/disabled state. */ - list_for_each_entry(setting, p-state-settings, node) { + list_for_each_entry(setting, old_state-settings, node) { bool found = false; if (setting-type != PIN_MAP_TYPE_MUX_GROUP) continue; @@ -989,7 +990,7 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state) } } - p-state = NULL; + p-state[PINCTRL_STATIC] = NULL; /* Apply all the settings for the new state */ list_for_each_entry(setting, state-settings, node) { @@ -1011,7 +1012,7 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state) } } - p-state = state; + p-state[PINCTRL_STATIC] = state; return 0; @@ -1492,7 +1493,8 @@ static int pinctrl_show(struct seq_file *s, void *what) list_for_each_entry(p, pinctrl_list, node) { seq_printf(s, device: %s current state: %s\n, dev_name(p-dev), - p-state ? p-state-name : none); + p-state[PINCTRL_STATIC] ? + p-state[PINCTRL_STATIC]-name : none); list_for_each_entry(state, p-states, node) { seq_printf(s, state: %s\n, state-name); diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 75476b3..ac5a269 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -53,12 +53,18 @@ struct pinctrl_dev { #endif }; +enum pinctrl_states { + PINCTRL_STATIC, + PINCTRL_DYNAMIC, + PINCTRL_NR_STATES, +}; + /** * struct pinctrl - per-device pin control state holder * @node: global list node * @dev: the device using this pin control handle * @states: a list of states for this device - * @state: the current state + * @state: the current state(s) * @dt_maps: the mapping table chunks dynamically parsed from device tree for * this device, if any * @users: reference count @@ -67,7 +73,7 @@ struct pinctrl { struct list_head node; struct device *dev; struct list_head states; - struct pinctrl_state *state; + struct pinctrl_state *state[PINCTRL_NR_STATES]; struct list_head dt_maps; struct kref users; }; -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/4] drivers: Add pinctrl handling for dynamic pin states
We want to have static pin states handled separately from dynamic pin states, so let's add optional state_active. Then if state_active is defined, let's check and make sure state_idle and state_sleep match state_active for the pin groups to avoid checking them during runtime as the active and idle pins may need to be toggled for many devices every time we enter and exit idle. See also Documentation/pinctrl.txt regarding runtime muxing of pins. Cc: Felipe Balbi ba...@ti.com Cc: Greg Kroah-Hartman gre...@linuxfoundation.org Cc: Grygorii Strashko grygorii.stras...@ti.com Cc: Stephen Warren swar...@wwwdotorg.org Signed-off-by: Tony Lindgren t...@atomide.com --- drivers/base/pinctrl.c | 39 +-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/drivers/base/pinctrl.c b/drivers/base/pinctrl.c index 5fb74b4..49644ed 100644 --- a/drivers/base/pinctrl.c +++ b/drivers/base/pinctrl.c @@ -34,6 +34,7 @@ int pinctrl_bind_pins(struct device *dev) goto cleanup_alloc; } + /* Default static pins that don't need to change */ dev-pins-default_state = pinctrl_lookup_state(dev-pins-p, PINCTRL_STATE_DEFAULT); if (IS_ERR(dev-pins-default_state)) { @@ -48,23 +49,57 @@ int pinctrl_bind_pins(struct device *dev) goto cleanup_get; } + /* Optional runtime dynamic pins in addition to the static pins */ + dev-pins-active_state = pinctrl_lookup_state(dev-pins-p, + PINCTRL_STATE_ACTIVE); + if (IS_ERR(dev-pins-active_state)) { + /* Not supplying this state is perfectly legal */ + dev_dbg(dev, no active pinctrl state\n); + } else { + ret = pinctrl_select_dynamic(dev-pins-p, + dev-pins-active_state); + if (ret) { + dev_dbg(dev, failed to select active pinctrl state\n); + goto cleanup_get; + } + } + #ifdef CONFIG_PM /* * If power management is enabled, we also look for the optional * sleep and idle pin states, with semantics as defined in * linux/pinctrl/pinctrl-state.h +* +* Note that if active state is defined, sleep and idle states must +* cover the same pin groups as active state. */ dev-pins-sleep_state = pinctrl_lookup_state(dev-pins-p, PINCTRL_STATE_SLEEP); - if (IS_ERR(dev-pins-sleep_state)) + if (IS_ERR(dev-pins-sleep_state)) { /* Not supplying this state is perfectly legal */ dev_dbg(dev, no sleep pinctrl state\n); + } else if (!IS_ERR(dev-pins-active_state)) { + ret = pinctrl_check_dynamic(dev, dev-pins-active_state, + dev-pins-sleep_state); + if (ret) { + dev_err(dev, sleep state groups do not match active state\n); + dev-pins-sleep_state = ERR_PTR(-EINVAL); + } + } dev-pins-idle_state = pinctrl_lookup_state(dev-pins-p, PINCTRL_STATE_IDLE); - if (IS_ERR(dev-pins-idle_state)) + if (IS_ERR(dev-pins-idle_state)) { /* Not supplying this state is perfectly legal */ dev_dbg(dev, no idle pinctrl state\n); + } else if (!IS_ERR(dev-pins-active_state)) { + ret = pinctrl_check_dynamic(dev, dev-pins-active_state, + dev-pins-idle_state); + if (ret) { + dev_err(dev, idle state groups do not match active state\n); + dev-pins-idle_state = ERR_PTR(-EINVAL); + } + } #endif return 0; -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/4] pinctrl: Add support for additional dynamic states
To toggle dynamic states, let's add the optional active state in addition to the static default state. Then if the optional active state is defined, we can require that idle and sleep states cover the same pingroups as the active state. Then let's add pinctrl_check_dynamic() and pinctrl_select_dynamic() to use instead of pinctrl_select() to avoid breaking existing users. With pinctrl_check_dynamic() we can check that idle and sleep states match the active state for pingroups during init, and don't need to do it during runtime. Then with the states pre-validated, pinctrl_select_dynamic() can just toggle between the dynamic states without extra checks. Note that pinctr_select_state() still has valid use cases, such as changing states when the pins can be shared between two drivers and don't necessarily cover the same pingroups. For dynamic runtime toggling of pin states, we should eventually always use just pinctrl_select_dynamic(). Cc: Felipe Balbi ba...@ti.com Cc: Grygorii Strashko grygorii.stras...@ti.com Cc: Stephen Warren swar...@wwwdotorg.org Signed-off-by: Tony Lindgren t...@atomide.com --- Documentation/pinctrl.txt | 77 ++- drivers/pinctrl/core.c| 226 ++--- include/linux/pinctrl/consumer.h | 46 +++ include/linux/pinctrl/devinfo.h |4 + include/linux/pinctrl/pinctrl-state.h | 15 ++ 5 files changed, 342 insertions(+), 26 deletions(-) diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index 052e13a..0477ec5 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -1283,12 +1283,77 @@ This gives the exact same result as the above construction. Runtime pinmuxing = -It is possible to mux a certain function in and out at runtime, say to move -an SPI port from one set of pins to another set of pins. Say for example for -spi0 in the example above, we expose two different groups of pins for the same -function, but with different named in the mapping as described under -Advanced mapping above. So that for an SPI device, we have two states named -pos-A and pos-B. +Typically runtime pinmuxing is done for runtime PM to mux a device RX pin +to GPIO for wake-up events. And In some cases a shared RX/TX pin may need to +be toggled. Sometimes pins can be also shared between two device drivers. + +In most cases runtime pinmuxing only is needed for some pins on a device, and +most pins can be static. To avoid continuously having to check for all the +pins of a device, pinctrl framework supports grouping device pin states to +static and dynamic states. + +Most devices only need to use the static default state. If a devices has a +need for runtime pinmuxing, the device must define the static default state, +and then the optional dynamic states using the following rules: + +1. The default dynamic states are in addition to the static default state. + +2. The default dynamic states are active, sleep and idle, or active and idle. + +3. At least active and idle, or active and sleep states must be defined. + +4. Out of the dynamic pin states, only one of the active, sleep or idle states + can be active at a time. + +5. The dynamic pin states must all toggle the same pins to avoid unnecessary + checks during runtime. + +6. The pinctrl consumer driver must use pinctrl_select_dynamic() instead of + pinctrl_select_state() to toggle between the dynamic states. + +For example, to mux a serial driver RX pin to GPIO for runtime PM wake-up +events, something like the following can be done. Most of the work is done +by the pinctrl framework as long as the default, active and idle states are +properly defined. + +#include linux/pinctrl/consumer.h + +serial_foo_probe() +{ + ... + if (!pinctrl_pm_is_idle_state_error()) + /* Set driver specific flags for runtime PM */ + ... +} + +static int serial_foo_runtime_suspend(struct device *dev) +{ + ... + res = pinctrl_pm_select_idle_state(dev); + if (ret 0) + return ret; + ... +} + +static int serial_foo_runtime_resume(struct device *dev) +{ + ... + res = pinctrl_pm_select_active_state(dev); + if (ret 0) + return ret; + ... +} + +Currently only runtime muxing for runtime PM has been optimized as that can +happen at high rate every time when idling and unidling devices. For less +latency critical runtime remuxing it is possible to use pinctrl_select_state() +as described below. + +For example, it is possible to move an SPI port from one set of pins to another +set of pins. Say for example for spi0 in the example above, we expose two +different groups of pins for the same function, but with different named in +the mapping as described under Advanced mapping above. So that for an SPI +device, we have two states named pos-A and pos-B. This snippet first muxes the function in the pins defined by group A, enables it, disables and
[PATCH 1/4] pinctrl: Remove duplicate code in pinctrl_pm_select_state functions
There's no need to duplicate essentially the same functions. Let's introduce static int pinctrl_pm_select_state() and make the other related functions call that. This allows us to add support later on for multiple active states, and more optimized dynamic remuxing. Note that we still need to export the various pinctrl_pm_select functions as we want to keep struct pinctrl_state private to the pinctrl code, and cannot replace those with inline functions. Cc: Felipe Balbi ba...@ti.com Cc: Stephen Warren swar...@wwwdotorg.org Signed-off-by: Grygorii Strashko grygorii.stras...@ti.com Signed-off-by: Tony Lindgren t...@atomide.com --- drivers/pinctrl/core.c | 55 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 5b272bf..a97b717 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -1227,23 +1227,36 @@ EXPORT_SYMBOL_GPL(pinctrl_force_default); #ifdef CONFIG_PM /** - * pinctrl_pm_select_default_state() - select default pinctrl state for PM + * pinctrl_pm_select_state() - select pinctrl state for PM * @dev: device to select default state for + * @state: state to set */ -int pinctrl_pm_select_default_state(struct device *dev) +static int pinctrl_pm_select_state(struct device *dev, + struct pinctrl_state *state) { struct dev_pin_info *pins = dev-pins; int ret; - if (!pins) - return 0; - if (IS_ERR(pins-default_state)) - return 0; /* No default state */ - ret = pinctrl_select_state(pins-p, pins-default_state); + if (IS_ERR(state)) + return 0; /* No such state */ + ret = pinctrl_select_state(pins-p, state); if (ret) - dev_err(dev, failed to activate default pinctrl state\n); + dev_err(dev, failed to activate pinctrl state %s\n, + state-name); return ret; } + +/** + * pinctrl_pm_select_default_state() - select default pinctrl state for PM + * @dev: device to select default state for + */ +int pinctrl_pm_select_default_state(struct device *dev) +{ + if (!dev-pins) + return 0; + + return pinctrl_pm_select_state(dev, dev-pins-default_state); +} EXPORT_SYMBOL_GPL(pinctrl_pm_select_default_state); /** @@ -1252,17 +1265,10 @@ EXPORT_SYMBOL_GPL(pinctrl_pm_select_default_state); */ int pinctrl_pm_select_sleep_state(struct device *dev) { - struct dev_pin_info *pins = dev-pins; - int ret; - - if (!pins) + if (!dev-pins) return 0; - if (IS_ERR(pins-sleep_state)) - return 0; /* No sleep state */ - ret = pinctrl_select_state(pins-p, pins-sleep_state); - if (ret) - dev_err(dev, failed to activate pinctrl sleep state\n); - return ret; + + return pinctrl_pm_select_state(dev, dev-pins-sleep_state); } EXPORT_SYMBOL_GPL(pinctrl_pm_select_sleep_state); @@ -1272,17 +1278,10 @@ EXPORT_SYMBOL_GPL(pinctrl_pm_select_sleep_state); */ int pinctrl_pm_select_idle_state(struct device *dev) { - struct dev_pin_info *pins = dev-pins; - int ret; - - if (!pins) + if (!dev-pins) return 0; - if (IS_ERR(pins-idle_state)) - return 0; /* No idle state */ - ret = pinctrl_select_state(pins-p, pins-idle_state); - if (ret) - dev_err(dev, failed to activate pinctrl idle state\n); - return ret; + + return pinctrl_pm_select_state(dev, dev-pins-idle_state); } EXPORT_SYMBOL_GPL(pinctrl_pm_select_idle_state); #endif -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC/PATCHv2 1/3] driver: spi: Modify core to compute the message length
On Thu, Jul 18, 2013 at 03:31:25PM +0530, Sourav Poddar wrote: Make spi core calculate the message length while populating the other transfer parameters. Applied, thanks. signature.asc Description: Digital signature
Re: [PATCHv4 2/3] drivers: spi: Add qspi flash controller
On Thu, Jul 18, 2013 at 08:25:05PM +0530, Sourav Poddar wrote: there is a QSPI_INTR_STATUS_ENABLED_CLEAR register, which indicated the interrupt status. if nothing is set in the above register, I should return IRQ_NONE. Yes, and/or complain in the log. signature.asc Description: Digital signature
Re: [PATCH 01/15] drivers: phy: add generic PHY framework
On Thu, Jul 18, 2013 at 02:29:52PM +0530, Kishon Vijay Abraham I wrote: Hi, On Thursday 18 July 2013 12:50 PM, Greg KH wrote: On Thu, Jul 18, 2013 at 12:16:10PM +0530, Kishon Vijay Abraham I wrote: +struct phy_provider *__of_phy_provider_register(struct device *dev, + struct module *owner, struct phy * (*of_xlate)(struct device *dev, + struct of_phandle_args *args)); +struct phy_provider *__devm_of_phy_provider_register(struct device *dev, + struct module *owner, struct phy * (*of_xlate)(struct device *dev, + struct of_phandle_args *args)) + +__of_phy_provider_register and __devm_of_phy_provider_register can be used to +register the phy_provider and it takes device, owner and of_xlate as +arguments. For the dt boot case, all PHY providers should use one of the above +2 APIs to register the PHY provider. Why do you have __ for the prefix of a public function? Is that really the way that OF handles this type of thing? I have a macro of_phy_provider_register/devm_of_phy_provider_register that calls these functions and should be used by the PHY drivers. Probably I should make a mention of it in the Documentation. Yes, mention those as you never want to be calling __* functions directly, right? + ret = dev_set_name(phy-dev, %s.%d, dev_name(dev), id); Your naming is odd, no phy anywhere in it? You rely on the sender to never send a duplicate name.id pair? Why not create your own ids based on the number of phys in the system, like almost all other classes and subsystems do? hmm.. some PHY drivers use the id they provide to perform some of their internal operation as in [1] (This is used only if a single PHY provider implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO to give the PHY drivers an option to use auto id. [1] - http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html No, who cares about the id? No one outside of the phy core ever should, because you pass back the only pointer that they really do care about, if they need to do anything with the device. Use that, and then you can rip out all of the search for a phy by a string logic, as that's not needed either. Just stick to the pointer, it's easier, and safer that way. +static inline int phy_pm_runtime_get(struct phy *phy) +{ + if (WARN(IS_ERR(phy), Invalid PHY reference\n)) + return -EINVAL; Why would phy ever not be valid and a error pointer? And why dump the stack if that happens, that seems really extreme. hmm.. there might be cases where the same controller in one soc needs PHY control and in some other soc does not need PHY control. In such cases, we might get error pointer here. I'll change WARN to dev_err. I still don't understand. You have control over the code that calls these functions, just ensure that they pass in a valid pointer, it's that simple. Or am I missing something? thanks, greg k-h -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
omap_hsmmc: race between omap_hsmmc_start_command() and DMA callback
Hi, I'm facing a NULL pointer dereference in omap_hsmmc_start_command() on an AM33xx board running 3.11-rc1 (DMA enabled). A quick debug session showed that DMA engine timing leads to a very reproducable race condition. In omap_hsmmc_request(), we have: host-mrq = req; omap_hsmmc_prepare_data() omap_hsmmc_start_dma_transfer() tx-callback = omap_hsmmc_dma_callback; [*] omap_hsmmc_start_command() if (cmd == host-mrq-stop) [-- oops] ... It turns out that omap_hsmmc_dma_callback() (which sets host-mrq = NULL) is entered just after the DMA submission, and *before* omap_hsmmc_start_command() is called, consequently leading to an Oops. I can debug this in more depth, but maybe someone has an idea already? Thanks, Daniel -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: omap_hsmmc: race between omap_hsmmc_start_command() and DMA callback
On Thursday 18 July 2013 09:36 PM, Daniel Mack wrote: Hi, I'm facing a NULL pointer dereference in omap_hsmmc_start_command() on an AM33xx board running 3.11-rc1 (DMA enabled). A quick debug session showed that DMA engine timing leads to a very reproducable race condition. In omap_hsmmc_request(), we have: host-mrq = req; omap_hsmmc_prepare_data() omap_hsmmc_start_dma_transfer() tx-callback = omap_hsmmc_dma_callback; [*] omap_hsmmc_start_command() if (cmd == host-mrq-stop) [-- oops] ... It turns out that omap_hsmmc_dma_callback() (which sets host-mrq = NULL) is entered just after the DMA submission, and *before* omap_hsmmc_start_command() is called, consequently leading to an Oops. I can debug this in more depth, but maybe someone has an idea already? Can you check with this hack patch in addition to other dependent patch for adding edma nodes to dt[1] and slave sg limit [2] diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index a432e6c..5a19164 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -1262,8 +1262,8 @@ int edma_start(unsigned channel) if (test_bit(channel, edma_cc[ctlr]-edma_unused)) { pr_debug(EDMA: ESR%d %08x\n, j, edma_shadow0_read_array(ctlr, SH_ESR, j)); - edma_shadow0_write_array(ctlr, SH_ESR, j, mask); - return 0; +// edma_shadow0_write_array(ctlr, SH_ESR, j, mask); +// return 0; } /* EDMA channel with event association */ -- [1] https://lkml.org/lkml/2013/6/18/49 [2] https://patchwork.kernel.org/patch/2228041/ Thanks, Daniel -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: ARM: AM335x: Kernel oops when using EDMA and MMC
On Wednesday 17 July 2013 10:08 PM, Joel Fernandes wrote: On 07/17/2013 10:55 AM, Mark Jackson wrote: I'm trying to get the MMC port working on our custom AM3352 CPU board. I have added MMC entries to out dts file (similar to [1]), and I've enabled CONFIG_TI_EDMA. Our board boots fine without an SD card inserted ... [0.00] Booting Linux on physical CPU 0x0 [0.00] Linux version 3.11.0-rc1-00025-g95b9b72 (mpfj@mpfj-nanobone) (gcc version 4.6.3 (Buildroot 2013.02-dirty) ) #309 Wed Jul 17 16:37:28 BST 2013 ... [2.789028] VFS: Mounted root (ubifs filesystem) on device 0:12. [2.797268] devtmpfs: mounted [2.801032] Freeing unused kernel memory: 200K (c0551000 - c0583000) ... Welcome to Buildroot nanobone login: But when I boot with a card already inserted, I get the following oops ... ... [1.827343] Unable to handle kernel NULL pointer dereference at virtual address 000c [1.835868] pgd = c0004000 [1.838774] [000c] *pgd= [1.842556] Internal error: Oops: 5 [#1] ARM [1.847063] CPU: 0 PID: 6 Comm: kworker/u2:0 Not tainted 3.11.0-rc1-00025-g95b9b72 #309 [1.855511] Workqueue: kmmcd mmc_rescan [1.859556] task: cf06a080 ti: cf072000 task.ti: cf072000 [1.865257] PC is at omap_hsmmc_start_command+0x74/0xf4 [1.870761] LR is at omap_hsmmc_request+0xec/0x4dc [1.875806] pc : [c0305b70]lr : [c0306c64]psr: 6113 [1.875806] sp : cf073ca0 ip : fp : 0008 [1.887885] r10: cf073de8 r9 : 0001 r8 : cf11d918 [1.893382] r7 : 0003 r6 : cf33cc80 r5 : 0001 r4 : 0033 [1.900250] r3 : 0002 r2 : cf073db8 r1 : cf073d84 r0 : cf33cc80 [1.907122] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel [1.914813] Control: 10c5387d Table: 80004019 DAC: 0015 [1.920859] Process kworker/u2:0 (pid: 6, stack limit = 0xcf072238) [1.927454] Stack: (0xcf073ca0 to 0xcf074000) [1.932048] 3ca0: cf33c800 cf073d40 0003 c0076a8c cf073d40 48060220 48060220 [1.940659] 3cc0: 0004 0004 0002 0002 cf073ec8 c0421a9c c051835c cf073d40 [1.949271] 3ce0: cf33c800 0001 0008 0008 0002 cf073db8 cf073ec8 c02f0f28 [1.957882] 3d00: 0200 0064 cf073db8 cf073ec8 cf073d40 cf073d50 [1.966493] 3d20: cf33c800 c02f18a4 cf369800 cf369a80 cf360880 0008 c02f9964 [1.975104] 3d40: cf073d84 cf073db8 0001 0001 dead4ead [1.983717] 3d60: c0af722c c06aa3e4 c04ddadc cf073d74 cf073d74 c02f0dc4 [1.992327] 3d80: 0033 00b5 [2.000938] 3da0: cf073db8 cf073d40 05f5e100 [2.009548] 3dc0: 0008 0001 0200 cf073d40 0001 [2.018159] 3de0: cf073de8 c0cf1c02 0880 0008 8f360880 cf369800 [2.026771] 3e00: cf33c800 cf369800 cf073e4c cf072000 c02f8740 0015 [2.035382] 3e20: 0003 cf33c800 cf369800 cf073e4c cf072000 c02f8b20 [2.043994] 3e40: 0002 c02f25cc 0002 02544d53 41303447 1026c914 2600bbbd c0ff8000 [2.052605] 3e60: c0455884 cf33c800 c0455884 c0455890 cf072000 c02f92bc [2.061217] 3e80: c0455890 00ff8000 0002 cf33cb14 cf33c800 c02f3a28 cf041ac0 cf33cb14 [2.069829] 3ea0: cf050c00 cf051c00 c00507ec 0002 c0050778 c0050f10 [2.078441] 3ec0: c0af7268 c06aa1c4 c0518cd0 cf06a080 cf041ac0 [2.087054] 3ee0: cf050c00 cf072000 cf050c30 cf041ad8 0089 c05d7b5c cf050c00 c0050e4c [2.095665] 3f00: cf072000 6113 cf04dda8 cf041ac0 c0050d08 [2.104276] 3f20: c0056c94 c0429a18 0001 cf041ac0 [2.112888] 3f40: 0001 dead4ead c05ec0a0 [2.121499] 3f60: c04ddadc cf073f64 cf073f64 0001 dead4ead [2.130112] 3f80: c05ec0a0 c04ddadc cf073f90 cf073f90 cf073fac cf04dda8 [2.138724] 3fa0: c0056bf0 c0013588 [2.147334] 3fc0: [2.155946] 3fe0: 0013 57e0c5db 5ffb7d3c [2.164565] [c0305b70] (omap_hsmmc_start_command+0x74/0xf4) from [0003] (0x3) [2.172814] Code: 13a03801 0a1b e590c008 e5914000 (e59cc00c) [2.179314] ---[ end trace 6ec9899a56aef6aa ]--- I have also noticed that when the kernel boots okay (without a card inserted), if I then insert a card, nothing happens (even with CONFIG_MMC_DEBUG=y) ... including no kernel oops. Can anyone shed light on what's wrong ? I see this issue too on -rc1. The mmc host pointer is mangled but this
[PATCH 0/3] Add crossbar driver
Some socs have a large number of interrupts/dma requests to service the needs of its many peripherals and subsystems. All of the requests lines from the subsystems are not needed at the same time, so they have to be muxed to the controllers appropriately. In such places a interrupt/dma controllers are preceded by an IRQ/DMA CROSSBAR that provides flexibility in muxing the device requests to the controller inputs. This series adds a crossbar driver and the DT bindings for the same. Also the DT nodes for DRA7xx SOC which has a IRQ/DMA crossbar has been added here. This series is on top of the basic DRA support from Rajendra [1][2] [1] http://comments.gmane.org/gmane.linux.ports.arm.omap/100763 [2] http://comments.gmane.org/gmane.linux.ports.arm.omap/100773 Sricharan R (3): misc: Add crossbar driver ARM: dts: DRA: Add crossbar device binding ARM: DRA: Enable crossbar driver for dra soc .../devicetree/bindings/arm/omap/crossbar.txt | 24 ++ arch/arm/boot/dts/dra7.dtsi| 19 ++ arch/arm/mach-omap2/Kconfig|1 + drivers/misc/Kconfig |8 + drivers/misc/Makefile |1 + drivers/misc/crossbar.c| 258 include/linux/crossbar.h | 71 ++ 7 files changed, 382 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/omap/crossbar.txt create mode 100644 drivers/misc/crossbar.c create mode 100644 include/linux/crossbar.h -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] ARM: dts: DRA: Add crossbar device binding
This adds the irq/dma crossbar device nodes. There is a IRQ and DMA crossbar device in the soc, which maps the irq/dma requests from the peripherals to the mpu/dsp/ipu/eve interrupt and sdma/edma controller's inputs. The Peripheral irq/dma requests are connected to only one crossbar input and the output of the crossbar is connected to only one controller's input line. On POR, there are some mappings which are done by default. Those peripherals which do not have a mapping on POR, should be configured to route its requests using the crossbar control registers. The irq/dma mapping for some peripherals are added with the crossbar nodes here. Signed-off-by: Sricharan R r.sricha...@ti.com --- arch/arm/boot/dts/dra7.dtsi | 19 +++ 1 file changed, 19 insertions(+) diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index a5d9350..e6208b4 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -85,6 +85,25 @@ ranges; ti,hwmods = l3_main_1, l3_main_2; + crossbar_mpu: mpuirq@4a002a48 { + compatible = crossbar; + crossbar-name = mpu-irq; + reg = 0x4a002a48 0x0130; + reg-width = 16; + crossbar-lines = mpu-irq, rtc-ss-alarm, 0x9f 0xd9 0x12c, +mpu-irq, mcasp3-arevt, 0x9e 0x96 0x12a, +mpu-irq, mcasp3-axevt, 0x9d 0x97 0x128; + }; + + crossbar_dma: dmareq@4a002b78 { + compatible = crossbar; + crossbar-name = dma-req; + reg = 0x4a002b78 0x0100; + reg-width = 16; + crossbar-lines = dma-req, mcasp3-rx, 0x7e 0x84 0xfc, +dma-req, mcasp3-tx, 0x7d 0x85 0xfa; + }; + counter32k: counter@4ae04000 { compatible = ti,omap-counter32k; reg = 0x4ae04000 0x40; -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] ARM: DRA7xx: Enable crossbar driver for the soc
Enable the crossbar driver to handle the irq/dma crossbar devices in the soc. Signed-off-by: Sricharan R r.sricha...@ti.com --- arch/arm/mach-omap2/Kconfig |1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 80aaadc..3def350 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -120,6 +120,7 @@ config SOC_DRA7XX select ARM_GIC select HAVE_SMP select COMMON_CLK + select CROSSBAR comment OMAP Core Type depends on ARCH_OMAP2 -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] misc: Add crossbar driver
Some socs have a large number of interrupts/dma requests to service the needs of its many peripherals and subsystems. All of the requests lines from the subsystems are not needed at the same time, so they have to be muxed to the controllers appropriately. In such places a interrupt/dma controllers are preceded by an IRQ/DMA CROSSBAR that provides flexibility in muxing the device requests to the controller inputs. The Peripheral irq/dma requests are connected to one crossbar's input and the output of the crossbar is connected to controller's input line. On POR, there are some mappings which are done by default. Those peripherals which do not have a mapping on POR, should be configured to route its requests using the crossbar. The drivers identifies every controller's crossbar as individual devices. The mappings can be specified from the DT crossbar nodes and those gets mapped during the crossbar device's probe. The mappings can also be specified by adding the crossbar lines to the peripheral device nodes and map it with crossbar_map/unmap apis. Signed-off-by: Sricharan R r.sricha...@ti.com --- .../devicetree/bindings/arm/omap/crossbar.txt | 24 ++ drivers/misc/Kconfig |8 + drivers/misc/Makefile |1 + drivers/misc/crossbar.c| 258 include/linux/crossbar.h | 71 ++ 5 files changed, 362 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/omap/crossbar.txt create mode 100644 drivers/misc/crossbar.c create mode 100644 include/linux/crossbar.h diff --git a/Documentation/devicetree/bindings/arm/omap/crossbar.txt b/Documentation/devicetree/bindings/arm/omap/crossbar.txt new file mode 100644 index 000..02a8a28 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/omap/crossbar.txt @@ -0,0 +1,24 @@ +* TI - IRQ/DMA Crossbar + +This version is an implementation of the Crossbar IRQ/DMA IP + +Required properties: +- compatible : Should be ti,dra-crossbar +- crossbar-name: Name of the controller to which crossbar output is routed +- reg: Contains crossbar register address range +- reg-width: Represents the width of the individual registers +- crossbar-lines: Default mappings.Should contain the crossbar-name + device name, int/dma request number, crossbar number, + register offset in the same order. + +Examples: + crossbar_mpu: mpuirq@4a002a48 { + compatible = crossbar; + crossbar-name = mpu-irq; + reg = 0x4a002a48 0x0130; + reg-width = 16; + crossbar-lines = mpu-irq, rtc-ss-alarm, 0x9f 0xd9 0x12c, +mpu-irq, mcasp3-arevt, 0x9e 0x96 0x12a, +mpu-irq, mcasp3-axevt, 0x9d 0x97 0x128; + }; + diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index c002d86..de89bff 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -527,6 +527,14 @@ config SRAM the genalloc API. It is supposed to be used for small on-chip SRAM areas found on many SoCs. +config CROSSBAR + bool on-chip crossbar driver + select REGMAP_MMIO + help + This driver is for IRQ/DMA crossbar devices which is responsible for + muxing the irq/dma requests from external peripherals to the corresponding + controller's inputs. + source drivers/misc/c2port/Kconfig source drivers/misc/eeprom/Kconfig source drivers/misc/cb710/Kconfig diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index c235d5b..37ce1b8 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -53,3 +53,4 @@ obj-$(CONFIG_INTEL_MEI) += mei/ obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/ obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o obj-$(CONFIG_SRAM) += sram.o +obj-$(CONFIG_CROSSBAR) += crossbar.o diff --git a/drivers/misc/crossbar.c b/drivers/misc/crossbar.c new file mode 100644 index 000..c0a7e83 --- /dev/null +++ b/drivers/misc/crossbar.c @@ -0,0 +1,258 @@ +/* + * IRQ/DMA CROSSBAR DRIVER + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * Sricharan R r.sricha...@ti.com + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if
Re: ARM: AM335x: Kernel oops when using EDMA and MMC
Hi Balaji, On 18.07.2013 18:40, Balaji T K wrote: With DMA channel info retrieved from dt binding on 3.11rc1, unused_chan_list is broken after hwmod cleanup removing mmc sdma resource info, hence pdev resource wont have DMA resource populated. arch/arm/common/edma.c static int prepare_unused_channel_list(struct device *dev, void *data) { struct platform_device *pdev = to_platform_device(dev); int i, ctlr; for (i = 0; i pdev-num_resources; i++) { if ((pdev-resource[i].flags IORESOURCE_DMA) (int)pdev-resource[i].start = 0) { ctlr = EDMA_CTLR(pdev-resource[i].start); clear_bit(EDMA_CHAN_SLOT(pdev-resource[i].start), edma_cc[ctlr]-edma_unused); } } return 0; } int edma_alloc_channel(int channel, if (!unused_chan_list_done) { /* * Scan all the platform devices to find out the EDMA channels * used and clear them in the unused list, making the rest * available for ARM usage. */ ret = bus_for_each_dev(platform_bus_type, NULL, NULL, prepare_unused_channel_list); if (ret 0) return ret; unused_chan_list_done = true; } === with the below hack patch, edma is working fine with mmc on your 3.11rc1+ branch diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index a432e6c..5a19164 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -1262,8 +1262,8 @@ int edma_start(unsigned channel) if (test_bit(channel, edma_cc[ctlr]-edma_unused)) { pr_debug(EDMA: ESR%d %08x\n, j, edma_shadow0_read_array(ctlr, SH_ESR, j)); - edma_shadow0_write_array(ctlr, SH_ESR, j, mask); - return 0; +// edma_shadow0_write_array(ctlr, SH_ESR, j, mask); +// return 0; } /* EDMA channel with event association */ Yes, this in fact works for me as well. Thanks for the quick reply! What would be the proper fix for this? Best, Daniel -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] dma: edma: add device_slave_sg_limits() support
From: Matt Porter mpor...@ti.com Implement device_slave_sg_limits(). EDMA has a finite set of PaRAM slots available for linking a multi-segment SG transfer. In order to prevent any one channel from consuming all PaRAM slots to fulfill a large SG transfer, the driver reports a static per-channel max number of SG segments it will handle. The maximum size of an SG segment is limited by the addr_width and maxburst of a given transfer request. These values are provided by the client driver and used to calculate and return the maximum segment length. [Joel Fernandes jo...@ti.com: Changes for filling sg_limits by DMAEngine implementation and allocating in client, channel parameter is unused in this implementation as all channels have the same capability] Signed-off-by: Matt Porter mpor...@ti.com Signed-off-by: Joel Fernandes jo...@ti.com Cc: Mark Jackson mpfj-l...@newflow.co.uk --- drivers/dma/edma.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c index 5f3e532..964de26 100644 --- a/drivers/dma/edma.c +++ b/drivers/dma/edma.c @@ -462,6 +462,19 @@ static void edma_issue_pending(struct dma_chan *chan) spin_unlock_irqrestore(echan-vchan.lock, flags); } +static inline int edma_get_slave_sg_limits(struct dma_chan *chan, + enum dma_slave_buswidth addr_width, + u32 maxburst, + struct dma_slave_sg_limits *sg_limits) +{ + if (!sg_limits) + return -EINVAL; + sg_limits-max_seg_nr = MAX_NR_SG; + sg_limits-max_seg_len = + (SZ_64K - 1) * addr_width * maxburst; + return 0; +} + static size_t edma_desc_size(struct edma_desc *edesc) { int i; @@ -537,6 +550,7 @@ static void edma_dma_init(struct edma_cc *ecc, struct dma_device *dma, dma-device_alloc_chan_resources = edma_alloc_chan_resources; dma-device_free_chan_resources = edma_free_chan_resources; dma-device_issue_pending = edma_issue_pending; + dma-device_slave_sg_limits = edma_get_slave_sg_limits; dma-device_tx_status = edma_tx_status; dma-device_control = edma_control; dma-dev = dev; -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] dmaengine: add dma_get_slave_sg_limits()
From: Matt Porter mpor...@ti.com Add a dmaengine API to retrieve slave SG transfer limits. The API is optionally implemented by dmaengine drivers and when unimplemented will return a NULL pointer. A client driver using this API provides the required dma channel, address width, and burst size of the transfer. dma_get_slave_sg_limits() returns an SG limits structure with the maximum number and size of SG segments that the given channel can handle. [Joel Fernandes jo...@ti.com: Changes to allocate limits structure in client and fill up in DMAEngine implementation.] Signed-off-by: Matt Porter mpor...@ti.com Signed-off-by: Joel Fernandes jo...@ti.com Cc: Mark Jackson mpfj-l...@newflow.co.uk --- include/linux/dmaengine.h | 45 + 1 file changed, 45 insertions(+) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 96d3e4a..2985878 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -371,6 +371,18 @@ struct dma_slave_config { unsigned int slave_id; }; +/* struct dma_slave_sg_limits - expose SG transfer limits of a channel + * + * @max_seg_nr: maximum number of SG segments supported on a SG/SLAVE + * channel (0 for no maximum or not a SG/SLAVE channel) + * @max_seg_len: maximum length of SG segments supported on a SG/SLAVE + * channel (0 for no maximum or not a SG/SLAVE channel) + */ +struct dma_slave_sg_limits { + u32 max_seg_nr; + u32 max_seg_len; +}; + static inline const char *dma_chan_name(struct dma_chan *chan) { return dev_name(chan-dev-device); @@ -534,6 +546,7 @@ struct dma_tx_state { * struct with auxiliary transfer status information, otherwise the call * will just return a simple status code * @device_issue_pending: push pending transactions to hardware + * @device_slave_sg_limits: return the slave SG capabilities */ struct dma_device { @@ -602,6 +615,10 @@ struct dma_device { dma_cookie_t cookie, struct dma_tx_state *txstate); void (*device_issue_pending)(struct dma_chan *chan); + int (*device_slave_sg_limits)(struct dma_chan *chan, + enum dma_slave_buswidth addr_width, + u32 maxburst, + struct dma_slave_sg_limits *sg_limits); }; static inline int dmaengine_device_control(struct dma_chan *chan, @@ -963,6 +980,34 @@ dma_set_tx_state(struct dma_tx_state *st, dma_cookie_t last, dma_cookie_t used, } } +/** + * dma_get_slave_sg_limits - get DMAC SG transfer capabilities + * @chan: target DMA channel + * @addr_width: address width of the DMA transfer + * @maxburst: maximum DMA transfer burst size + * @sg_limits: point to sg_limits struct to populate with limit info + * + * Get SG transfer capabilities for a specified channel. If the dmaengine + * driver does not implement SG transfer capabilities then NULL is + * returned. + */ +static inline int +dma_get_slave_sg_limits(struct dma_chan *chan, + enum dma_slave_buswidth addr_width, + u32 maxburst, + struct dma_slave_sg_limits *sg_limits) + +{ + + if (chan-device-device_slave_sg_limits sg_limits) + return chan-device-device_slave_sg_limits(chan, + addr_width, + maxburst, + sg_limits); + + return -EINVAL; +} + enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie); #ifdef CONFIG_DMA_ENGINE enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx); -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] mmc: omap_hsmmc: set max_segs based on dma engine limits
From: Matt Porter mpor...@ti.com The EDMA DMAC has a hardware limitation that prevents supporting scatter gather lists with any number of segments. The DMA Engine API reports the maximum number of segments a channel can support via the optional dma_get_slave_sg_limits() API. If the max_nr_segs limit is present, the value is used to configure mmc-max_segs appropriately. [Joel Fernandes jo...@ti.com: Allocate sg_limits structure in client driver, and have the dmaengine implementation fill it up] Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Tony Lindgren t...@atomide.com Signed-off-by: Joel Fernandes jo...@ti.com Cc: Mark Jackson mpfj-l...@newflow.co.uk --- drivers/mmc/host/omap_hsmmc.c |9 + 1 file changed, 9 insertions(+) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index eccedc7..b723095 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1776,6 +1776,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) const struct of_device_id *match; dma_cap_mask_t mask; unsigned tx_req, rx_req; + struct dma_slave_sg_limits dma_sg_limits; struct pinctrl *pinctrl; match = of_match_device(of_match_ptr(omap_mmc_of_match), pdev-dev); @@ -1952,6 +1953,14 @@ static int omap_hsmmc_probe(struct platform_device *pdev) goto err_irq; } + /* Some DMA Engines only handle a limited number of SG segments */ + ret = dma_get_slave_sg_limits(host-rx_chan, + DMA_SLAVE_BUSWIDTH_4_BYTES, + mmc-max_blk_size / 4, + dma_sg_limits); + if (!ret dma_sg_limits.max_seg_nr) + mmc-max_segs = dma_sg_limits.max_seg_nr; + /* Request IRQ for MMC operations */ ret = request_irq(host-irq, omap_hsmmc_irq, 0, mmc_hostname(mmc), host); -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] misc: Add crossbar driver
On Thu, 2013-07-18 at 22:13 +0530, Sricharan R wrote: Some socs have a large number of interrupts/dma requests to service the needs of its many peripherals and subsystems. All of the requests lines from the subsystems are not needed at the same time, so they have to be muxed to the controllers appropriately. In such places a interrupt/dma controllers are preceded by an IRQ/DMA CROSSBAR that provides flexibility in muxing the device requests to the controller inputs. [] diff --git a/drivers/misc/crossbar.c b/drivers/misc/crossbar.c [] +int crossbar_unmap(struct device_node *cbdev_node, unsigned index) [] + list_for_each_entry(cbdev, cb_devlist, node) { + if (strcmp(cbdev-name, tmp.cb_name)) + continue; [] + dev_warn(cbdev-dev, + unmapped int_no %x mapped to cb %x\n, + tmp.int_no, tmp.cb_no); + return 0; [] + dev_warn(cbdev-dev, %s cb entry %d not found\n, + __func__, tmp.cb_no); + return -ENOENT; Why does this function always emit a dev_warn before return? Maybe the first should be dev_info? -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 0/4] Add PWM polarity flag macro for DT
On 07/17/2013 04:54 PM, Laurent Pinchart wrote: Hello, Here's a small patch set that replaces PWM polarity numerical constants with macros in DT. The series, Reviewed-by: Stephen Warren swar...@nvidia.com I'm (very very) slightly hesitant about patch 3/4, since it's moving towards all PWMs having to use the same specifier format, whereas specifiers are at least potentially binding-specific, not device-type-specific. However, consistency is good; there's no need to do something different just for the heck of it. Equally, there's nothing actually stopping a new binding from defining its own format rather than simply deferring to pwm.txt if it absolutely has to, so I think this will turn out fine. -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] dmaengine: add dma_get_slave_sg_limits()
On Thu, Jul 18, 2013 at 11:46:39AM -0500, Joel Fernandes wrote: From: Matt Porter mpor...@ti.com Add a dmaengine API to retrieve slave SG transfer limits. The API is optionally implemented by dmaengine drivers and when unimplemented will return a NULL pointer. A client driver using this API provides the required dma channel, address width, and burst size of the transfer. dma_get_slave_sg_limits() returns an SG limits structure with the maximum number and size of SG segments that the given channel can handle. Hi Joel, I have already resurrected this and generalized the API to get the slave capablities. https://lkml.org/lkml/2013/7/15/147 Please start using this API ~Vinod -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: ARM: AM335x: Kernel oops when using EDMA and MMC
Hi Balaji, On 07/18/2013 11:40 AM, Balaji T K wrote: On Wednesday 17 July 2013 10:08 PM, Joel Fernandes wrote: On 07/17/2013 10:55 AM, Mark Jackson wrote: I'm trying to get the MMC port working on our custom AM3352 CPU board. I have added MMC entries to out dts file (similar to [1]), and I've enabled CONFIG_TI_EDMA. Our board boots fine without an SD card inserted ... [0.00] Booting Linux on physical CPU 0x0 [0.00] Linux version 3.11.0-rc1-00025-g95b9b72 (mpfj@mpfj-nanobone) (gcc version 4.6.3 (Buildroot 2013.02-dirty) ) #309 Wed Jul 17 16:37:28 BST 2013 ... [2.789028] VFS: Mounted root (ubifs filesystem) on device 0:12. [2.797268] devtmpfs: mounted [2.801032] Freeing unused kernel memory: 200K (c0551000 - c0583000) ... Welcome to Buildroot nanobone login: But when I boot with a card already inserted, I get the following oops ... ... [1.827343] Unable to handle kernel NULL pointer dereference at virtual address 000c [1.835868] pgd = c0004000 [1.838774] [000c] *pgd= [1.842556] Internal error: Oops: 5 [#1] ARM [1.847063] CPU: 0 PID: 6 Comm: kworker/u2:0 Not tainted 3.11.0-rc1-00025-g95b9b72 #309 [1.855511] Workqueue: kmmcd mmc_rescan [1.859556] task: cf06a080 ti: cf072000 task.ti: cf072000 [1.865257] PC is at omap_hsmmc_start_command+0x74/0xf4 [1.870761] LR is at omap_hsmmc_request+0xec/0x4dc [1.875806] pc : [c0305b70]lr : [c0306c64]psr: 6113 [1.875806] sp : cf073ca0 ip : fp : 0008 [1.887885] r10: cf073de8 r9 : 0001 r8 : cf11d918 [1.893382] r7 : 0003 r6 : cf33cc80 r5 : 0001 r4 : 0033 [1.900250] r3 : 0002 r2 : cf073db8 r1 : cf073d84 r0 : cf33cc80 [1.907122] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel [1.914813] Control: 10c5387d Table: 80004019 DAC: 0015 [1.920859] Process kworker/u2:0 (pid: 6, stack limit = 0xcf072238) [1.927454] Stack: (0xcf073ca0 to 0xcf074000) [1.932048] 3ca0: cf33c800 cf073d40 0003 c0076a8c cf073d40 48060220 48060220 [1.940659] 3cc0: 0004 0004 0002 0002 cf073ec8 c0421a9c c051835c cf073d40 [1.949271] 3ce0: cf33c800 0001 0008 0008 0002 cf073db8 cf073ec8 c02f0f28 [1.957882] 3d00: 0200 0064 cf073db8 cf073ec8 cf073d40 cf073d50 [1.966493] 3d20: cf33c800 c02f18a4 cf369800 cf369a80 cf360880 0008 c02f9964 [1.975104] 3d40: cf073d84 cf073db8 0001 0001 dead4ead [1.983717] 3d60: c0af722c c06aa3e4 c04ddadc cf073d74 cf073d74 c02f0dc4 [1.992327] 3d80: 0033 00b5 [2.000938] 3da0: cf073db8 cf073d40 05f5e100 [2.009548] 3dc0: 0008 0001 0200 cf073d40 0001 [2.018159] 3de0: cf073de8 c0cf1c02 0880 0008 8f360880 cf369800 [2.026771] 3e00: cf33c800 cf369800 cf073e4c cf072000 c02f8740 0015 [2.035382] 3e20: 0003 cf33c800 cf369800 cf073e4c cf072000 c02f8b20 [2.043994] 3e40: 0002 c02f25cc 0002 02544d53 41303447 1026c914 2600bbbd c0ff8000 [2.052605] 3e60: c0455884 cf33c800 c0455884 c0455890 cf072000 c02f92bc [2.061217] 3e80: c0455890 00ff8000 0002 cf33cb14 cf33c800 c02f3a28 cf041ac0 cf33cb14 [2.069829] 3ea0: cf050c00 cf051c00 c00507ec 0002 c0050778 c0050f10 [2.078441] 3ec0: c0af7268 c06aa1c4 c0518cd0 cf06a080 cf041ac0 [2.087054] 3ee0: cf050c00 cf072000 cf050c30 cf041ad8 0089 c05d7b5c cf050c00 c0050e4c [2.095665] 3f00: cf072000 6113 cf04dda8 cf041ac0 c0050d08 [2.104276] 3f20: c0056c94 c0429a18 0001 cf041ac0 [2.112888] 3f40: 0001 dead4ead c05ec0a0 [2.121499] 3f60: c04ddadc cf073f64 cf073f64 0001 dead4ead [2.130112] 3f80: c05ec0a0 c04ddadc cf073f90 cf073f90 cf073fac cf04dda8 [2.138724] 3fa0: c0056bf0 c0013588 [2.147334] 3fc0: [2.155946] 3fe0: 0013 57e0c5db 5ffb7d3c [2.164565] [c0305b70] (omap_hsmmc_start_command+0x74/0xf4) from [0003] (0x3) [2.172814] Code: 13a03801 0a1b e590c008 e5914000 (e59cc00c) [2.179314] ---[ end trace 6ec9899a56aef6aa ]--- I have also noticed that when the kernel boots okay (without a card inserted), if I then insert a card, nothing happens (even with CONFIG_MMC_DEBUG=y) ... including no kernel
Re: ARM: AM335x: Kernel oops when using EDMA and MMC
On 07/18/2013 11:47 AM, Daniel Mack wrote: Hi Balaji, On 18.07.2013 18:40, Balaji T K wrote: With DMA channel info retrieved from dt binding on 3.11rc1, unused_chan_list is broken after hwmod cleanup removing mmc sdma resource info, hence pdev resource wont have DMA resource populated. arch/arm/common/edma.c static int prepare_unused_channel_list(struct device *dev, void *data) { struct platform_device *pdev = to_platform_device(dev); int i, ctlr; for (i = 0; i pdev-num_resources; i++) { if ((pdev-resource[i].flags IORESOURCE_DMA) (int)pdev-resource[i].start = 0) { ctlr = EDMA_CTLR(pdev-resource[i].start); clear_bit(EDMA_CHAN_SLOT(pdev-resource[i].start), edma_cc[ctlr]-edma_unused); } } return 0; } int edma_alloc_channel(int channel, if (!unused_chan_list_done) { /* * Scan all the platform devices to find out the EDMA channels * used and clear them in the unused list, making the rest * available for ARM usage. */ ret = bus_for_each_dev(platform_bus_type, NULL, NULL, prepare_unused_channel_list); if (ret 0) return ret; unused_chan_list_done = true; } === with the below hack patch, edma is working fine with mmc on your 3.11rc1+ branch diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index a432e6c..5a19164 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -1262,8 +1262,8 @@ int edma_start(unsigned channel) if (test_bit(channel, edma_cc[ctlr]-edma_unused)) { pr_debug(EDMA: ESR%d %08x\n, j, edma_shadow0_read_array(ctlr, SH_ESR, j)); -edma_shadow0_write_array(ctlr, SH_ESR, j, mask); -return 0; +// edma_shadow0_write_array(ctlr, SH_ESR, j, mask); +// return 0; } /* EDMA channel with event association */ Yes, this in fact works for me as well. Thanks for the quick reply! What would be the proper fix for this? Correct fix would be in the common EDMA driver to populate the unused channel list correctly as found by Balaji. Thanks, -Joel -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] dmaengine: add dma_get_slave_sg_limits()
On Thu, Jul 18, 2013 at 11:46:39AM -0500, Joel Fernandes wrote: The API is optionally implemented by dmaengine drivers and when unimplemented will return a NULL pointer. A client driver using this API provides the required dma channel, address width, and burst size of the transfer. dma_get_slave_sg_limits() returns an SG limits structure with the maximum number and size of SG segments that the given channel can handle. Please look at what's already in struct device: struct device { ... struct device_dma_parameters *dma_parms; ... }; This provides: struct device_dma_parameters { /* * a low level driver may set these to teach IOMMU code about * sg limitations. */ unsigned int max_segment_size; unsigned long segment_boundary_mask; }; Now, these are helpfully accessed via: dma_get_max_seg_size(dev) dma_set_max_seg_size(dev) dma_get_seg_boundary(dev) dma_set_seg_boundary(dev, mask) Drivers already use these to work out how to construct the scatterlist before passing it to the DMA API, which means that they should also be used when creating a scatterlist for the DMA engine (think about it - you have to use the DMA API to map the buffers for the DMA engine too.) So, we already have two properties defined on a per-device basis: the maximum size of a scatterlist segment, and the boundary over which any segment must not cross. The former ties up with your max_seg_len() property, though arguably it may depend on the DMA engine access size. The problem with implementing this new API though is that the subsystems (such as SCSI) which already use dma_get_max_seg_size() will be at odds with what is possible via the DMA engine. I strongly suggest using the infrastructure at device level and not implementing some private DMA engine API to convey this information. As for the maximum number of scatterlist entries, really that's a bug in the DMA engine implementations if they can't accept arbitary lengths. I've created DMA engine drivers for implementations where you have to program each segment individually, ones which can have the current and next segments, as well as those which can walk a list. Provided you get informed of a transfer being completed, there really is no reason for a DMA engine driver to limit the number of scatterlist entries that it will accept. -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] misc: Add crossbar driver
Hi, On Thu, Jul 18, 2013 at 10:13:48PM +0530, Sricharan R wrote: Some socs have a large number of interrupts/dma requests to service the needs of its many peripherals and subsystems. All of the requests lines from the subsystems are not needed at the same time, so they have to be muxed to the controllers appropriately. In such places a interrupt/dma controllers are preceded by an IRQ/DMA CROSSBAR that provides flexibility in muxing the device requests to the controller inputs. The Peripheral irq/dma requests are connected to one crossbar's input and the output of the crossbar is connected to controller's input line. On POR, there are some mappings which are done by default. Those peripherals which do not have a mapping on POR, should be configured to route its requests using the crossbar. The drivers identifies every controller's crossbar as individual devices. The mappings can be specified from the DT crossbar nodes and those gets mapped during the crossbar device's probe. The mappings can also be specified by adding the crossbar lines to the peripheral device nodes and map it with crossbar_map/unmap apis. Signed-off-by: Sricharan R r.sricha...@ti.com why isn't this done under pinctrl ? If all it does is mux DMA and IRQ request lines, it should be written as a pinctrl driver no ? -- balbi signature.asc Description: Digital signature
Re: [PATCH 1/3] misc: Add crossbar driver
On 07/18/2013 11:43 AM, Sricharan R wrote: Some socs have a large number of interrupts/dma requests to service the needs of its many peripherals and subsystems. All of the requests lines from the subsystems are not needed at the same time, so they have to be muxed to the controllers appropriately. In such places a interrupt/dma controllers are preceded by an IRQ/DMA CROSSBAR that provides flexibility in muxing the device requests to the controller inputs. The Peripheral irq/dma requests are connected to one crossbar's input and the output of the crossbar is connected to controller's input line. On POR, there are some mappings which are done by default. Those peripherals which do not have a mapping on POR, should be configured to route its requests using the crossbar. The drivers identifies every controller's crossbar as individual devices. The mappings can be specified from the DT crossbar nodes and those gets mapped during the crossbar device's probe. The mappings can also be specified by adding the crossbar lines to the peripheral device nodes and map it with crossbar_map/unmap apis. Signed-off-by: Sricharan R r.sricha...@ti.com --- .../devicetree/bindings/arm/omap/crossbar.txt | 24 ++ drivers/misc/Kconfig |8 + drivers/misc/Makefile |1 + drivers/misc/crossbar.c| 258 include/linux/crossbar.h | 71 ++ 5 files changed, 362 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/omap/crossbar.txt create mode 100644 drivers/misc/crossbar.c create mode 100644 include/linux/crossbar.h diff --git a/Documentation/devicetree/bindings/arm/omap/crossbar.txt b/Documentation/devicetree/bindings/arm/omap/crossbar.txt new file mode 100644 index 000..02a8a28 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/omap/crossbar.txt @@ -0,0 +1,24 @@ +* TI - IRQ/DMA Crossbar + +This version is an implementation of the Crossbar IRQ/DMA IP + +Required properties: +- compatible : Should be ti,dra-crossbar +- crossbar-name: Name of the controller to which crossbar output is routed +- reg: Contains crossbar register address range +- reg-width: Represents the width of the individual registers +- crossbar-lines: Default mappings.Should contain the crossbar-name + device name, int/dma request number, crossbar number, + register offset in the same order. + +Examples: + crossbar_mpu: mpuirq@4a002a48 { + compatible = crossbar; + crossbar-name = mpu-irq; + reg = 0x4a002a48 0x0130; + reg-width = 16; + crossbar-lines = mpu-irq, rtc-ss-alarm, 0x9f 0xd9 0x12c, +mpu-irq, mcasp3-arevt, 0x9e 0x96 0x12a, +mpu-irq, mcasp3-axevt, 0x9d 0x97 0x128; + }; I carry forward my TI internal objection to this approach: NAK. DRA7 uses a cross bar to map a line to GIC interrupt. Flow of interrupt is as follows: hardware IP block -interrupt line- IRQ Cross bar - GIC IRQ line -- MPU IRQ. What we have done today for DRA is to provide IRQ numbers as direct maps from hardware IP block to GIC based on default IRQ cross bar mapping. Lets see what happens as a result of this: https://patchwork.kernel.org/patch/2825148/ (introducing DTS for DRA7) uart1 to uart6 is defined. while in fact 10 uarts exist on IP block. uart1: serial@4806a000 { snip + interrupts = 0 72 0x4; Assumes that GIC interrupt by default mapping used. Now, think of a product that wants to use UART10 instead of UART1, SoC design allows you do that by doing a remapping of GIC interrupt to UART10 - which is awesome. Option 1: u-boot/bootloader mw.l IRQ_CROSSBAR_address with value to map uart10 to GIC IRQ for UART1, Option 2: in kernel do a raw_writel version of option 1. This patch does option 1 in kernel in a fancy way - why the heck would I want to do that when u-boot allows me to do the same thing in uEnv.txt Option 3: map GIC interrupt to IRQ CROSS bar dynamically. a) Allows us to define every single IP available on DRA7 SoC. b) GIC allocation happens dynamically c) allow products use IPs as needed. Sorry, Conceptually option 3 is the right approach in my view. instead of doing uart1: serial@4806a000 { snip + interrupts = GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH; we should be able to do the following: uart1: serial@4806a000 { snip + interrupts = TI_IRQ_CROSSBAR 192 IRQ_TYPE_LEVEL_HIGH; and not worry about the GIC interrupt number used -- Regards, Nishanth Menon -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] dmaengine: add dma_get_slave_sg_limits()
On 07/18/2013 12:08 PM, Russell King - ARM Linux wrote: On Thu, Jul 18, 2013 at 11:46:39AM -0500, Joel Fernandes wrote: The API is optionally implemented by dmaengine drivers and when unimplemented will return a NULL pointer. A client driver using this API provides the required dma channel, address width, and burst size of the transfer. dma_get_slave_sg_limits() returns an SG limits structure with the maximum number and size of SG segments that the given channel can handle. Please look at what's already in struct device: struct device { ... struct device_dma_parameters *dma_parms; ... }; This provides: struct device_dma_parameters { /* * a low level driver may set these to teach IOMMU code about * sg limitations. */ unsigned int max_segment_size; unsigned long segment_boundary_mask; }; Now, these are helpfully accessed via: dma_get_max_seg_size(dev) dma_set_max_seg_size(dev) dma_get_seg_boundary(dev) dma_set_seg_boundary(dev, mask) Drivers already use these to work out how to construct the scatterlist before passing it to the DMA API, which means that they should also be used when creating a scatterlist for the DMA engine (think about it - you have to use the DMA API to map the buffers for the DMA engine too.) So, we already have two properties defined on a per-device basis: the maximum size of a scatterlist segment, and the boundary over which any segment must not cross. The former ties up with your max_seg_len() property, though arguably it may depend on the DMA engine access size. The problem with implementing this new API though is that the subsystems (such as SCSI) which already use dma_get_max_seg_size() will be at odds with what is possible via the DMA engine. Not very clear for this particular case, are you saying the DMAEngine driver implementation should set the max_seg_size of its own struct dev, and then the drivers retrieve it from the channel they are allocated? I strongly suggest using the infrastructure at device level and not implementing some private DMA engine API to convey this information. Certainly see the value. OK with either approach. Can Vinod add to the discussion here, and we can decide a way forward? Is it ok to use the new CAPS API added for now so that we can keep AM33xx MMC alive? seg_size atleast is a real regression, the number of slots limit however is related more to MMC grabbing a lot of slots. Atleast for -rc cycle the seg_size and MMC fixes should go in. As for the maximum number of scatterlist entries, really that's a bug in the DMA engine implementations if they can't accept arbitary lengths. I've created DMA engine drivers for implementations where you have to program each segment individually, ones which can have the current and next segments, as well as those which can walk a list. Provided you get informed of a transfer being completed, there really is no reason for a DMA engine driver to limit the number of scatterlist entries that it will accept. Sure, that makes sense. Can you point to such a typical example implementation to get some ideas? Thanks, -Joel -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/3] ARM: dts: DRA: Add crossbar device binding
On 07/18/2013 11:43 AM, Sricharan R wrote: This adds the irq/dma crossbar device nodes. There is a IRQ and DMA crossbar device in the soc, which maps the irq/dma requests from the peripherals to the mpu/dsp/ipu/eve interrupt and sdma/edma controller's inputs. The Peripheral irq/dma requests are connected to only one crossbar input and the output of the crossbar is connected to only one controller's input line. On POR, there are some mappings which are done by default. Those peripherals which do not have a mapping on POR, should be configured to route its requests using the crossbar control registers. What is POR? Plan on Record? I supppose, we just love our TLA? The irq/dma mapping for some peripherals are added with the crossbar nodes here. Signed-off-by: Sricharan R r.sricha...@ti.com --- arch/arm/boot/dts/dra7.dtsi | 19 +++ 1 file changed, 19 insertions(+) diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index a5d9350..e6208b4 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -85,6 +85,25 @@ ranges; ti,hwmods = l3_main_1, l3_main_2; + crossbar_mpu: mpuirq@4a002a48 { + compatible = crossbar; + crossbar-name = mpu-irq; + reg = 0x4a002a48 0x0130; + reg-width = 16; + crossbar-lines = mpu-irq, rtc-ss-alarm, 0x9f 0xd9 0x12c, +mpu-irq, mcasp3-arevt, 0x9e 0x96 0x12a, +mpu-irq, mcasp3-axevt, 0x9d 0x97 0x128; a) I'd like to use UART10. oh, let me guess: we dont map all cross bar options here.. just certain ones b) I like to use random 6 uarts out of the available 10 uarts on the fly. c) I'd like to use IRQCROSS bar such that i use all the hardware block instances that dont have default GIC IRQ mapping. + }; + + crossbar_dma: dmareq@4a002b78 { + compatible = crossbar; + crossbar-name = dma-req; + reg = 0x4a002b78 0x0100; + reg-width = 16; + crossbar-lines = dma-req, mcasp3-rx, 0x7e 0x84 0xfc, +dma-req, mcasp3-tx, 0x7d 0x85 0xfa; + }; + counter32k: counter@4ae04000 { compatible = ti,omap-counter32k; reg = 0x4ae04000 0x40; -- Regards, Nishanth Menon -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv4 2/3] drivers: spi: Add qspi flash controller
On Thu, Jul 18, 2013 at 3:01 AM, Sourav Poddar sourav.pod...@ti.com wrote: +Required properties: +- compatible : should be ti,dra7xxx-qspi. +- reg: Should contain QSPI registers location and length. +- #address-cells, #size-cells : Must be present if the device has sub-nodes +- ti,hwmods: Name of the hwmod associated to the QSPI What is ti,hwmods? It's not clear from the description. It also doesn't appear to be used in the driver. At least, I did not find any occurrence of hwmods in the driver code. +static inline unsigned long ti_qspi_readl_data(struct ti_qspi *qspi, + unsigned long reg, int wlen) readl means read LONG. That's what the L is for. But this does different widths. +{ + switch (wlen) { + case 8: + return readw(qspi-base + reg); + break; wlen == 8, but readw == 16 bit read? The break after the return isn't necessary. + case 16: + return readb(qspi-base + reg); + break; wlen == 16, but readb == 8 bit read? + case 32: + return readl(qspi-base + reg); wlen == 32, readl == 32, this one makes sense, but +static inline void ti_qspi_writel_data(struct ti_qspi *qspi, + unsigned long val, unsigned long reg, int wlen) + case 32: + writeb(val, qspi-base + reg); + break; A 32 bit write uses an 8 bit write command, while read is 32 bits?? This doesn't make a lot of sense. If it's actually correct, there should be come kind of comment about it. + +static int ti_qspi_setup(struct spi_device *spi) +{ + + clk_ctrl_reg = ti_qspi_readl(qspi, QSPI_SPI_CLOCK_CNTRL_REG); + + clk_ctrl_reg = ~QSPI_CLK_EN; + + /* disable SCLK */ + ti_qspi_writel(qspi, clk_ctrl_reg, QSPI_SPI_CLOCK_CNTRL_REG); Did you read this from Documentation/spi/spi-summary? ** BUG ALERT: for some reason the first version of ** many spi_master drivers seems to get this wrong. ** When you code setup(), ASSUME that the controller ** is actively processing transfers for another device. +static int ti_qspi_probe(struct platform_device *pdev) +{ + + master-mode_bits = SPI_CPOL | SPI_CPHA; Does your device support full duplex? It doesn't look like it does. You should set the SPI_MASER_HALF_DUPLEX flag in master-flags. + + if (!of_property_read_u32(np, ti,spi-num-cs, num_cs)) + master-num_chipselect = num_cs; You didn't document this property. How is this different than the num-cs property already documented in spi-bus bindings? + qspi-base = devm_ioremap_resource(pdev-dev, r); + if (IS_ERR(qspi-base)) { + ret = -ENOMEM; Shouldn't that be ret = PTR_ERR(qspi-base) -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html