Re: [PATCH 1/2] regulator: pbias: use untranslated address to program pbias regulator
On Tue, Aug 25, 2015 at 01:03:04PM +0300, Grygorii Strashko wrote: On 08/19/2015 09:11 PM, Mark Brown wrote: So substract this address from the start of the resource to get the offset? Or provide a wrapper function in the resource code which does that. I'd be very appreciated if you have and can share any thought on How can we get this absolute base address to substract? Ask the syscon device for its resource? Or have it provide an absolute address based interface for that matter? signature.asc Description: Digital signature
Re: [PATCH v2 07/11] mmc: host: omap_hsmmc: add tuning support
On 25 August 2015 at 11:05, Kishon Vijay Abraham I kis...@ti.com wrote: From: Balaji T K balaj...@ti.com MMC tuning procedure is required to support SD card UHS1-SDR104 mode and EMMC HS200 mode. The tuning function omap_execute_tuning() will only be called by the MMC/SD core if the corresponding speed modes are supported by the OMAP silicon which is set in the mmc host caps field. Signed-off-by: Balaji T K balaj...@ti.com Signed-off-by: Viswanath Puttagunta vi...@ti.com Signed-off-by: Sourav Poddar sourav.pod...@ti.com [kis...@ti.com : cleanup the tuning sequence] Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 234 - 1 file changed, 232 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index c042b91..43485c3 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -18,6 +18,7 @@ #include linux/module.h #include linux/init.h #include linux/kernel.h +#include linux/slab.h #include linux/debugfs.h #include linux/dmaengine.h #include linux/seq_file.h @@ -49,6 +50,7 @@ /* OMAP HSMMC Host Controller Registers */ #define OMAP_HSMMC_SYSSTATUS 0x0014 #define OMAP_HSMMC_CON 0x002C +#define OMAP_HSMMC_DLL 0x0034 #define OMAP_HSMMC_SDMASA 0x0100 #define OMAP_HSMMC_BLK 0x0104 #define OMAP_HSMMC_ARG 0x0108 @@ -66,6 +68,7 @@ #define OMAP_HSMMC_ISE 0x0138 #define OMAP_HSMMC_AC120x013C #define OMAP_HSMMC_CAPA0x0140 +#define OMAP_HSMMC_CAPA2 0x0144 #define VS18 (1 26) #define VS30 (1 25) @@ -114,6 +117,7 @@ /* AC12 */ #define AC12_V1V8_SIGEN(1 19) +#define AC12_SCLK_SEL (1 23) #define AC12_UHSMC_MASK(7 16) #define AC12_UHSMC_SDR12 (0 16) #define AC12_UHSMC_SDR25 (1 16) @@ -122,6 +126,18 @@ #define AC12_UHSMC_DDR50 (4 16) #define AC12_UHSMC_RES (0x7 16) +/* DLL */ +#define DLL_SWT(1 20) +#define DLL_FORCE_SR_C_SHIFT 13 +#define DLL_FORCE_SR_C_MASK0x7f +#define DLL_FORCE_VALUE(1 12) +#define DLL_CALIB (1 1) + +#define MAX_PHASE_DELAY0x7c + +/* CAPA2 */ +#define CAPA2_TSDR50 (1 13) + /* Interrupt masks for IE and ISE register */ #define CC_EN (1 0) #define TC_EN (1 1) @@ -202,6 +218,7 @@ struct omap_hsmmc_host { int vqmmc_enabled; resource_size_t mapbase; spinlock_t irq_lock; /* Prevent races with irq handler */ + struct completion buf_ready; unsigned intdma_len; unsigned intdma_sg_idx; unsigned char bus_mode; @@ -229,6 +246,9 @@ struct omap_hsmmc_host { struct omap_hsmmc_next next_data; struct omap_hsmmc_platform_data*pdata; + u32 *tuning_data; + int tuning_size; + /* return MMC cover switch state, can be NULL if not supported. * * possible return values: @@ -245,8 +265,39 @@ struct omap_mmc_of_data { u8 controller_flags; }; +static const u8 ref_tuning_4bits[] = { + 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc, + 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef, + 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb, + 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef, + 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c, + 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee, + 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff, + 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde, +}; + +static const u8 ref_tuning_8bits[] = { + 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, + 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc, + 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff, + 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff, + 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd, + 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, + 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff, + 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, + 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, + 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, + 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, + 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, + 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, + 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, + 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, +}; These bit patterns already exists in the mmc core as a part of the mmc_send_tuning() API. + static void
Re: [PATCH v2 16/16] mmc: host: omap_hsmmc: use mmc_of_parse_voltage to get ocr_avail
On 3 August 2015 at 14:26, Kishon Vijay Abraham I kis...@ti.com wrote: From: Roger Quadros rog...@ti.com For platforms that doesn't have explicit regulator control in MMC, populate voltage-ranges in MMC device tree node and use mmc_of_parse_voltage to get ocr_avail I don't like this. If we are able to fetch the OCR mask via an external regulator, that shall be done. I think the mmc_of_parse_voltage() API and the corresponding DT binding it parses, should be used for those HW when we don't have an external regulator to use. For example if the MMC controller itself somehow controls the voltage levels. Is that really the case for you? Kind regards Uffe Signed-off-by: Roger Quadros rog...@ti.com Signed-off-by: Lokesh Vutla lokeshvu...@ti.com Signed-off-by: Murali Karicheri m-kariche...@ti.com Signed-off-by: Franklin S Cooper Jr fcoo...@ti.com Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- .../devicetree/bindings/mmc/ti-omap-hsmmc.txt |2 ++ drivers/mmc/host/omap_hsmmc.c |9 - 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt index 76bf087..2408e87 100644 --- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt +++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt @@ -22,6 +22,8 @@ ti,dual-volt: boolean, supports dual voltage cards ti,non-removable: non-removable slot (like eMMC) ti,needs-special-reset: Requires a special softreset sequence ti,needs-special-hs-handling: HSMMC IP needs special setting for handling High Speed +voltage-ranges: Specify the voltage range supported if regulator framework +isn't enabled. dmas: List of DMA specifiers with the controller specific format as described in the generic DMA client binding. A tx and rx specifier is required. diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 15973f1..d884d8f 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -2184,7 +2184,13 @@ static int omap_hsmmc_probe(struct platform_device *pdev) goto err_irq; } - mmc-ocr_avail = mmc_pdata(host)-ocr_mask; + if (!mmc_pdata(host)-ocr_mask) { + ret = mmc_of_parse_voltage(pdev-dev.of_node, mmc-ocr_avail); + if (ret) + goto err_parse_voltage; + } else { + mmc-ocr_avail = mmc_pdata(host)-ocr_mask; + } omap_hsmmc_disable_irq(host); @@ -2224,6 +2230,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) err_slot_name: mmc_remove_host(mmc); +err_parse_voltage: omap_hsmmc_reg_put(host); err_irq: device_init_wakeup(pdev-dev, false); -- 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
omap_wdt: node present in device-tree but kmod is not autoloaded
The question is two-folded, hence the crossposting. I have a kernel that runs perfectly on my beaglebone black, except for one thing - the kmod for the watchdog is not autoloaded upon boot albeit the device-tree node is present: ubuntu@beaglebone:~$ dmesg | grep wdt ubuntu@beaglebone:~$ ll /dev/watch* ls: cannot access /dev/watch*: No such file or directory ubuntu@beaglebone:~$ ls -la /proc/device-tree/ocp/wdt\@44e35000/ total 0 drwxr-xr-x 2 root root 0 Aug 25 13:43 . drwxr-xr-x 54 root root 0 Aug 25 13:43 .. -r--r--r-- 1 root root 13 Aug 25 13:43 compatible -r--r--r-- 1 root root 4 Aug 25 13:43 interrupts -r--r--r-- 1 root root 4 Aug 25 13:43 name -r--r--r-- 1 root root 8 Aug 25 13:43 reg -r--r--r-- 1 root root 10 Aug 25 13:43 ti,hwmods ubuntu@beaglebone:~$ cat /proc/device-tree/ocp/wdt\@44e35000/compatible ti,omap3-wdt ubuntu@beaglebone:~$ ls -la /sys/bus/platform/devices/ocp/*wdt* total 0 drwxr-xr-x 3 root root0 Aug 25 13:49 ./ drwxr-xr-x 33 root root0 Aug 25 13:49 ../ -rw-r--r-- 1 root root 4096 Aug 25 13:49 driver_override -r--r--r-- 1 root root 4096 Aug 25 13:49 modalias lrwxrwxrwx 1 root root0 Aug 25 13:49 of_node - ../../../../firmware/devicetree/base/ocp/wdt@44e35000/ drwxr-xr-x 2 root root0 Aug 25 13:49 power/ lrwxrwxrwx 1 root root0 Aug 25 13:49 subsystem - ../../../../bus/platform/ -rw-r--r-- 1 root root 4096 Aug 25 13:49 uevent and if i manually load the module: ubuntu@beaglebone:~$ sudo modprobe omap_wdt ubuntu@beaglebone:~$ dmesg | grep wdt [ 388.104283] omap_wdt: OMAP Watchdog Timer Rev 0x01: initial timeout 60 sec ubuntu@beaglebone:~$ ls -la /dev/watchdog* crw--- 1 root root 10, 130 Aug 25 13:46 /dev/watchdog crw--- 1 root root 251, 0 Aug 25 13:46 /dev/watchdog0 ubuntu@beaglebone:~$ ls -la /sys/bus/platform/devices/ocp/*wdt* total 0 drwxr-xr-x 3 root root0 Aug 25 13:53 . drwxr-xr-x 33 root root0 Aug 25 13:49 .. lrwxrwxrwx 1 root root0 Aug 25 13:53 driver - ../../../../bus/platform/drivers/omap_wdt -rw-r--r-- 1 root root 4096 Aug 25 13:49 driver_override -r--r--r-- 1 root root 4096 Aug 25 13:49 modalias lrwxrwxrwx 1 root root0 Aug 25 13:49 of_node - ../../../../firmware/devicetree/base/ocp/wdt@44e35000 drwxr-xr-x 2 root root0 Aug 25 13:49 power lrwxrwxrwx 1 root root0 Aug 25 13:49 subsystem - ../../../../bus/platform -rw-r--r-- 1 root root 4096 Aug 25 13:49 uevent and then the device works as expected. So here are my questions: 1) My understanding was that, once a device node was present in the device-tree and there was a compatible driver available, it would have been autoloaded, so why it's not happening here? 2) And more importantly, how do i debug these situations? Building a kernel with the driver built-in, and comparing the two dmesgs, didn't show any noticeable difference either. Any idea? -- bye, p. -- 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/11] mmc: omap: fix error return code
On 23 August 2015 at 02:11, Julia Lawall julia.law...@lip6.fr wrote: Return a negative error code on failure. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // smpl @@ identifier ret; expression e1,e2; @@ ( if (\(ret 0\|ret != 0\)) { ... return ret; } | ret = 0 ) ... when != ret = e1 when != ret *if(...) { ... when != ret = e2 when forall return ret; } // /smpl Signed-off-by: Julia Lawall julia.law...@lip6.fr Thanks, applied for next! Kind regards Uffe --- drivers/mmc/host/omap.c |4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 70dcf07..b763b11 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -1420,8 +1420,10 @@ static int mmc_omap_probe(struct platform_device *pdev) host-reg_shift = (mmc_omap7xx() ? 1 : 2); host-mmc_omap_wq = alloc_workqueue(mmc_omap, 0, 0); - if (!host-mmc_omap_wq) + if (!host-mmc_omap_wq) { + ret = -ENOMEM; goto err_plat_cleanup; + } for (i = 0; i pdata-nr_slots; i++) { ret = mmc_omap_new_slot(host, i); -- 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 v2] ARM: OMAP: Change all cpu_is_* occurences to soc_is_*
Currently apart from dra7, omap5 and amx3 all the other SoCs are identified using cpu_is_* functions which is not right since they are all SoCs(System on Chips). Hence changing the SoC identification code to use soc_is instead of cpu_is and keeping defines for cpu_is where needed. This allows us to replace the rest of cpu_is usage along with other fixes as needed. Acked-by: Russell King rmk+ker...@arm.linux.org.uk Signed-off-by: Keerthy j-keer...@ti.com --- Changes in v2: * Corrected a typo in the commit log. arch/arm/mach-omap2/id.c | 30 +++ arch/arm/mach-omap2/soc.h | 193 ++ 2 files changed, 123 insertions(+), 100 deletions(-) diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index e3f713f..24f24d4 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -57,15 +57,15 @@ int omap_type(void) if (val OMAP2_DEVICETYPE_MASK) return val; - if (cpu_is_omap24xx()) { + if (soc_is_omap24xx()) { val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS); - } else if (cpu_is_ti81xx()) { + } else if (soc_is_ti81xx()) { val = omap_ctrl_readl(TI81XX_CONTROL_STATUS); } else if (soc_is_am33xx() || soc_is_am43xx()) { val = omap_ctrl_readl(AM33XX_CONTROL_STATUS); - } else if (cpu_is_omap34xx()) { + } else if (soc_is_omap34xx()) { val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS); - } else if (cpu_is_omap44xx()) { + } else if (soc_is_omap44xx()) { val = omap_ctrl_readl(OMAP4_CTRL_MODULE_CORE_STATUS); } else if (soc_is_omap54xx() || soc_is_dra7xx()) { val = omap_ctrl_readl(OMAP5XXX_CONTROL_STATUS); @@ -122,7 +122,7 @@ static u16 tap_prod_id; void omap_get_die_id(struct omap_die_id *odi) { - if (cpu_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx()) { + if (soc_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx()) { odi-id_0 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_0); odi-id_1 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_1); odi-id_2 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_2); @@ -218,17 +218,17 @@ static void __init omap3_cpuinfo(void) * on available features. Upon detection, update the CPU id * and CPU class bits. */ - if (cpu_is_omap3630()) { + if (soc_is_omap3630()) { cpu_name = OMAP3630; } else if (soc_is_am35xx()) { cpu_name = (omap3_has_sgx()) ? AM3517 : AM3505; - } else if (cpu_is_ti816x()) { + } else if (soc_is_ti816x()) { cpu_name = TI816X; } else if (soc_is_am335x()) { cpu_name = AM335X; } else if (soc_is_am437x()) { cpu_name = AM437x; - } else if (cpu_is_ti814x()) { + } else if (soc_is_ti814x()) { cpu_name = TI814X; } else if (omap3_has_iva() omap3_has_sgx()) { /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */ @@ -275,11 +275,11 @@ void __init omap3xxx_check_features(void) OMAP3_CHECK_FEATURE(status, SGX); OMAP3_CHECK_FEATURE(status, NEON); OMAP3_CHECK_FEATURE(status, ISP); - if (cpu_is_omap3630()) + if (soc_is_omap3630()) omap_features |= OMAP3_HAS_192MHZ_CLK; - if (cpu_is_omap3430() || cpu_is_omap3630()) + if (soc_is_omap3430() || soc_is_omap3630()) omap_features |= OMAP3_HAS_IO_WAKEUP; - if (cpu_is_omap3630() || omap_rev() == OMAP3430_REV_ES3_1 || + if (soc_is_omap3630() || omap_rev() == OMAP3430_REV_ES3_1 || omap_rev() == OMAP3430_REV_ES3_1_2) omap_features |= OMAP3_HAS_IO_CHAIN_CTRL; @@ -697,7 +697,7 @@ void __init omap2_set_globals_tap(u32 class, void __iomem *tap) tap_base = tap; /* XXX What is this intended to do? */ - if (cpu_is_omap34xx()) + if (soc_is_omap34xx()) tap_prod_id = 0x0210; else tap_prod_id = 0x0208; @@ -715,11 +715,11 @@ static const char * const omap_types[] = { static const char * __init omap_get_family(void) { - if (cpu_is_omap24xx()) + if (soc_is_omap24xx()) return kasprintf(GFP_KERNEL, OMAP2); - else if (cpu_is_omap34xx()) + else if (soc_is_omap34xx()) return kasprintf(GFP_KERNEL, OMAP3); - else if (cpu_is_omap44xx()) + else if (soc_is_omap44xx()) return kasprintf(GFP_KERNEL, OMAP4); else if (soc_is_omap54xx()) return kasprintf(GFP_KERNEL, OMAP5); diff --git a/arch/arm/mach-omap2/soc.h b/arch/arm/mach-omap2/soc.h index f97654d..bb824ae 100644 --- a/arch/arm/mach-omap2/soc.h +++ b/arch/arm/mach-omap2/soc.h @@ -148,13 +148,13 @@ static inline int soc_is_omap(void) /* * Macros to group OMAP into cpu classes. * These can be used in most places. - * cpu_is_omap24xx():
Re: [net-next PATCH 1/3] drivers: net: cpsw: add am335x errata workarround for interrutps
On Monday 24 August 2015 03:34 PM, Sekhar Nori wrote: Hi Mugunthan, On Wednesday 12 August 2015 03:22 PM, Mugunthan V N wrote: +static const struct of_device_id cpsw_of_mtable[] = { + { .compatible = ti,cpsw, .data = cpsw_devtype[CPSW], }, + { .compatible = ti,am335x-cpsw, .data = cpsw_devtype[AM335X_CPSW], }, + { .compatible = ti,am4372-cpsw, .data = cpsw_devtype[AM4372_CPSW], }, + { .compatible = ti,dra7-cpsw, .data = cpsw_devtype[DRA7_CPSW], }, I do not see documentation added for these compatibles. Since the series is already applied, can you send additional patches adding documentation? Will submit a patch ASAP Regards Mugunthan V N -- 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 12/17] ARM: dts: am57xx-beagle-x15: Fix regulator populated in MMC1 dt node
Hi Tony, On Thursday 30 July 2015 01:07 AM, Nishanth Menon wrote: On 07/29/2015 06:09 AM, Kishon Vijay Abraham I wrote: For beagle x15, both the vdd and io lines are connected to the same regulator (ldo1_reg). However vmmc_aux is populated to vdd_3v3. Remove it. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- arch/arm/boot/dts/am57xx-beagle-x15.dts |1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/boot/dts/am57xx-beagle-x15.dts b/arch/arm/boot/dts/am57xx-beagle-x15.dts index a63bf78..d0db5c5 100644 --- a/arch/arm/boot/dts/am57xx-beagle-x15.dts +++ b/arch/arm/boot/dts/am57xx-beagle-x15.dts @@ -579,7 +579,6 @@ pinctrl-0 = mmc1_pins_default; vmmc-supply = ldo1_reg; -vmmc_aux-supply = vdd_3v3; pbias-supply = pbias_mmc_reg; bus-width = 4; cd-gpios = gpio6 27 0; /* gpio 219 */ Acked-by: Nishanth Menon n...@ti.com Can you pick this one or you want me to resend it? 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] spi: ti-qspi: use 128 bit transfer mode for writing to flash
On 08/20/2015 11:25 PM, Mark Brown wrote: On Thu, Aug 20, 2015 at 04:00:59PM +0530, Vignesh R wrote: -writeb(*txbuf, qspi-base + QSPI_SPI_DATA_REG); +if (count = QSPI_WLEN_MAX_BYTES) { +u32 *txp = (u32 *)txbuf; + +data = cpu_to_be32(*txp++); +writel(data, qspi-base + + QSPI_SPI_DATA_REG_3); +data = cpu_to_be32(*txp++); +writel(data, qspi-base + + QSPI_SPI_DATA_REG_2); +data = cpu_to_be32(*txp++); +writel(data, qspi-base + + QSPI_SPI_DATA_REG_1); +data = cpu_to_be32(*txp++); +writel(data, qspi-base + + QSPI_SPI_DATA_REG); +xfer_len = QSPI_WLEN_MAX_BYTES; +cmd |= QSPI_WLEN(QSPI_WLEN_MAX_BITS); +} else { +writeb(*txbuf, qspi-base + QSPI_SPI_DATA_REG); +cmd = qspi-cmd | QSPI_WR_SNGL; +xfer_len = wlen; +cmd |= QSPI_WLEN(wlen); +} It's a bit sad that this isn't able to do a Duff's device type thing and only kicks in for the full 128 bit FIFO size, it looks like it could do any number of words. Yes, any number of bytes can be transfered (max 16 bytes). I will try to work on your suggestion. Thanks! -- Regards Vignesh -- 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/2] regulator: pbias: use untranslated address to program pbias regulator
Hi Mark, On 08/19/2015 09:11 PM, Mark Brown wrote: On Tue, Aug 18, 2015 at 11:23:54AM +0530, Kishon Vijay Abraham I wrote: On Friday 14 August 2015 11:30 PM, Mark Brown wrote: On Mon, Jul 27, 2015 at 04:54:09PM +0530, Kishon Vijay Abraham I wrote: is moved as a child node of syscon, vsel_reg and enable_reg has the absolute address because of the address translation that happens while creating device from device tree node. So avoid using platform_get_resource and use of_get_address in order to get only the offset (untranslated address) and populate these in vsel_reg and enable_reg. This sounds like we're going in the wrong direction, we're moving from a more generic API to a firmware specific one. Why is this a good fix? platform_get_resource can be used if we need the absolute address but here we need only the offset. So substract this address from the start of the resource to get the offset? Or provide a wrapper function in the resource code which does that. I'd be very appreciated if you have and can share any thought on How can we get this absolute base address to substract? Below is what we have in DT: l4_cfg: l4@4a00 { compatible = ti,dra7-l4-cfg, simple-bus; #address-cells = 1; #size-cells = 1; ranges = 0 0x4a00 0x22c000; [GS] === 0x4a00 is our top level l4 base address scm: scm@2000 { compatible = ti,dra7-scm-core, simple-bus; reg = 0x2000 0x2000; #address-cells = 1; #size-cells = 1; ranges = 0 0x2000 0x2000; [GS] === 0x4a002000 is our scm-core base address IORESOURCE_MEM: 0x4a002000 : 4A003FFF scm_conf: scm_conf@0 { compatible = syscon, simple-bus; reg = 0x0 0x1400; #address-cells = 1; #size-cells = 1; [GS] === 0x4a002000 is our syscon base address IORESOURCE_MEM: 0x4a002000 : 4A0033FF pbias_regulator: pbias_regulator { compatible = ti,pbias-omap; reg = 0xe00 0x4; [GS] === 0x4a002E00 is our pbias base address IORESOURCE_MEM: 0x4a002E00 : 4A002E03 Here we should use reg_offset=0xE00 as input parameter for regmap APIs. syscon = scm_conf; pbias_mmc_reg: pbias_mmc_omap5 { regulator-name = pbias_mmc_omap5; regulator-min-microvolt = 180; regulator-max-microvolt = 300; }; }; scm_conf_clocks: clocks { #address-cells = 1; #size-cells = 0; }; }; As I understood, all of_address APIs/code is designed to parse/translate addresses in top-bottom direction, and it looks nontrivial to get any kind of base addresses from driver's side (except of its own address), because it will require reverse DT parsing in bottom-top direction. Maybe I missed smth? -- regards, -grygorii -- 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 v2 02/11] mmc: host: omap_hsmmc: separate setting voltage capabilities from bus power
Added a separate function to set the voltage capabilities of the host controller. Voltage capabilities should be set only once during controller initialization but bus power can be changed every time there is a voltage switch and whenever a different card is inserted. This allows omap_hsmmc_conf_bus_power to be invoked every time there is a voltage switch. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 28 +++- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 9c13157..fd8cc81 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1821,25 +1821,34 @@ err: return ret; } +static void omap_hsmmc_set_capabilities(struct omap_hsmmc_host *host) +{ + u32 val; + + val = OMAP_HSMMC_READ(host-base, CAPA); + + /* Only MMC1 supports 3.0V */ + if (host-pdata-controller_flags OMAP_HSMMC_SUPPORTS_DUAL_VOLT) + val |= (VS30 | VS18); + else + val |= VS18; + + OMAP_HSMMC_WRITE(host-base, CAPA, val); +} + static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host) { - u32 hctl, capa, value; + u32 hctl, value; /* Only MMC1 supports 3.0V */ - if (host-pdata-controller_flags OMAP_HSMMC_SUPPORTS_DUAL_VOLT) { + if (host-pdata-controller_flags OMAP_HSMMC_SUPPORTS_DUAL_VOLT) hctl = SDVS30; - capa = VS30 | VS18; - } else { + else hctl = SDVS18; - capa = VS18; - } value = OMAP_HSMMC_READ(host-base, HCTL) ~SDVS_MASK; OMAP_HSMMC_WRITE(host-base, HCTL, value | hctl); - value = OMAP_HSMMC_READ(host-base, CAPA); - OMAP_HSMMC_WRITE(host-base, CAPA, value | capa); - /* Set SD bus power bit */ set_sd_bus_power(host); } @@ -2143,6 +2152,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) mmc-pm_caps |= mmc_pdata(host)-pm_caps; + omap_hsmmc_set_capabilities(host); omap_hsmmc_conf_bus_power(host); if (!pdev-dev.of_node) { -- 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 v2 01/11] mmc: host: omap_hsmmc: Support vmmc_aux to switch to 1.8v
Add support for vmmc_aux to switch to 1.8v. Also use iov instead of vdd to indicate io voltage. This is in preparation for adding support for io signal voltage switch. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 48 +++-- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index d884d8f..9c13157 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -244,11 +244,12 @@ static int omap_hsmmc_get_cover_state(struct device *dev) return mmc_gpio_get_cd(host-mmc); } -static int omap_hsmmc_enable_supply(struct mmc_host *mmc) +static int omap_hsmmc_enable_supply(struct mmc_host *mmc, int iov) { int ret; struct omap_hsmmc_host *host = mmc_priv(mmc); struct mmc_ios *ios = mmc-ios; + int uvoltage; if (mmc-supply.vmmc) { ret = mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, ios-vdd); @@ -257,7 +258,25 @@ static int omap_hsmmc_enable_supply(struct mmc_host *mmc) } /* Enable interface voltage rail, if needed */ - if (mmc-supply.vqmmc !host-vqmmc_enabled) { + if (mmc-supply.vqmmc) { + if (host-vqmmc_enabled) { + ret = regulator_disable(mmc-supply.vqmmc); + if (ret) { + dev_err(mmc_dev(mmc), + vmmc_aux reg disable failed\n); + goto err_vqmmc; + } + host-vqmmc_enabled = 0; + } + + uvoltage = (iov == VDD_165_195) ? VDD_1V8 : VDD_3V0; + ret = regulator_set_voltage(mmc-supply.vqmmc, uvoltage, + uvoltage); + if (ret) { + dev_err(mmc_dev(mmc), vmmc_aux set voltage failed\n); + goto err_vqmmc; + } + ret = regulator_enable(mmc-supply.vqmmc); if (ret) { dev_err(mmc_dev(mmc), vmmc_aux reg enable failed\n); @@ -309,22 +328,19 @@ err_set_ocr: } static int omap_hsmmc_set_pbias(struct omap_hsmmc_host *host, bool power_on, - int vdd) + int iov) { int ret; + int uvoltage; if (!host-pbias) return 0; if (power_on) { - if (vdd = VDD_165_195) - ret = regulator_set_voltage(host-pbias, VDD_1V8, - VDD_1V8); - else - ret = regulator_set_voltage(host-pbias, VDD_3V0, - VDD_3V0); - if (ret 0) { - dev_err(host-dev, pbias set voltage fail\n); + uvoltage = (iov = VDD_165_195) ? VDD_1V8 : VDD_3V0; + ret = regulator_set_voltage(host-pbias, uvoltage, uvoltage); + if (ret) { + dev_err(host-dev, pbias set voltage failed\n); return ret; } @@ -348,7 +364,7 @@ static int omap_hsmmc_set_pbias(struct omap_hsmmc_host *host, bool power_on, return 0; } -static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) +static int omap_hsmmc_set_power(struct device *dev, int power_on, int iov) { struct omap_hsmmc_host *host = platform_get_drvdata(to_platform_device(dev)); @@ -363,7 +379,7 @@ static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) return 0; if (mmc_pdata(host)-before_set_reg) - mmc_pdata(host)-before_set_reg(dev, power_on, vdd); + mmc_pdata(host)-before_set_reg(dev, power_on, iov); ret = omap_hsmmc_set_pbias(host, false, 0); if (ret) @@ -383,11 +399,11 @@ static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) * chips/cards need an interface voltage rail too. */ if (power_on) { - ret = omap_hsmmc_enable_supply(mmc); + ret = omap_hsmmc_enable_supply(mmc, iov); if (ret) return ret; - ret = omap_hsmmc_set_pbias(host, true, vdd); + ret = omap_hsmmc_set_pbias(host, true, iov); if (ret) goto err_set_voltage; } else { @@ -397,7 +413,7 @@ static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) } if (mmc_pdata(host)-after_set_reg) - mmc_pdata(host)-after_set_reg(dev, power_on, vdd); + mmc_pdata(host)-after_set_reg(dev, power_on, iov); return 0; -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to
[PATCH v2 04/11] mmc: host: omap_hsmmc: add voltage switch support for UHS SD card
From: Balaji T K balaj...@ti.com UHS sd card i/o data line can operate at 3V and 1.8V on UHS speed modes. Add support for signal voltage switch and check for card_busy. Signed-off-by: Balaji T K balaj...@ti.com Signed-off-by: Sourav Poddar sourav.pod...@ti.com [kis...@ti.com : cleanup the voltage switch sequence] Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 129 + 1 file changed, 129 insertions(+) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index d3fe0f8..7dac486 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -112,6 +112,9 @@ /* PSTATE */ #define DLEV_DAT(x)(1 (20 + (x))) +/* AC12 */ +#define AC12_V1V8_SIGEN(1 19) + /* Interrupt masks for IE and ISE register */ #define CC_EN (1 0) #define TC_EN (1 1) @@ -151,6 +154,12 @@ #define VDD_1V8180 /* 18 uV */ #define VDD_3V0300 /* 30 uV */ #define VDD_165_195(ffs(MMC_VDD_165_195) - 1) +#define VDD_30_31 (ffs(MMC_VDD_30_31) - 1) + +#define CON_CLKEXTFREE (1 16) +#define CON_PADEN (1 15) +#define PSTATE_CLEV(1 24) +#define PSTATE_DLEV(0xF 20) /* * One controller can have multiple slots, like on some omap boards using @@ -1860,6 +1869,124 @@ static int omap_hsmmc_multi_io_quirk(struct mmc_card *card, return blk_size; } +static int omap_hsmmc_start_signal_voltage_switch(struct mmc_host *mmc, + struct mmc_ios *ios) +{ + struct omap_hsmmc_host *host; + u32 val = 0; + int ret = 0; + + host = mmc_priv(mmc); + + if (ios-signal_voltage == MMC_SIGNAL_VOLTAGE_330) { + val = OMAP_HSMMC_READ(host-base, CAPA); + if (!(val VS30)) + return -EOPNOTSUPP; + + omap_hsmmc_conf_bus_power(host, ios-signal_voltage); + + val = OMAP_HSMMC_READ(host-base, AC12); + val = ~AC12_V1V8_SIGEN; + OMAP_HSMMC_WRITE(host-base, AC12, val); + + ret = mmc_pdata(host)-set_power(host-dev, 1, VDD_30_31); + if (ret) { + dev_dbg(mmc_dev(host-mmc), failed to switch to 3v\n); + return ret; + } + + dev_dbg(mmc_dev(host-mmc), i/o voltage switch to 3V\n); + } else if (ios-signal_voltage == MMC_SIGNAL_VOLTAGE_180) { + val = OMAP_HSMMC_READ(host-base, CAPA); + if (!(val VS18)) + return -EOPNOTSUPP; + + omap_hsmmc_conf_bus_power(host, ios-signal_voltage); + + val = OMAP_HSMMC_READ(host-base, AC12); + val |= AC12_V1V8_SIGEN; + OMAP_HSMMC_WRITE(host-base, AC12, val); + + ret = mmc_pdata(host)-set_power(host-dev, 1, VDD_165_195); + if (ret 0) { + dev_dbg(mmc_dev(host-mmc), failed to switch 1.8v\n); + return ret; + } + } else { + return -EOPNOTSUPP; + } + + return 0; +} + +static int omap_hsmmc_card_busy_low(struct omap_hsmmc_host *host) +{ + u32 val; + unsigned long timeout; + + val = OMAP_HSMMC_READ(host-base, CON); + val = ~CON_CLKEXTFREE; + val |= CON_PADEN; + OMAP_HSMMC_WRITE(host-base, CON, val); + + timeout = jiffies + msecs_to_jiffies(1); + do { + val = OMAP_HSMMC_READ(host-base, PSTATE); + if (!(val (PSTATE_CLEV | PSTATE_DLEV))) + return true; + + usleep_range(100, 200); + } while (!time_after(jiffies, timeout)); + + dev_err(mmc_dev(host-mmc), timeout : i/o low 0x%x\n, val); + + return false; +} + +static int omap_hsmmc_card_busy_high(struct omap_hsmmc_host *host) +{ + u32 val; + unsigned long timeout; + + val = OMAP_HSMMC_READ(host-base, CON); + val |= CLKEXTFREE; + OMAP_HSMMC_WRITE(host-base, CON, val); + + timeout = jiffies + msecs_to_jiffies(1); + do { + val = OMAP_HSMMC_READ(host-base, PSTATE); + if ((val PSTATE_CLEV) (val PSTATE_DLEV)) { + val = OMAP_HSMMC_READ(host-base, CON); + val = ~(CON_CLKEXTFREE | CON_PADEN); + OMAP_HSMMC_WRITE(host-base, CON, val); + return false; + } + + usleep_range(100, 200); + } while (!time_after(jiffies, timeout)); + + dev_err(mmc_dev(host-mmc), timeout : i/o high 0x%x\n, val); + + return true; +} + +static int omap_hsmmc_card_busy(struct mmc_host *mmc) +{ + struct omap_hsmmc_host *host; + u32 val; + int ret; + + host
[PATCH v2 03/11] mmc: host: omap_hsmmc: program HCTL based on signal_voltage set by mmc core
HCTL is now set based on ios.signal_voltage set by mmc core and not hardcoded to 3V0 if OMAP_HSMMC_SUPPORTS_DUAL_VOLT is set. If OMAP_HSMMC_SUPPORTS_DUAL_VOLT is set, it means HCTL can be set to either 3V0 or 1V8. And it should be set to 3V0 or 1V8 depending on ios.signal_voltage. Also it is now set on power mode status being changed to MMC_POWER_ON. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 16 +++- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index fd8cc81..d3fe0f8 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -229,6 +229,7 @@ struct omap_mmc_of_data { }; static void omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host); +static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host, int iov); static int omap_hsmmc_card_detect(struct device *dev) { @@ -1674,6 +1675,7 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) mmc_pdata(host)-set_power(host-dev, 1, ios-vdd); break; case MMC_POWER_ON: + omap_hsmmc_conf_bus_power(host, ios-signal_voltage); do_send_init_stream = 1; break; } @@ -1836,17 +1838,12 @@ static void omap_hsmmc_set_capabilities(struct omap_hsmmc_host *host) OMAP_HSMMC_WRITE(host-base, CAPA, val); } -static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host) +static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host, int iov) { u32 hctl, value; - /* Only MMC1 supports 3.0V */ - if (host-pdata-controller_flags OMAP_HSMMC_SUPPORTS_DUAL_VOLT) - hctl = SDVS30; - else - hctl = SDVS18; - value = OMAP_HSMMC_READ(host-base, HCTL) ~SDVS_MASK; + hctl = (iov == MMC_SIGNAL_VOLTAGE_180) ? SDVS18 : SDVS30; OMAP_HSMMC_WRITE(host-base, HCTL, value | hctl); /* Set SD bus power bit */ @@ -2153,7 +2150,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev) mmc-pm_caps |= mmc_pdata(host)-pm_caps; omap_hsmmc_set_capabilities(host); - omap_hsmmc_conf_bus_power(host); if (!pdev-dev.of_node) { res = platform_get_resource_byname(pdev, IORESOURCE_DMA, tx); @@ -2328,6 +2324,7 @@ static int omap_hsmmc_suspend(struct device *dev) static int omap_hsmmc_resume(struct device *dev) { struct omap_hsmmc_host *host = dev_get_drvdata(dev); + struct mmc_ios *ios; if (!host) return 0; @@ -2337,8 +2334,9 @@ static int omap_hsmmc_resume(struct device *dev) if (host-dbclk) clk_prepare_enable(host-dbclk); + ios = host-mmc-ios; if (!(host-mmc-pm_flags MMC_PM_KEEP_POWER)) - omap_hsmmc_conf_bus_power(host); + omap_hsmmc_conf_bus_power(host, ios-signal_voltage); omap_hsmmc_protect_card(host); pm_runtime_mark_last_busy(host-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 v2 07/11] mmc: host: omap_hsmmc: add tuning support
From: Balaji T K balaj...@ti.com MMC tuning procedure is required to support SD card UHS1-SDR104 mode and EMMC HS200 mode. The tuning function omap_execute_tuning() will only be called by the MMC/SD core if the corresponding speed modes are supported by the OMAP silicon which is set in the mmc host caps field. Signed-off-by: Balaji T K balaj...@ti.com Signed-off-by: Viswanath Puttagunta vi...@ti.com Signed-off-by: Sourav Poddar sourav.pod...@ti.com [kis...@ti.com : cleanup the tuning sequence] Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 234 - 1 file changed, 232 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index c042b91..43485c3 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -18,6 +18,7 @@ #include linux/module.h #include linux/init.h #include linux/kernel.h +#include linux/slab.h #include linux/debugfs.h #include linux/dmaengine.h #include linux/seq_file.h @@ -49,6 +50,7 @@ /* OMAP HSMMC Host Controller Registers */ #define OMAP_HSMMC_SYSSTATUS 0x0014 #define OMAP_HSMMC_CON 0x002C +#define OMAP_HSMMC_DLL 0x0034 #define OMAP_HSMMC_SDMASA 0x0100 #define OMAP_HSMMC_BLK 0x0104 #define OMAP_HSMMC_ARG 0x0108 @@ -66,6 +68,7 @@ #define OMAP_HSMMC_ISE 0x0138 #define OMAP_HSMMC_AC120x013C #define OMAP_HSMMC_CAPA0x0140 +#define OMAP_HSMMC_CAPA2 0x0144 #define VS18 (1 26) #define VS30 (1 25) @@ -114,6 +117,7 @@ /* AC12 */ #define AC12_V1V8_SIGEN(1 19) +#define AC12_SCLK_SEL (1 23) #define AC12_UHSMC_MASK(7 16) #define AC12_UHSMC_SDR12 (0 16) #define AC12_UHSMC_SDR25 (1 16) @@ -122,6 +126,18 @@ #define AC12_UHSMC_DDR50 (4 16) #define AC12_UHSMC_RES (0x7 16) +/* DLL */ +#define DLL_SWT(1 20) +#define DLL_FORCE_SR_C_SHIFT 13 +#define DLL_FORCE_SR_C_MASK0x7f +#define DLL_FORCE_VALUE(1 12) +#define DLL_CALIB (1 1) + +#define MAX_PHASE_DELAY0x7c + +/* CAPA2 */ +#define CAPA2_TSDR50 (1 13) + /* Interrupt masks for IE and ISE register */ #define CC_EN (1 0) #define TC_EN (1 1) @@ -202,6 +218,7 @@ struct omap_hsmmc_host { int vqmmc_enabled; resource_size_t mapbase; spinlock_t irq_lock; /* Prevent races with irq handler */ + struct completion buf_ready; unsigned intdma_len; unsigned intdma_sg_idx; unsigned char bus_mode; @@ -229,6 +246,9 @@ struct omap_hsmmc_host { struct omap_hsmmc_next next_data; struct omap_hsmmc_platform_data*pdata; + u32 *tuning_data; + int tuning_size; + /* return MMC cover switch state, can be NULL if not supported. * * possible return values: @@ -245,8 +265,39 @@ struct omap_mmc_of_data { u8 controller_flags; }; +static const u8 ref_tuning_4bits[] = { + 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc, + 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef, + 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb, + 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef, + 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c, + 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee, + 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff, + 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde, +}; + +static const u8 ref_tuning_8bits[] = { + 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, + 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc, + 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff, + 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff, + 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd, + 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, + 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff, + 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, + 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, + 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, + 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, + 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, + 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, + 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, + 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, +}; + static void omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host); static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host, int iov); +static void omap_hsmmc_disable_tuning(struct omap_hsmmc_host *host); static int omap_hsmmc_card_detect(struct device *dev) { @@ -609,8 +660,12 @@
[PATCH v2 08/11] mmc: host: omap_hsmmc: Workaround for errata id i802
According to errata i802, DCRC error interrupts (MMCHS_STAT[21] DCRC=0x1) can occur during the tuning procedure. The DCRC interrupt, occurs when the last tuning block fails (the last ratio tested). The delay from CRC check until the interrupt is asserted is bigger than the delay until assertion of the tuning end flag. Assertion of tuning end flag is what masks the interrupts. Because of this race, an erroneous DCRC interrupt occurs. The suggested workaround is to disable DCRC interrupts during the tuning procedure which is implemented here. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com Signed-off-by: Sekhar Nori nsek...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 43485c3..9ab0f6e 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -665,8 +665,17 @@ static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host, is_tuning = (cmd-opcode == MMC_SEND_TUNING_BLOCK) || (cmd-opcode == MMC_SEND_TUNING_BLOCK_HS200); - if (!is_tuning host-use_dma) + if (is_tuning) { + /* +* OMAP5/DRA74X/DRA72x Errata i802: +* DCRC error interrupts (MMCHS_STAT[21] DCRC=0x1) can occur +* during the tuning procedure. So disable it during the +* tuning procedure. +*/ + irq_mask = ~DCRC_EN; + } else if (host-use_dma) { irq_mask = ~(BRR_EN | BWR_EN); + } /* Disable timeout for erases */ if (cmd-opcode == MMC_ERASE) -- 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 v2 11/11] mmc: host: omap_hsmmc: add software timer when timeout greater than hardware capablility
From: Mugunthan V N mugunthan...@ti.com DRA7 Errata No i834: When using high speed HS200 and SDR104 cards, the functional clock for MMC module will be 192MHz. At this frequency, the maximum obtainable timeout (DTO =0xE) in hardware is (1/192MHz)*2^27 = 700ms. Commands taking longer than 700ms will be affected by this small window frame and will be timing out frequently even without a genune timeout from the card. Workarround for this errata is use a software timer instead of hardware timer to provide the delay requested by the upper layer So adding a software timer as a work around for the errata. Instead of using software timeout only for larger delays requested when using HS200/SDR104 cards which results in hardware and software timer race conditions, so move all the timeout request to use software timer when HS200/SDR104 card is connected and use hardware timer when other type cards are connected. Also start the software timer after queueing to DMA to ensure we are more likely to expire within correct limits. To be ever more sure that we won't expire this soft timer too early, we're adding a 100ns slack to the data timeout requested by the upper layer. Signed-off-by: Mugunthan V N mugunthan...@ti.com Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 71 +++-- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index bc59822..ec80de9 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -168,6 +168,7 @@ #define ACNE (1 0) #define MMC_AUTOSUSPEND_DELAY 100 +#define MMC_SOFT_TIMER_SLACK 100 /* ns */ #define MMC_TIMEOUT_MS 20 /* 20 mSec */ #define MMC_TIMEOUT_US 2 /* 2 micro Sec */ #define OMAP_MMC_MIN_CLOCK 40 @@ -246,6 +247,10 @@ struct omap_hsmmc_host { struct omap_hsmmc_next next_data; struct omap_hsmmc_platform_data*pdata; + struct timer_list timer; + unsigned long data_timeout; + unsigned intneed_i834_errata:1; + u32 *tuning_data; int tuning_size; @@ -670,8 +675,8 @@ static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host, irq_mask = ~(BRR_EN | BWR_EN); } - /* Disable timeout for erases */ - if (cmd-opcode == MMC_ERASE) + /* Disable timeout for erases or when using software timeout */ + if (cmd-opcode == MMC_ERASE || host-need_i834_errata) irq_mask = ~DTO_EN; spin_lock_irqsave(host-irq_lock, flags); @@ -761,6 +766,22 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host) OMAP_HSMMC_WRITE(host-base, HCTL, regval); } + /* +* DRA7 Errata No i834: When using high speed HS200 and SDR104 +* cards, the functional clock for MMC module will be 192MHz. +* At this frequency, the maximum obtainable timeout (DTO =0xE) +* in hardware is (1/192MHz)*2^27 = 700ms. Commands taking longer +* than 700ms will be affected by this small window frame and +* will be timing out frequently even without a genune timeout +* from the card. Workarround for this errata is use a software +* timer instead of hardware timer to provide the delay requested +* by the upper layer +*/ + if (ios-clock == 19200) + host-need_i834_errata = true; + else + host-need_i834_errata = false; + omap_hsmmc_start_clock(host); } @@ -1307,6 +1328,16 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id) int status; status = OMAP_HSMMC_READ(host-base, STAT); + + /* +* During a successful bulk data transfer command-completion +* interrupt and transfer-completion interrupt will be generated, +* but software-timeout timer should be deleted only on non-CC +* interrupts (transfer complete or error) +*/ + if (host-need_i834_errata (status (~CC_EN))) + del_timer(host-timer); + while (status (INT_EN_MASK | CIRQ_EN)) { if (host-req_in_progress) omap_hsmmc_do_irq(host, status); @@ -1321,6 +1352,13 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id) return IRQ_HANDLED; } +static void omap_hsmmc_soft_timeout(unsigned long data) +{ + struct omap_hsmmc_host *host = (struct omap_hsmmc_host *)data; + + hsmmc_command_incomplete(host, -ETIMEDOUT, 0); +} + static void set_sd_bus_power(struct omap_hsmmc_host *host) { unsigned long i; @@ -1522,6 +1560,22 @@ static void set_data_timeout(struct omap_hsmmc_host *host, if (clkd == 0) clkd = 1; + if (host-need_i834_errata) { + unsigned long delta; + +
[PATCH v2 09/11] mmc: host: omap_hsmmc: Allow io voltage switch even for fixed vdd
Now that vmmc regulator is made optional, do not bail out if vmmc regulator is not found. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c |7 --- 1 file changed, 7 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 9ab0f6e..f553b5f 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -440,13 +440,6 @@ static int omap_hsmmc_set_power(struct device *dev, int power_on, int iov) struct mmc_host *mmc = host-mmc; int ret = 0; - /* -* If we don't see a Vcc regulator, assume it's a fixed -* voltage always-on regulator. -*/ - if (!mmc-supply.vmmc) - return 0; - if (mmc_pdata(host)-before_set_reg) mmc_pdata(host)-before_set_reg(dev, power_on, iov); -- 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 v2 10/11] mmc: host: omap_hsmmc: remove incorrect voltage switch sequence
ios-vdd is set only in mmc_power_up and mmc_power_off and not in mmc_select_voltage as mentioned in the code comment. This seems to be legacy code that has been carried for a long time without being tested. This will be replaced with a proper voltage switch sequence and populated in start_signal_voltage_switch ops to be used by mmc core for switching voltages. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 81 - 1 file changed, 81 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index f553b5f..bc59822 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1334,69 +1334,6 @@ static void set_sd_bus_power(struct omap_hsmmc_host *host) } } -/* - * Switch MMC interface voltage ... only relevant for MMC1. - * - * MMC2 and MMC3 use fixed 1.8V levels, and maybe a transceiver. - * The MMC2 transceiver controls are used instead of DAT4..DAT7. - * Some chips, like eMMC ones, use internal transceivers. - */ -static int omap_hsmmc_switch_opcond(struct omap_hsmmc_host *host, int vdd) -{ - u32 reg_val = 0; - int ret; - - /* Disable the clocks */ - pm_runtime_put_sync(host-dev); - if (host-dbclk) - clk_disable_unprepare(host-dbclk); - - /* Turn the power off */ - ret = mmc_pdata(host)-set_power(host-dev, 0, 0); - - /* Turn the power ON with given VDD 1.8 or 3.0v */ - if (!ret) - ret = mmc_pdata(host)-set_power(host-dev, 1, vdd); - pm_runtime_get_sync(host-dev); - if (host-dbclk) - clk_prepare_enable(host-dbclk); - - if (ret != 0) - goto err; - - OMAP_HSMMC_WRITE(host-base, HCTL, - OMAP_HSMMC_READ(host-base, HCTL) SDVSCLR); - reg_val = OMAP_HSMMC_READ(host-base, HCTL); - - /* -* If a MMC dual voltage card is detected, the set_ios fn calls -* this fn with VDD bit set for 1.8V. Upon card removal from the -* slot, omap_hsmmc_set_ios sets the VDD back to 3V on MMC_POWER_OFF. -* -* Cope with a bit of slop in the range ... per data sheets: -* - 1.8V for vdds_mmc1/vdds_mmc1a can be up to 2.45V max, -*but recommended values are 1.71V to 1.89V -* - 3.0V for vdds_mmc1/vdds_mmc1a can be up to 3.5V max, -*but recommended values are 2.7V to 3.3V -* -* Board setup code shouldn't permit anything very out-of-range. -* TWL4030-family VMMC1 and VSIM regulators are fine (avoiding the -* middle range) but VSIM can't power DAT4..DAT7 at more than 3V. -*/ - if ((1 vdd) = MMC_VDD_23_24) - reg_val |= SDVS18; - else - reg_val |= SDVS30; - - OMAP_HSMMC_WRITE(host-base, HCTL, reg_val); - set_sd_bus_power(host); - - return 0; -err: - dev_err(mmc_dev(host-mmc), Unable to switch operating voltage\n); - return ret; -} - /* Protect the card while the cover is open */ static void omap_hsmmc_protect_card(struct omap_hsmmc_host *host) { @@ -1808,24 +1745,6 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) omap_hsmmc_set_bus_width(host); - if (host-pdata-controller_flags OMAP_HSMMC_SUPPORTS_DUAL_VOLT) { - /* Only MMC1 can interface at 3V without some flavor -* of external transceiver; but they all handle 1.8V. -*/ - if ((OMAP_HSMMC_READ(host-base, HCTL) SDVSDET) - (ios-vdd == DUAL_VOLT_OCR_BIT)) { - /* -* The mmc_select_voltage fn of the core does -* not seem to set the power_mode to -* MMC_POWER_UP upon recalculating the voltage. -* vdd 1.8v. -*/ - if (omap_hsmmc_switch_opcond(host, ios-vdd) != 0) - dev_dbg(mmc_dev(host-mmc), - Switch operation failed\n); - } - } - omap_hsmmc_set_clock(host); if (ios-timing != host-timing) { -- 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 v2 06/11] mmc: host: omap_hsmmc: set timing in the UHSMS field
Add a separate function to set the UHSMS field to one of SDR104, SDR50, DDR50, SDR25 or SDR12 depending on the inserted SD card. This is required for tuning to succeed in the case of SDR104/HS200 or SDR50. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 49 + 1 file changed, 49 insertions(+) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 60c1ac2..c042b91 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -114,6 +114,13 @@ /* AC12 */ #define AC12_V1V8_SIGEN(1 19) +#define AC12_UHSMC_MASK(7 16) +#define AC12_UHSMC_SDR12 (0 16) +#define AC12_UHSMC_SDR25 (1 16) +#define AC12_UHSMC_SDR50 (2 16) +#define AC12_UHSMC_SDR104 (3 16) +#define AC12_UHSMC_DDR50 (4 16) +#define AC12_UHSMC_RES (0x7 16) /* Interrupt masks for IE and ISE register */ #define CC_EN (1 0) @@ -199,6 +206,7 @@ struct omap_hsmmc_host { unsigned intdma_sg_idx; unsigned char bus_mode; unsigned char power_mode; + unsigned char timing; int suspended; u32 con; u32 hctl; @@ -1667,6 +1675,41 @@ static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req) omap_hsmmc_start_command(host, req-cmd, req-data); } +static void omap_hsmmc_set_timing(struct omap_hsmmc_host *host) +{ + u32 val; + struct mmc_ios *ios = host-mmc-ios; + + omap_hsmmc_stop_clock(host); + + val = OMAP_HSMMC_READ(host-base, AC12); + val = ~AC12_UHSMC_MASK; + switch (ios-timing) { + case MMC_TIMING_UHS_SDR104: + case MMC_TIMING_MMC_HS200: + val |= AC12_UHSMC_SDR104; + break; + case MMC_TIMING_UHS_DDR50: + val |= AC12_UHSMC_DDR50; + break; + case MMC_TIMING_UHS_SDR50: + val |= AC12_UHSMC_SDR50; + break; + case MMC_TIMING_UHS_SDR25: + val |= AC12_UHSMC_SDR25; + break; + case MMC_TIMING_UHS_SDR12: + val |= AC12_UHSMC_SDR12; + break; + default: + val |= AC12_UHSMC_RES; + break; + } + OMAP_HSMMC_WRITE(host-base, AC12, val); + + omap_hsmmc_start_clock(host); +} + /* Routine to configure clock values. Exposed API to core */ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { @@ -1715,6 +1758,11 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) omap_hsmmc_set_clock(host); + if (ios-timing != host-timing) { + omap_hsmmc_set_timing(host); + host-timing = ios-timing; + } + if (do_send_init_stream) send_init_stream(host); @@ -2204,6 +2252,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) host-mapbase = res-start + pdata-reg_offset; host-base = base + pdata-reg_offset; host-power_mode = MMC_POWER_OFF; + host-timing= 0; host-next_data.cookie = 1; host-vqmmc_enabled = 0; -- 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 v2 05/11] mmc: host: omap_hsmmc: set clk rate to the max frequency
Set the clock rate of the functional clock to the max frequency that is passed to the driver either using pdata or dt. Also remove unnecessary setting of host-fclk to NULL. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 7dac486..60c1ac2 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -2149,6 +2149,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) struct omap_hsmmc_host *host = NULL; struct resource *res; int ret, irq; + unsigned int freq; const struct of_device_id *match; dma_cap_mask_t mask; unsigned tx_req, rx_req; @@ -2229,10 +2230,20 @@ static int omap_hsmmc_probe(struct platform_device *pdev) host-fclk = devm_clk_get(pdev-dev, fck); if (IS_ERR(host-fclk)) { ret = PTR_ERR(host-fclk); - host-fclk = NULL; goto err1; } + freq = clk_get_rate(host-fclk); + if (freq mmc-f_max) { + mmc-f_max = freq; + } else { + ret = clk_set_rate(host-fclk, mmc-f_max); + if (ret) { + dev_err(pdev-dev, failed to set clock to %d\n, mmc-f_max); + goto err1; + } + } + if (host-pdata-controller_flags OMAP_HSMMC_BROKEN_MULTIBLOCK_READ) { dev_info(pdev-dev, multiblock reads disabled due to 35xx erratum 2.1.1.128; MMC read performance may suffer\n); omap_hsmmc_ops.multi_io_quirk = omap_hsmmc_multi_io_quirk; -- 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 v2 00/11] omap_hsmmc: voltage switching and tuning
Patch series implements voltage switching and tuning for omap_hsmmc driver. Changes from v1: *) rebased on top of [1] *) Patch breaking omap3 beagle xm is fixed. (set clk rate patch was breaking beagle xm) [1] - https://lkml.org/lkml/2015/8/21/125 Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM, Beaglebone black, OMAP5 uEVM and OMAP4 PANDA, OMAP3 beagle xm. Also performed PM suspend/resume test with OMAP3 beagle xm. Balaji T K (2): mmc: host: omap_hsmmc: add voltage switch support for UHS SD card mmc: host: omap_hsmmc: add tuning support Kishon Vijay Abraham I (8): mmc: host: omap_hsmmc: Support vmmc_aux to switch to 1.8v mmc: host: omap_hsmmc: separate setting voltage capabilities from bus power mmc: host: omap_hsmmc: program HCTL based on signal_voltage set by mmc core mmc: host: omap_hsmmc: set clk rate to the max frequency mmc: host: omap_hsmmc: set timing in the UHSMS field mmc: host: omap_hsmmc: Workaround for errata id i802 mmc: host: omap_hsmmc: Allow io voltage switch even for fixed vdd mmc: host: omap_hsmmc: remove incorrect voltage switch sequence Mugunthan V N (1): mmc: host: omap_hsmmc: add software timer when timeout greater than hardware capablility drivers/mmc/host/omap_hsmmc.c | 677 + 1 file changed, 554 insertions(+), 123 deletions(-) -- 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] ARM: dts: DRA7: fix a typo in ethernet
Register address in name of the node is wrong Signed-off-by: Vishal Mahaveer vish...@ti.com Acked-by: Mugunthan V N mugunthan...@ti.com --- arch/arm/boot/dts/dra7.dtsi |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index 1e29ccf..9a20d46 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -1398,7 +1398,7 @@ ti,irqs-safe-map = 0; }; - mac: ethernet@4a10 { + mac: ethernet@48484000 { compatible = ti,cpsw; ti,hwmods = gmac; clocks = dpll_gmac_ck, gmac_gmii_ref_clk_div; -- 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] of: device: fix NULL pointer dereference on driver removal
If we don't insert resources into the resource tree, calls to of_platform_depopulate() will end up in NULL pointer dereferences because the resource parent will be set to NULL even though we still have more resources to go through. Without this patch, the result is as follows: [ 28.238158] Unable to handle kernel NULL pointer dereference at virtual address 0008 [ 28.246646] pgd = ed3d8000 [ 28.249480] [0008] *pgd= [ 28.253247] Internal error: Oops: 5 [#1] SMP ARM [ 28.258072] Modules linked in: input_leds hid_generic usbkbd usbhid xhci_plat_hcd xhci_hcd usbcore joydev dwc3 udc_core usb_common m25p80 evdev spi_nor omapfb cfbfillrect cfbimg blt cpufreq_dt cfbcopyarea thermal_sys snd_soc_simple_card leds_gpio matrix_keypad pwm_bl hwmon led_class matrix_keymap panel_dpi snd_soc_tlv320aic3x snd_soc_davinci_mcasp snd_soc_edma snd_soc_omap snd_soc_core omapdss snd_compress snd_pcm_dmaengine snd_pcm dwc3_omap(-) extcon snd_timer pwm_tiecap snd lis3lv02d_i2c lis3lv02d soundcore input_polldev rtc_omap spi_ti_qspi tps65218_pwrbutton omap_wdt phy_omap_usb2 autofs4 [ 28.313186] CPU: 0 PID: 289 Comm: modprobe Not tainted 4.2.0-rc7-next-20150824-2-g5681a109a938-dirty #1093 [ 28.323643] Hardware name: Generic AM43 (Flattened Device Tree) [ 28.329836] task: ed39d180 ti: ed076000 task.ti: ed076000 [ 28.335496] PC is at __release_resource+0x30/0x13c [ 28.340501] LR is at __release_resource+0x24/0x13c [ 28.345501] pc : [c00439e0]lr : [c00439d4]psr: 600d0013 [ 28.345501] sp : ed077e98 ip : 0007 fp : befb3e14 [ 28.357487] r10: r9 : ed076000 r8 : c000f724 [ 28.362941] r7 : r6 : ee6f9800 r5 : ed268d40 r4 : c094679c [ 28.369755] r3 : r2 : 00f4 r1 : c0648b34 r0 : 0045 [ 28.376560] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user [ 28.384008] Control: 10c5387d Table: ad3d8059 DAC: 0015 [ 28.390005] Process modprobe (pid: 289, stack limit = 0xed076218) [ 28.396375] Stack: (0xed077e98 to 0xed078000) [ 28.400924] 7e80: ed268d40 [ 28.409455] 7ea0: befb3e14 c0640838 0001 c094679c ed268d40 ee6f9800 0081 c0043b1c [ 28.417996] 7ec0: 001c 0001 ee6f9800 c03e2674 ee6f9800 c04d3f20 c03e26ac [ 28.426537] 7ee0: ee6f9810 c04d3fac c03dcf10 ee1592c0 ed268cf0 ee170010 ee170010 [ 28.435065] 7f00: ee170044 c04d3f08 ed268ed0 bf093208 ee170010 bf093c94 ee170044 c03e2754 [ 28.443607] 7f20: ee170010 bf093c94 ee170044 c03e095c ee170010 bf093c94 ee170044 c03e116c [ 28.452150] 7f40: bf093c94 7f6232fc 0800 c03e04e4 bf093d00 c00c8a80 33637764 [ 28.460703] 7f60: 616d6f5f b6f70070 ed39d180 ed076000 befb3e14 c005be74 [ 28.469241] 7f80: ed076000 7f6232c0 7f6232c0 0001 f67c 7f6232c0 7f6232c0 [ 28.477783] 7fa0: 0001 c000f540 7f6232c0 7f6232c0 7f6232fc 0800 66d19c00 [ 28.486341] 7fc0: 7f6232c0 7f6232c0 0001 0081 0001 7f6232c0 befb3e14 [ 28.494903] 7fe0: b6f1c2e1 befb2a3c 7f60638f b6f1c2e6 800d0030 7f6232fc [ 28.503476] [c00439e0] (__release_resource) from [c0043b1c] (release_resource+0x30/0x54) [ 28.512299] [c0043b1c] (release_resource) from [c03e2674] (platform_device_del+0x70/0x9c) [ 28.521218] [c03e2674] (platform_device_del) from [c03e26ac] (platform_device_unregister+0xc/0x20) [ 28.530962] [c03e26ac] (platform_device_unregister) from [c04d3fac] (of_platform_device_destroy+0x8c/0x98) [ 28.541425] [c04d3fac] (of_platform_device_destroy) from [c03dcf10] (device_for_each_child+0x50/0x7c) [ 28.551430] [c03dcf10] (device_for_each_child) from [c04d3f08] (of_platform_depopulate+0x2c/0x44) [ 28.561101] [c04d3f08] (of_platform_depopulate) from [bf093208] (dwc3_omap_remove+0x3c/0x5c [dwc3_omap]) [ 28.571390] [bf093208] (dwc3_omap_remove [dwc3_omap]) from [c03e2754] (platform_drv_remove+0x18/0x30) [ 28.581387] [c03e2754] (platform_drv_remove) from [c03e095c] (__device_release_driver+0x88/0x114) [ 28.591023] [c03e095c] (__device_release_driver) from [c03e116c] (driver_detach+0xb4/0xb8) [ 28.600014] [c03e116c] (driver_detach) from [c03e04e4] (bus_remove_driver+0x4c/0xa0) [ 28.608485] [c03e04e4] (bus_remove_driver) from [c00c8a80] (SyS_delete_module+0x11c/0x1e4) [ 28.617518] [c00c8a80] (SyS_delete_module) from [c000f540] (ret_fast_syscall+0x0/0x54) [ 28.626172] Code: eb0354bf e5957010 e3a020f4 e59f10f0 (e5973008) [ 28.632722] ---[ end trace d2a21fc5d73a2dfd ]--- Cc: sta...@vger.kernel.org Signed-off-by: Felipe Balbi ba...@ti.com --- very easy to trigger with 'modprobe -r dwc3-omap' on any of TI's platform sporting dwc3 drivers/of/device.c | 23 +++ 1 file changed, 23 insertions(+) diff --git a/drivers/of/device.c b/drivers/of/device.c index 8b91ea241b10..c03600c08207 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -53,6 +53,8 @@ EXPORT_SYMBOL(of_dev_put); int
Re: [PATCH 0/7] gpio: omap: fixes and improvements
On 08/21/2015 11:13 AM, Tony Lindgren wrote: * Tony Lindgren t...@atomide.com [150818 23:42]: Hi, * Grygorii Strashko grygorii.stras...@ti.com [150818 04:14]: Hi, This patch series contains set of trivial fixes and improvements, and also patches which fixes wrong APIs usage in atomic context as for -RT as for non-RT kernel. The final goal of this series is to make TI OMAP GPIO driver compatible with -RT kernel as much as possible. Patch 1-4: trivial fixes and improvements Patch 5: fixes wrong CLK clk_prepare/unprepare APIs usage in atomic contexet Patch 6(rfc): required to be compatible with -RT kernel, because PM runtime can't be used in atimic context on -RT. Patch 7(rfc): This patch converts TI OMAP GPIO driver to use generic irq handler instead of chained IRQ handler. This way OMAP GPIO driver will be compatible with RT kernel where it will be forced thread IRQ handler while in non-RT kernel it still will be executed in HW IRQ context. Based on quick testing this series breaks at least core off idle for omap3. You probably should add a beagle xm to your test devices so you can properly test PM features. Sorry I take that back, after trying to figure out which patch breaks PM I noticed I had some other patches applied also. Looks like PM works just fine with this series for me, so please feel free to add: Uh... :) Thanks Tony a lot and sorry for delayed reply (was ooo). You've restored my heartbeat :) Tested-by: Tony Lindgren t...@atomide.com Note that I have not been able to test this with gpio button as my boards are in a rack. You may want to do some gpio button tests to make sure things wake up properly from off idle if you can get hold of a beagle xm. I posted some instructions how to test earlier today for Kishon in the [PATCH v2 00/16] omap_hsmmc: regulator usage cleanup and fixes thread. I've tested it actually using GPIO buttons and UART console wake-up (Results - https://lkml.org/lkml/2015/8/14/194 :) And I'd try to retest it on beagle xm also, but not sure if i'd be able to test button's wake-up - have shared access only now to beagle xm which is rack also. -- regards, -grygorii -- 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 00/16] omap_hsmmc: regulator usage cleanup and fixes
On 3 August 2015 at 14:26, Kishon Vijay Abraham I kis...@ti.com wrote: Changes from v1: *) return on -EPROBE_DEFER and other fatal errors. (Don't return only if the return value is -ENODEV) *) Remove the beagle x15 dts patch. It can be part of a different series. *) Avoid using regulator_is_enabled for vqmmc since if the regulator is shared and the other users are not using regulator_is_enabled then there can be unbalanced regulator_enable/regulator_disable This patch series does the following *) Uses devm_regulator_get_optional() for vmmc and then removes the CONFIG_REGULATOR check altogether. *) return on -EPROBE_DEFER and any other fatal errors *) enable/disable vmmc_aux regulator based on prior state I've pushed this patch series to git://git.ti.com/linux-phy/linux-phy.git mmc_regulator_cleanup_fixes_v2 Please note the branch also has the pbias fixes [1] [2]. [1] - https://lkml.org/lkml/2015/7/27/358 [2] - https://lkml.org/lkml/2015/7/27/391 This series is in preparation for implementing the voltage switch sequence so that UHS cards can be supported. Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM, Beaglebone black, OMAP5 uEVM and OMAP4 PANDA. Kishon Vijay Abraham I (15): mmc: host: omap_hsmmc: use devm_regulator_get_optional() for vmmc mmc: host: omap_hsmmc: return on fatal errors from omap_hsmmc_reg_get mmc: host: omap_hsmmc: cleanup omap_hsmmc_reg_get() mmc: host: omap_hsmmc: use the ocrmask provided by the vmmc regulator mmc: host: omap_hsmmc: use mmc_host's vmmc and vqmmc mmc: host: omap_hsmmc: remove unnecessary pbias set_voltage mmc: host: omap_hsmmc: return error if any of the regulator APIs fail mmc: host: omap_hsmmc: add separate functions for enable/disable supply mmc: host: omap_hsmmc: add separate function to set pbias mmc: host: omap_hsmmc: avoid pbias regulator enable on power off mmc: host: omap_hsmmc: don't use -set_power to set initial regulator state mmc: host: omap_hsmmc: enable/disable vmmc_aux regulator based on previous state mmc: host: omap_hsmmc: use regulator_is_enabled to find pbias status mmc: host: omap_hsmmc: use ios-vdd for setting vmmc voltage mmc: host: omap_hsmmc: remove CONFIG_REGULATOR check Roger Quadros (1): mmc: host: omap_hsmmc: use mmc_of_parse_voltage to get ocr_avail .../devicetree/bindings/mmc/ti-omap-hsmmc.txt |2 + drivers/mmc/host/omap_hsmmc.c | 340 +--- 2 files changed, 224 insertions(+), 118 deletions(-) -- 1.7.9.5 I tried to apply this on top of my next branch, but it didn't work. Could you please rebase and send a v3!? While you do that, please add Tony's tested-by tag as well. Kind regards Uffe -- 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
CONFIG_DEBUG_SHIRQ and PM
Hi Ingo, I'm facing an issue with CONFIG_DEBUG_SHIRQ and pm_runtime when using devm_request_*irq(). If we using devm_request_*irq(), that irq will be freed after device drivers' -remove() gets called. If on -remove(), we're calling pm_runtime_put_sync(); pm_runtime_disable(), device's clocks might get gated and, because we do an extra call to the device's IRQ handler when CONFIG_DEBUG_SHIRQ=y, we might trigger an abort exception if, inside the IRQ handler, we try to read a register which is clocked by the device's clock. This is, of course, really old code which has been in tree for many, many years. I guess nobody has been running their tests in the setup mentioned above (CONFIG_DEBUG_SHIRQ=y, pm_runtime_put_sync() on -remove(), a register read on IRQ handler, and a shared IRQ handler), so that's why we never caught this before. Disabling CONFIG_DEBUG_SHIRQ, of course, makes the problem go away, but if driver *must* be ready to receive, and handle, an IRQ even during module removal, I wonder what the IRQ handler should do. We can't, in most cases, call pm_runtime_put_sync() from IRQ handler. I'm guessing the only way would be to move pm_runtime calls into the bus driver (in this case, the platform_bus) and make sure it only gets called after device managed resources are freed ? Any hints would be greatly appreciated. cheers -- balbi signature.asc Description: Digital signature