Re: [PATCH V2 1/3] scsi: ufs: Allow vendor specific initialization
Looks good to me. Reviewed-by: Subhash Jadavani subha...@codeaurora.org On 8/27/2013 9:48 AM, Sujit Reddy Thumma wrote: Some vendor specific controller versions might need to configure vendor specific - registers, clocks, voltage regulators etc. to initialize the host controller UTP layer and Uni-Pro stack. Provide some common initialization operations that can be used to configure vendor specifics. The methods can be extended in future, for example, for power mode transitions. The operations are vendor/board specific and hence determined with the help of compatible property in device tree. Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org --- drivers/scsi/ufs/ufshcd-pci.c| 8 +- drivers/scsi/ufs/ufshcd-pltfrm.c | 24 +- drivers/scsi/ufs/ufshcd.c| 157 +++ drivers/scsi/ufs/ufshcd.h| 34 - 4 files changed, 187 insertions(+), 36 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c index a823cf4..6b0d299 100644 --- a/drivers/scsi/ufs/ufshcd-pci.c +++ b/drivers/scsi/ufs/ufshcd-pci.c @@ -191,7 +191,13 @@ ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) return err; } - err = ufshcd_init(pdev-dev, hba, mmio_base, pdev-irq); + err = ufshcd_alloc_host(pdev-dev, hba); + if (err) { + dev_err(pdev-dev, Allocation failed\n); + return err; + } + + err = ufshcd_init(hba, mmio_base, pdev-irq); if (err) { dev_err(pdev-dev, Initialization failed\n); return err; diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 5e46232..9c94052 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -35,9 +35,23 @@ #include linux/platform_device.h #include linux/pm_runtime.h +#include linux/of.h #include ufshcd.h +static const struct of_device_id ufs_of_match[]; +static struct ufs_hba_variant_ops *get_variant_ops(struct device *dev) +{ + if (dev-of_node) { + const struct of_device_id *match; + match = of_match_node(ufs_of_match, dev-of_node); + if (match) + return (struct ufs_hba_variant_ops *)match-data; + } + + return NULL; +} + #ifdef CONFIG_PM /** * ufshcd_pltfrm_suspend - suspend power management function @@ -150,10 +164,18 @@ static int ufshcd_pltfrm_probe(struct platform_device *pdev) goto out; } + err = ufshcd_alloc_host(dev, hba); + if (err) { + dev_err(pdev-dev, Allocation failed\n); + goto out; + } + + hba-vops = get_variant_ops(pdev-dev); + pm_runtime_set_active(pdev-dev); pm_runtime_enable(pdev-dev); - err = ufshcd_init(dev, hba, mmio_base, irq); + err = ufshcd_init(hba, mmio_base, irq); if (err) { dev_err(dev, Intialization failed\n); goto out_disable_rpm; diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index a0f5ac2..743696a 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -174,13 +174,14 @@ static inline u32 ufshcd_get_ufs_version(struct ufs_hba *hba) /** * ufshcd_is_device_present - Check if any device connected to * the host controller - * @reg_hcs - host controller status register value + * @hba: pointer to adapter instance * * Returns 1 if device present, 0 if no device detected */ -static inline int ufshcd_is_device_present(u32 reg_hcs) +static inline int ufshcd_is_device_present(struct ufs_hba *hba) { - return (DEVICE_PRESENT reg_hcs) ? 1 : 0; + return (ufshcd_readl(hba, REG_CONTROLLER_STATUS) + DEVICE_PRESENT) ? 1 : 0; } /** @@ -1483,11 +1484,10 @@ out: * @hba: per adapter instance * * To bring UFS host controller to operational state, - * 1. Check if device is present - * 2. Enable required interrupts - * 3. Configure interrupt aggregation - * 4. Program UTRL and UTMRL base addres - * 5. Configure run-stop-registers + * 1. Enable required interrupts + * 2. Configure interrupt aggregation + * 3. Program UTRL and UTMRL base addres + * 4. Configure run-stop-registers * * Returns 0 on success, non-zero value on failure */ @@ -1496,14 +1496,6 @@ static int ufshcd_make_hba_operational(struct ufs_hba *hba) int err = 0; u32 reg; - /* check if device present */ - reg = ufshcd_readl(hba, REG_CONTROLLER_STATUS); - if (!ufshcd_is_device_present(reg)) { - dev_err(hba-dev, cc: Device not present\n); - err = -ENXIO; - goto out; - } - /* Enable required interrupts */ ufshcd_enable_intr(hba, UFSHCD_ENABLE_INTRS); @@ -1524,6 +1516,7 @@ static int ufshcd_make_hba_operational(struct ufs_hba
Re: [PATCH V2 3/3] scsi: ufs: Add clock initialization support
Looks good to me. Reviewed-by: Subhash Jadavani subha...@codeaurora.org On 8/27/2013 9:48 AM, Sujit Reddy Thumma wrote: Add generic clock initialization support for UFSHCD platform driver. The clock info is read from device tree using standard clock bindings. A generic max-clock-frequency-hz property is defined to save information on maximum operating clock frequency the h/w supports. Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org --- .../devicetree/bindings/ufs/ufshcd-pltfrm.txt | 15 +++- drivers/scsi/ufs/ufshcd-pltfrm.c | 71 + drivers/scsi/ufs/ufshcd.c | 89 +- drivers/scsi/ufs/ufshcd.h | 18 + 4 files changed, 190 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt index 65e3117..b0f791a 100644 --- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt +++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt @@ -21,8 +21,17 @@ Optional properties: - vccq-max-microamp : specifies max. load that can be drawn from vccq supply - vccq2-max-microamp: specifies max. load that can be drawn from vccq2 supply +- clocks: List of phandle and clock specifier pairs +- clock-names : List of clock input name strings sorted in the same + order as the clocks property. +- max-clock-frequency-hz : List of maximum operating frequency stored in the same + order as the clocks property. If this property is not + defined or a value in the array is 0 then it is assumed + that the frequency is set by the parent clock or a + fixed rate clock source. + Note: If above properties are not defined it can be assumed that the supply -regulators are always on. +regulators or clocks are always on. Example: ufshc@0xfc598000 { @@ -37,4 +46,8 @@ Example: vcc-max-microamp = 50; vccq-max-microamp = 20; vccq2-max-microamp = 20; + + clocks = core 0, ref 0, iface 0; + clock-names = core_clk, ref_clk, iface_clk; + max-clock-frequency-hz = 1 1920 0; }; diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index cbdf5f3..15c8086 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -52,6 +52,71 @@ static struct ufs_hba_variant_ops *get_variant_ops(struct device *dev) return NULL; } +static int ufshcd_parse_clock_info(struct ufs_hba *hba) +{ + int ret = 0; + int cnt; + int i; + struct device *dev = hba-dev; + struct device_node *np = dev-of_node; + char *name; + u32 *clkfreq = NULL; + struct ufs_clk_info *clki; + + if (!np) + goto out; + + INIT_LIST_HEAD(hba-clk_list_head); + + cnt = of_property_count_strings(np, clock-names); + if (!cnt || (cnt == -EINVAL)) { + dev_info(dev, %s: Unable to find clocks, assuming enabled\n, + __func__); + } else if (cnt 0) { + dev_err(dev, %s: count clock strings failed, err %d\n, + __func__, cnt); + ret = cnt; + } + + if (cnt = 0) + goto out; + + clkfreq = kzalloc(cnt * sizeof(*clkfreq), GFP_KERNEL); + if (!clkfreq) { + ret = -ENOMEM; + dev_err(dev, %s: memory alloc failed\n, __func__); + goto out; + } + + ret = of_property_read_u32_array(np, + max-clock-frequency-hz, clkfreq, cnt); + if (ret (ret != -EINVAL)) { + dev_err(dev, %s: invalid max-clock-frequency-hz property, %d\n, + __func__, ret); + goto out; + } + + for (i = 0; i cnt; i++) { + ret = of_property_read_string_index(np, + clock-names, i, (const char **)name); + if (ret) + goto out; + + clki = devm_kzalloc(dev, sizeof(*clki), GFP_KERNEL); + if (!clki) { + ret = -ENOMEM; + goto out; + } + + clki-max_freq = clkfreq[i]; + clki-name = kstrdup(name, GFP_KERNEL); + list_add_tail(clki-list, hba-clk_list_head); + } +out: + kfree(clkfreq); + return ret; +} + #define MAX_PROP_SIZE 32 static int ufshcd_populate_vreg(struct device *dev, const char *name, struct ufs_vreg **out_vreg) @@ -265,6 +330,12 @@ static int ufshcd_pltfrm_probe(struct platform_device *pdev) hba-vops = get_variant_ops(pdev-dev); + err =
Re: [PATCH] scsi: ufs: read door bell register after clearing interrupt aggregation
Looks good to me. Reviewed-by: Subhash Jadavani subha...@codeaurora.org On 8/25/2013 4:06 PM, Dolev Raviv wrote: In interrupt context, after reading and comparing the UTRLDBR to hba-outstanding_request and before resetting the interrupt aggregation, there might be completion of another transfer request (TR). Such TRs might get stuck, pending, until the next interrupt is generated. The fix reads the UTRLDBR after resetting the interrupt aggregation and handles completed TRs. Signed-off-by: Dolev Raviv dra...@codeaurora.org diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 4dca9b4..30c84d8 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1915,6 +1915,13 @@ static void ufshcd_uic_cmd_compl(struct ufs_hba *hba) /** * ufshcd_transfer_req_compl - handle SCSI and query command completion * @hba: per adapter instance + * + * Resetting interrupt aggregation counters first and reading the DOOR_BELL + * afterward , allows us to handle all the completed requests. + * In order to prevent other interrupts starvation the DB is read once + * after reset. The down side of this solution is the possibility of false + * interrupt if device completes another request after resetting aggregation + * and before reading the DB. */ static void ufshcd_transfer_req_compl(struct ufs_hba *hba) { @@ -1924,47 +1931,36 @@ static void ufshcd_transfer_req_compl(struct ufs_hba *hba) u32 tr_doorbell; int result; int index; - bool int_aggr_reset = false; + + /* Reset interrupt aggregation counters */ + ufshcd_config_int_aggr(hba, INT_AGGR_RESET); tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); completed_reqs = tr_doorbell ^ hba-outstanding_reqs; - for (index = 0; index hba-nutrs; index++) { - if (test_bit(index, completed_reqs)) { - lrbp = hba-lrb[index]; - cmd = lrbp-cmd; - /* -* Don't skip resetting interrupt aggregation counters -* if a regular command is present. -*/ - int_aggr_reset |= !lrbp-intr_cmd; - - if (cmd) { - result = ufshcd_transfer_rsp_status(hba, lrbp); - scsi_dma_unmap(cmd); - cmd-result = result; - /* Mark completed command as NULL in LRB */ - lrbp-cmd = NULL; - clear_bit_unlock(index, hba-lrb_in_use); - /* Do not touch lrbp after scsi done */ - cmd-scsi_done(cmd); - } else if (lrbp-command_type == - UTP_CMD_TYPE_DEV_MANAGE) { - if (hba-dev_cmd.complete) - complete(hba-dev_cmd.complete); - } - } /* end of if */ - } /* end of for */ + for_each_set_bit(index, completed_reqs, hba-nutrs) { + lrbp = hba-lrb[index]; + cmd = lrbp-cmd; + if (cmd) { + result = ufshcd_transfer_rsp_status(hba, lrbp); + scsi_dma_unmap(cmd); + cmd-result = result; + /* Mark completed command as NULL in LRB */ + lrbp-cmd = NULL; + clear_bit_unlock(index, hba-lrb_in_use); + /* Do not touch lrbp after scsi done */ + cmd-scsi_done(cmd); + } else if (lrbp-command_type == UTP_CMD_TYPE_DEV_MANAGE) { + if (hba-dev_cmd.complete) + complete(hba-dev_cmd.complete); + } + } /* end of for_each_set_bit */ /* clear corresponding bits of completed commands */ hba-outstanding_reqs ^= completed_reqs; /* we might have free'd some tags above */ wake_up(hba-dev_cmd.tag_wq); - - /* Reset interrupt aggregation counters */ - if (int_aggr_reset) - ufshcd_config_int_aggr(hba, INT_AGGR_RESET); } /** @@ -2569,6 +2565,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) int poll_cnt; u8 resp = 0xF; struct ufshcd_lrb *lrbp; + u32 reg; host = cmd-device-host; hba = shost_priv(host); @@ -2578,6 +2575,13 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) if (!(test_bit(tag, hba-outstanding_reqs))) goto out; + reg = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); + if (!(reg (1 tag))) { + dev_err(hba-dev, + %s: cmd was completed, but without a notifying intr, tag = %d, + __func__, tag); + } + lrbp = hba-lrb[tag]; for (poll_cnt = 100;
Re: [PATCH V2 2/3] scsi: ufs: Add regulator enable support
Looks good to me. Reviewed-by: Subhash Jadavani subha...@codeaurora.org On 8/27/2013 9:48 AM, Sujit Reddy Thumma wrote: UFS devices are powered by at most three external power supplies - - VCC - The flash memory core power supply, 2.7V to 3.6V or 1.70V to 1.95V - VCCQ - The controller and I/O power supply, 1.1V to 1.3V - VCCQ2 - Secondary controller and/or I/O power supply, 1.65V to 1.95V For some devices VCCQ or VCCQ2 are optional as they can be generated using internal LDO inside the UFS device. Add DT bindings for voltage regulators that can be controlled from host driver. Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org --- .../devicetree/bindings/ufs/ufshcd-pltfrm.txt | 24 +++ drivers/scsi/ufs/ufs.h | 25 +++ drivers/scsi/ufs/ufshcd-pltfrm.c | 100 +++ drivers/scsi/ufs/ufshcd.c | 193 - drivers/scsi/ufs/ufshcd.h | 3 + 5 files changed, 342 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt index 20468b2..65e3117 100644 --- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt +++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt @@ -8,9 +8,33 @@ Required properties: - interrupts: interrupt mapping for UFS host controller IRQ - reg : registers mapping +Optional properties: +- vcc-supply: phandle to VCC supply regulator node +- vccq-supply : phandle to VCCQ supply regulator node +- vccq2-supply : phandle to VCCQ2 supply regulator node +- vcc-supply-1p8: For embedded UFS devices, valid VCC range is 1.7-1.95V + or 2.7-3.6V. This boolean property when set, specifies + to use low voltage range of 1.7-1.95V. Note for external + UFS cards this property is invalid and valid VCC range is + always 2.7-3.6V. +- vcc-max-microamp : specifies max. load that can be drawn from vcc supply +- vccq-max-microamp : specifies max. load that can be drawn from vccq supply +- vccq2-max-microamp: specifies max. load that can be drawn from vccq2 supply + +Note: If above properties are not defined it can be assumed that the supply +regulators are always on. + Example: ufshc@0xfc598000 { compatible = jedec,ufs-1.1; reg = 0xfc598000 0x800; interrupts = 0 28 0; + + vcc-supply = xxx_reg1; + vcc-supply-1p8; + vccq-supply = xxx_reg2; + vccq2-supply = xxx_reg3; + vcc-max-microamp = 50; + vccq-max-microamp = 20; + vccq2-max-microamp = 20; }; diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index bce09a6..7db080e 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -325,4 +325,29 @@ struct ufs_query_res { struct utp_upiu_query upiu_res; }; +#define UFS_VREG_VCC_MIN_UV 270 /* uV */ +#define UFS_VREG_VCC_MAX_UV 360 /* uV */ +#define UFS_VREG_VCC_1P8_MIN_UV170 /* uV */ +#define UFS_VREG_VCC_1P8_MAX_UV195 /* uV */ +#define UFS_VREG_VCCQ_MIN_UV 110 /* uV */ +#define UFS_VREG_VCCQ_MAX_UV 130 /* uV */ +#define UFS_VREG_VCCQ2_MIN_UV 165 /* uV */ +#define UFS_VREG_VCCQ2_MAX_UV 195 /* uV */ + +struct ufs_vreg { + struct regulator *reg; + const char *name; + bool enabled; + int min_uV; + int max_uV; + int min_uA; + int max_uA; +}; + +struct ufs_vreg_info { + struct ufs_vreg *vcc; + struct ufs_vreg *vccq; + struct ufs_vreg *vccq2; +}; + #endif /* End of Header */ diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 9c94052..cbdf5f3 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -52,6 +52,99 @@ static struct ufs_hba_variant_ops *get_variant_ops(struct device *dev) return NULL; } +#define MAX_PROP_SIZE 32 +static int ufshcd_populate_vreg(struct device *dev, const char *name, + struct ufs_vreg **out_vreg) +{ + int ret = 0; + char prop_name[MAX_PROP_SIZE]; + struct ufs_vreg *vreg = NULL; + struct device_node *np = dev-of_node; + + if (!np) { + dev_err(dev, %s: non DT initialization\n, __func__); + goto out; + } + + snprintf(prop_name, MAX_PROP_SIZE, %s-supply, name); + if (!of_parse_phandle(np, prop_name, 0)) { + dev_info(dev, %s: Unable to find %s regulator, assuming enabled\n, + __func__, prop_name); + goto out; + } + + vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL); + if (!vreg) { +
Re: [PATCH RFC v3] mmc: sdhci-msm: Add support for MSM chipsets
Hi Georgi, I found the sdhci_msm_vreg_reset(). Why do you run enable-disable? +/* + * Reset vreg by ensuring it is off during probe. A call + * to enable vreg is needed to balance disable vreg + */ +static int sdhci_msm_vreg_reset(struct sdhci_msm_pltfm_data *pdata) I think that controller didn't have responsibility to ensure whether power is enabled or not at probing time. If just needed to balance vreg, then i think this function can be removed. How about? Also before using regulator_is_enabled(), i had found the hole for balancing the vreg. Best Regards, Jaehoon Chung On 08/21/2013 01:44 AM, Georgi Djakov wrote: This platform driver adds the support of Secure Digital Host Controller Interface compliant controller in MSM chipsets. CC: Asutosh Das asuto...@codeaurora.org CC: Venkat Gopalakrishnan venk...@codeaurora.org CC: Sahitya Tummala stumm...@codeaurora.org CC: Subhash Jadavani subha...@codeaurora.org Signed-off-by: Georgi Djakov gdja...@mm-sol.com --- Changes from v2: - Added DT bindings for clocks - Moved voltage regulators data to platform data - Removed unneeded includes - Removed obsolete and wrapper functions - Removed error checking where unnecessary - Removed redundant _clk suffix from clock names - Just return instead of goto where possible - Minor fixes Changes from v1: - GPIO references are replaced by pinctrl - DT parsing is done mostly by mmc_of_parse() - Use of_match_device() for DT matching - A few minor changes .../devicetree/bindings/mmc/sdhci-msm.txt | 71 ++ drivers/mmc/host/Kconfig | 13 + drivers/mmc/host/Makefile |1 + drivers/mmc/host/sdhci-msm.c | 687 4 files changed, 772 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-msm.txt create mode 100644 drivers/mmc/host/sdhci-msm.c diff --git a/Documentation/devicetree/bindings/mmc/sdhci-msm.txt b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt new file mode 100644 index 000..ee112da --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt @@ -0,0 +1,71 @@ +* Qualcomm SDHCI controller (sdhci-msm) + +This file documents differences between the core properties in mmc.txt +and the properties used by the sdhci-msm driver. + +Required properties: +- compatible: should be qcom,sdhci-msm +- reg: should contain SDHC, SD Core register map +- reg-names: indicates various resources passed to driver (via reg proptery) by name + reg-names examples are hc_mem and core_mem +- interrupts: should contain SDHC interrupts +- interrupt-names: indicates interrupts passed to driver (via interrupts property) by name + interrupt-names examples are hc_irq and pwr_irq +- supply-name-supply: phandle to the regulator device tree node + supply-name examples are vdd and vdd-io +- pinctrl-names: Should contain only one value - default. +- pinctrl-0: Should specify pin control groups used for this controller. +- clocks: phandles to clock instances of the device tree nodes +- clock-names: + iface: Main peripheral bus clock (PCLK/HCLK - AHB Bus clock) (required) + core: SDC MMC clock (MCLK) (required) + bus: SDCC bus voter clock (optional) + +Optional properties: +- qcom,bus-speed-mode - specifies supported bus speed modes by host + The supported bus speed modes are : + HS200_1p8v - indicates that host can support HS200 at 1.8v + HS200_1p2v - indicates that host can support HS200 at 1.2v + DDR_1p8v - indicates that host can support DDR mode at 1.8v + DDR_1p2v - indicates that host can support DDR mode at 1.2v + +In the following, supply can be vdd (flash core voltage) or vdd-io (I/O voltage). +- qcom,supply-always-on - specifies whether supply should be kept on always. +- qcom,supply-lpm-sup - specifies whether supply can be kept in low power mode (lpm). +- qcom,supply-voltage-level - specifies voltage levels for supply. Should be +specified in pairs (min, max), units uV. +- qcom,supply-current-level - specifies load levels for supply in lpm or high power mode + (hpm). Should be specified in pairs (lpm, hpm), units uA. + +Example: + + aliases { + sdhc1 = sdhc_1; + }; + + sdhc_1: qcom,sdhc@f9824900 { + compatible = qcom,sdhci-msm; + reg = 0xf9824900 0x11c, 0xf9824000 0x800; + reg-names = hc_mem, core_mem; + interrupts = 0 123 0, 0 138 0; + interrupt-names = hc_irq, pwr_irq; + bus-width = 4; + non-removable; + + vdd-supply = pm8941_l21; + vdd-io-supply = pm8941_l13; + qcom,vdd-voltage-level = 295 295; + qcom,vdd-current-level = 9000 80; + qcom,vdd-io-always-on; + qcom,vdd-io-lpm-sup; + qcom,vdd-io-voltage-level = 180 295;
Re: [PATCH] scsi: ufs: read door bell register after clearing interrupt aggregation
On 8/27/2013 1:50 PM, Subhash Jadavani wrote: Looks good to me. Reviewed-by: Subhash Jadavani subha...@codeaurora.org On 8/25/2013 4:06 PM, Dolev Raviv wrote: In interrupt context, after reading and comparing the UTRLDBR to hba-outstanding_request and before resetting the interrupt aggregation, there might be completion of another transfer request (TR). Such TRs might get stuck, pending, until the next interrupt is generated. The fix reads the UTRLDBR after resetting the interrupt aggregation and handles completed TRs. Signed-off-by: Dolev Raviv dra...@codeaurora.org diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 4dca9b4..30c84d8 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1915,6 +1915,13 @@ static void ufshcd_uic_cmd_compl(struct ufs_hba *hba) /** * ufshcd_transfer_req_compl - handle SCSI and query command completion * @hba: per adapter instance + * + * Resetting interrupt aggregation counters first and reading the DOOR_BELL + * afterward , allows us to handle all the completed requests. + * In order to prevent other interrupts starvation the DB is read once + * after reset. The down side of this solution is the possibility of false + * interrupt if device completes another request after resetting aggregation + * and before reading the DB. */ static void ufshcd_transfer_req_compl(struct ufs_hba *hba) { @@ -1924,47 +1931,36 @@ static void ufshcd_transfer_req_compl(struct ufs_hba *hba) u32 tr_doorbell; int result; int index; -bool int_aggr_reset = false; + +/* Reset interrupt aggregation counters */ +ufshcd_config_int_aggr(hba, INT_AGGR_RESET); You may have to rebase your change on top of [PATCH v3 2/6] scsi: ufs: fix the setting interrupt aggregation counter patch. Once you do that, you will be calling ufshcd_reset_intr_aggr() (instead of ufshscd_config_int_aggr()) to reset the interrupt aggregation counters. tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); completed_reqs = tr_doorbell ^ hba-outstanding_reqs; -for (index = 0; index hba-nutrs; index++) { -if (test_bit(index, completed_reqs)) { -lrbp = hba-lrb[index]; -cmd = lrbp-cmd; -/* - * Don't skip resetting interrupt aggregation counters - * if a regular command is present. - */ -int_aggr_reset |= !lrbp-intr_cmd; - -if (cmd) { -result = ufshcd_transfer_rsp_status(hba, lrbp); -scsi_dma_unmap(cmd); -cmd-result = result; -/* Mark completed command as NULL in LRB */ -lrbp-cmd = NULL; -clear_bit_unlock(index, hba-lrb_in_use); -/* Do not touch lrbp after scsi done */ -cmd-scsi_done(cmd); -} else if (lrbp-command_type == -UTP_CMD_TYPE_DEV_MANAGE) { -if (hba-dev_cmd.complete) -complete(hba-dev_cmd.complete); -} -} /* end of if */ -} /* end of for */ +for_each_set_bit(index, completed_reqs, hba-nutrs) { +lrbp = hba-lrb[index]; +cmd = lrbp-cmd; +if (cmd) { +result = ufshcd_transfer_rsp_status(hba, lrbp); +scsi_dma_unmap(cmd); +cmd-result = result; +/* Mark completed command as NULL in LRB */ +lrbp-cmd = NULL; +clear_bit_unlock(index, hba-lrb_in_use); +/* Do not touch lrbp after scsi done */ +cmd-scsi_done(cmd); +} else if (lrbp-command_type == UTP_CMD_TYPE_DEV_MANAGE) { +if (hba-dev_cmd.complete) +complete(hba-dev_cmd.complete); +} +} /* end of for_each_set_bit */ /* clear corresponding bits of completed commands */ hba-outstanding_reqs ^= completed_reqs; /* we might have free'd some tags above */ wake_up(hba-dev_cmd.tag_wq); - -/* Reset interrupt aggregation counters */ -if (int_aggr_reset) -ufshcd_config_int_aggr(hba, INT_AGGR_RESET); } /** @@ -2569,6 +2565,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) int poll_cnt; u8 resp = 0xF; struct ufshcd_lrb *lrbp; +u32 reg; host = cmd-device-host; hba = shost_priv(host); @@ -2578,6 +2575,13 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) if (!(test_bit(tag, hba-outstanding_reqs))) goto out; +reg = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); +if (!(reg (1 tag))) { +dev_err(hba-dev, +%s: cmd was completed, but without a notifying intr, tag = %d, +__func__, tag); +} + lrbp = hba-lrb[tag]; for (poll_cnt = 100; poll_cnt; poll_cnt--) { err = ufshcd_issue_tm_cmd(hba, lrbp-lun, lrbp-task_tag, @@ -2586,8 +2590,6 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) /* cmd pending in the
Re: [PATCH RFC v2 3/5] spmi: add generic SPMI controller binding documentation
Hey Stephen- Thanks for the comments. On Fri, Aug 23, 2013 at 03:58:36PM -0600, Stephen Warren wrote: On 08/22/2013 01:59 PM, Josh Cartwright wrote: Signed-off-by: Josh Cartwright jo...@codeaurora.org --- I'm introducing this as an RFC, because there are set of assumptions made in this binding spec, that currently hold true for the supported controller/addressing scheme for the Snapdragon 800 series, but don't necessarily hold true for SPMI in general. 1. No use of Group Slave Identifiers (GSIDs) (SPMI allows for a slave to belong to zero or more groups specified by GSID, however this feature isn't currently implemented) 2. No specification of Master Identifier (MID) (A system integrator allocates to each master a 2-bit MID, this currently isn't being specified, as it isn't needed by software for the PMIC Arb; not sure if this is of use to other SPMI controllers) 3. Single SPMI master per controller Effectively, only a subset of possible SPMI configurations are specified in this document. So, if it's considered necessary to provide a generic SPMI binding specification, is it acceptable to only define a subset at this time, expanding only when necessary, or shall I expand the definition to at least address 1 2, even though they are of no use in the current implementation? It's best to define the whole thing from the start if possible. It's easier to ensure the whole binding is consistent, and nothing has been left out. That makes sense. I think I'll go down this route for v3 of this patchset: For #1 above, extend the 'reg' property of a slave node to include the group slave ID's in which the slave is a member. The first 'reg' entry will remain the slave's Unique Slave Identifier (USID) as before. For #2, add additional required 'spmi-mid' property in the controller/master node that describes the 2-bit Master Identifier (MID). For #3, rename the SPMI API's s/controller/master/. The current controller/master terminology difference is confusing and unnecessary. However, it's probably OK to define a subset binding initially and then expand it later, as long as some thought it put into how it can be expanded in a way that is 100% compatible: old DTs will still operate with new kernels and perhaps even new DTs will still operate with old kernels. That said, if the thought is put in to ensure that's possible, it's probably just as easy to define the whole binding from the start. That all makes sense. If we want to ensure for the generic bindings that we are fulling characterizing/describing the SPMI bus, then we'll additionally need to tackle an additional identified assumption: 4. One master per SPMI bus. (The SPMI spec allows for up to 4 masters) On the Snapdragon 800 series, there exists only one software-controlled master, but it is conceivably possible to have a setup with two software-controlled masters on the same SPMI bus. This necessarily means that the description of the slaves and the masters will need to be decoupled; I'm imagining a generic binding supporting multiple masters would look something like this: master0: master@0 { compatible = ...; #spmi-master-cells = 0; spmi-mid = 0; ... }; master2: master@2 { compatible = ...; #spmi-master-cells = 0; spmi-mid = 2; ... }; spmi_bus { compatible = ...; spmi-masters = master0 master2; foo@0 { compatible = ...; reg = 0 ...; }; foo@8 { compatible = ...; reg = 8 ...; }; }; (This will also necessitate a change in the underlying SPMI driver model, in the current implementation, a SPMI master 'owns' a particular device. This is not a valid assumption to make.) Would this property-containing-phandle-vector be considered the canonical way of representing nodes with multiple parents in the device tree? Thanks, Josh -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 2/3] usb: phy: Add Qualcomm SS-USB and HS-USB drivers for DWC3 core
Hi, On Thu, Aug 22, 2013 at 09:24:49PM +, Paul Zimmerman wrote: From: Ivan T. Ivanov [mailto:iiva...@mm-sol.com] Sent: Tuesday, August 20, 2013 8:26 AM On Tue, 2013-08-20 at 10:01 -0500, Kumar Gala wrote: On Aug 20, 2013, at 9:54 AM, Ivan T. Ivanov wrote: Hi, On Tue, 2013-08-20 at 09:33 -0500, Felipe Balbi wrote: On Tue, Aug 20, 2013 at 05:09:11PM +0300, Ivan T. Ivanov wrote: On Tue, 2013-08-20 at 08:37 -0500, Felipe Balbi wrote: On Tue, Aug 20, 2013 at 04:32:23PM +0300, Ivan T. Ivanov wrote: I think they are SNPS DesignWare PHY's, additionally wrapped with Qualcomm logic. I could substitute dwc3 with just dw, which will be more correct. alright, thank you. Let's add Paul to the loop since he might have very good insight in the synopsys PHYs. mental note: if any other platform shows up with Synopsys PHY, ask them to use this driver instead :-) I really doubt that this will bi possible. Control of the PHY's is not directly trough ULPI, UTMI or PIPE3 interfaces, but trough QSCRATCH registers, which of course is highly Qualcomm specific. isn't it a memory mapped IP ? doesn't synopsys provide their own set of registers ? From what I see it is not directly mapped. How QSCRATCH write and reads transactions are translated to DW IP is unclear to me. I think the question is how does SW access them? USB QSCRATCH Hardware registers don't ask me what is this :-) or like Pawel says: it depends on the SOC . To answer the question doesn't synopsys provide their own set of registers, we provide registers in our USB cores to access the PHYs through I2C, ULPI/UTMI, or PIPE3 interfaces. But if someone wants to use our PHY with some other controller that doesn't provide that, then they may need to implement their own register set, as Qualcomm has apparently done. thanks for clarifying. that pretty much hinders writing any sort of generic drivers for Synopsys' PHYs though :-s But I guess that's alright. -- balbi signature.asc Description: Digital signature
Re: [PATCH RFC v2 3/5] spmi: add generic SPMI controller binding documentation
On 08/27/2013 11:01 AM, Josh Cartwright wrote: ... If we want to ensure for the generic bindings that we are fulling characterizing/describing the SPMI bus, then we'll additionally need to tackle an additional identified assumption: 4. One master per SPMI bus. (The SPMI spec allows for up to 4 masters) On the Snapdragon 800 series, there exists only one software-controlled master, but it is conceivably possible to have a setup with two software-controlled masters on the same SPMI bus. This necessarily means that the description of the slaves and the masters will need to be decoupled; I'm imagining a generic binding supporting multiple masters would look something like this: Is there a need to represent the other masters in the DT? Sure they're there in HW, but if there's no specific way for the CPU-to-which-the-DT-applies to actually interact with those other masters (except perhaps by experiencing some arbitration delays) then presumably there's no need to represent the other masters in DT? master0: master@0 { compatible = ...; #spmi-master-cells = 0; spmi-mid = 0; ... }; master2: master@2 { compatible = ...; #spmi-master-cells = 0; spmi-mid = 2; ... }; spmi_bus { compatible = ...; spmi-masters = master0 master2; foo@0 { compatible = ...; reg = 0 ...; }; foo@8 { compatible = ...; reg = 8 ...; }; }; (This will also necessitate a change in the underlying SPMI driver model, in the current implementation, a SPMI master 'owns' a particular device. This is not a valid assumption to make.) Would this property-containing-phandle-vector be considered the canonical way of representing nodes with multiple parents in the device tree? I don't think I've seen anything like this before, although that in-and-of-itself doesn't make it wrong. Another approach might be to encode master-vs-slave into a cell in the reg property? Something like: cell 0 - address type (0: master, 1: unique ID, 2: group ID, ...) cell 1 - address value I haven't thought much about that; perhaps there are disadvantages doing that. -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm 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/5] Document msm_serial bindings and support newer uartdms
On Tue, Aug 20, 2013 at 11:48:01PM -0700, Stephen Boyd wrote: This patchset aligns the msm_serial driver more with downstream usage and also documents the msm_serial driver's DT binding. Along the way we update the clock names and add support for newer UARTDM hardware that isn't part of a GSBI and make the console layer use the extra registers in UARTDM. Changes since v1: * Dropped _clk postfix from {core,iface}_clk * Split DT binding into two files * Renamed DT binding files to match compatible strings * Fixed up DT review comments * Added new patch 5/5 (more than 1 char for UARTDM) I took patches 1, 3, and 5 from this series, as it seems that the dt bindings are still being discussed. thanks, greg k-h -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm 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/5] Document msm_serial bindings and support newer uartdms
On 08/27/13 16:23, Greg Kroah-Hartman wrote: On Tue, Aug 20, 2013 at 11:48:01PM -0700, Stephen Boyd wrote: This patchset aligns the msm_serial driver more with downstream usage and also documents the msm_serial driver's DT binding. Along the way we update the clock names and add support for newer UARTDM hardware that isn't part of a GSBI and make the console layer use the extra registers in UARTDM. Changes since v1: * Dropped _clk postfix from {core,iface}_clk * Split DT binding into two files * Renamed DT binding files to match compatible strings * Fixed up DT review comments * Added new patch 5/5 (more than 1 char for UARTDM) I took patches 1, 3, and 5 from this series, as it seems that the dt bindings are still being discussed. Thanks Greg. I'll resend the patches right now. I got sidetracked on other things. -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 0/2] Document msm_serial bindings and support newer uartdms
This patchset aligns the msm_serial driver more with downstream usage and updates the driver's DT bindings. Changes since v2: * Fixed up DT review comments * Dropped patches that were picked up in tty tree Changes since v1: * Dropped _clk postfix from {core,iface}_clk * Split DT binding into two files * Renamed DT binding files to match compatible strings * Fixed up DT review comments * Added new patch 5/5 (more than 1 char for UARTDM) Stephen Boyd (2): devicetree: serial: Document msm_serial bindings ARM: dts: msm: Update uartdm compatible strings .../devicetree/bindings/tty/serial/msm_serial.txt | 27 --- .../bindings/tty/serial/qcom,msm-uart.txt | 25 ++ .../bindings/tty/serial/qcom,msm-uartdm.txt| 53 ++ arch/arm/boot/dts/msm8660-surf.dts | 2 +- arch/arm/boot/dts/msm8960-cdp.dts | 2 +- 5 files changed, 80 insertions(+), 29 deletions(-) delete mode 100644 Documentation/devicetree/bindings/tty/serial/msm_serial.txt create mode 100644 Documentation/devicetree/bindings/tty/serial/qcom,msm-uart.txt create mode 100644 Documentation/devicetree/bindings/tty/serial/qcom,msm-uartdm.txt -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 1/2] devicetree: serial: Document msm_serial bindings
Let's fix up the msm serial device bindings so that it's clearer what hardware is supported. Instead of using hsuart (for high speed uart) let's use uartdm because that matches the actual name of the hardware. Also, let's add the version information in case we need to differentiate between different versions of the hardware in the future. Finally, lets specify that clocks are required (the clock bindings didn't exist when the original binding was written) and also specify dma bindings just in case we want to use it in software. We split the binding into two files to make it clearer what's required and not required. Cc: David Brown dav...@codeaurora.org Cc: devicet...@vger.kernel.org Signed-off-by: Stephen Boyd sb...@codeaurora.org --- .../devicetree/bindings/tty/serial/msm_serial.txt | 27 --- .../bindings/tty/serial/qcom,msm-uart.txt | 25 ++ .../bindings/tty/serial/qcom,msm-uartdm.txt| 53 ++ 3 files changed, 78 insertions(+), 27 deletions(-) delete mode 100644 Documentation/devicetree/bindings/tty/serial/msm_serial.txt create mode 100644 Documentation/devicetree/bindings/tty/serial/qcom,msm-uart.txt create mode 100644 Documentation/devicetree/bindings/tty/serial/qcom,msm-uartdm.txt diff --git a/Documentation/devicetree/bindings/tty/serial/msm_serial.txt b/Documentation/devicetree/bindings/tty/serial/msm_serial.txt deleted file mode 100644 index aef383e..000 --- a/Documentation/devicetree/bindings/tty/serial/msm_serial.txt +++ /dev/null @@ -1,27 +0,0 @@ -* Qualcomm MSM UART - -Required properties: -- compatible : - - qcom,msm-uart, and one of qcom,msm-hsuart or - qcom,msm-lsuart. -- reg : offset and length of the register set for the device - for the hsuart operating in compatible mode, there should be a - second pair describing the gsbi registers. -- interrupts : should contain the uart interrupt. - -There are two different UART blocks used in MSM devices, -qcom,msm-hsuart and qcom,msm-lsuart. The msm-serial driver is -able to handle both of these, and matches against the qcom,msm-uart -as the compatibility. - -The registers for the qcom,msm-hsuart device need to specify both -register blocks, even for the common driver. - -Example: - - uart@19c40 { - compatible = qcom,msm-hsuart, qcom,msm-uart; - reg = 0x19c4 0x1000, - 0x19c0 0x1000; - interrupts = 195; - }; diff --git a/Documentation/devicetree/bindings/tty/serial/qcom,msm-uart.txt b/Documentation/devicetree/bindings/tty/serial/qcom,msm-uart.txt new file mode 100644 index 000..ce8c901 --- /dev/null +++ b/Documentation/devicetree/bindings/tty/serial/qcom,msm-uart.txt @@ -0,0 +1,25 @@ +* MSM Serial UART + +The MSM serial UART hardware is designed for low-speed use cases where a +dma-engine isn't needed. From a software perspective it's mostly compatible +with the MSM serial UARTDM except that it only supports reading and writing one +character at a time. + +Required properties: +- compatible: Should contain qcom,msm-uart +- reg: Should contain UART register location and length. +- interrupts: Should contain UART interrupt. +- clocks: Should contain the core clock. +- clock-names: Should be core. + +Example: + +A uart device at 0xa9c0 with interrupt 11. + +serial@a9c0 { + compatible = qcom,msm-uart; + reg = 0xa9c0 0x1000; + interrupts = 11; + clocks = uart_cxc; + clock-names = core; +}; diff --git a/Documentation/devicetree/bindings/tty/serial/qcom,msm-uartdm.txt b/Documentation/devicetree/bindings/tty/serial/qcom,msm-uartdm.txt new file mode 100644 index 000..ffa5b78 --- /dev/null +++ b/Documentation/devicetree/bindings/tty/serial/qcom,msm-uartdm.txt @@ -0,0 +1,53 @@ +* MSM Serial UARTDM + +The MSM serial UARTDM hardware is designed for high-speed use cases where the +transmit and/or receive channels can be offloaded to a dma-engine. From a +software perspective it's mostly compatible with the MSM serial UART except +that it supports reading and writing multiple characters at a time. + +Required properties: +- compatible: Should contain at least qcom,msm-uartdm. + A more specific property should be specified as follows depending + on the version: + qcom,msm-uartdm-v1.1 + qcom,msm-uartdm-v1.2 + qcom,msm-uartdm-v1.3 + qcom,msm-uartdm-v1.4 +- reg: Should contain UART register locations and lengths. The first + register shall specify the main control registers. An optional second + register location shall specify the GSBI control region. + qcom,msm-uartdm-v1.3 is the only compatible value that might + need the GSBI control region. +- interrupts: Should contain UART interrupt. +- clocks: Should contain the core clock and the AHB clock. +- clock-names: Should be core for the core clock and iface for the + AHB
[PATCH v3 2/2] ARM: dts: msm: Update uartdm compatible strings
Let's follow the ratified DT binding and use uartdm instead of hsuart. This does break backwards compatibility but this shouldn't be a problem because the uart driver isn't probing on these devices without adding clock support (which isn't merged so far). Cc: David Brown dav...@codeaurora.org Signed-off-by: Stephen Boyd sb...@codeaurora.org --- arch/arm/boot/dts/msm8660-surf.dts | 2 +- arch/arm/boot/dts/msm8960-cdp.dts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/msm8660-surf.dts b/arch/arm/boot/dts/msm8660-surf.dts index cdc010e..386d428 100644 --- a/arch/arm/boot/dts/msm8660-surf.dts +++ b/arch/arm/boot/dts/msm8660-surf.dts @@ -38,7 +38,7 @@ }; serial@19c4 { - compatible = qcom,msm-hsuart, qcom,msm-uart; + compatible = qcom,msm-uartdm-v1.3, qcom,msm-uartdm; reg = 0x19c4 0x1000, 0x19c0 0x1000; interrupts = 0 195 0x0; diff --git a/arch/arm/boot/dts/msm8960-cdp.dts b/arch/arm/boot/dts/msm8960-cdp.dts index db2060c..532050b 100644 --- a/arch/arm/boot/dts/msm8960-cdp.dts +++ b/arch/arm/boot/dts/msm8960-cdp.dts @@ -38,7 +38,7 @@ }; serial@1644 { - compatible = qcom,msm-hsuart, qcom,msm-uart; + compatible = qcom,msm-uartdm-v1.3, qcom,msm-uartdm; reg = 0x1644 0x1000, 0x1640 0x1000; interrupts = 0 154 0x0; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html