Loading Documentation/devicetree/bindings/platform/msm/qca1530.txt +9 −2 Original line number Diff line number Diff line Loading @@ -16,11 +16,18 @@ Optional properties - qca,clk-gpio: handle the clock control using GPIO interface - qca,xlna-supply: handle to the regulator for xLNA - qca,xlna-gpio: handle to xLNA power control using GPIO interface - qca,xlna-voltage-level: list containing minimum and maximum voltage levels for xlna regulator - qca,xlna-current-level: list containing current values for active operation and sleep modes Example: gnss_qca1530: qca,qca1530{ compatible = "qca,qca1530"; qca,pwr-supply = <&pma8084_l26>; /* Power regulator */ qca,reset-gpio = <&msmgpio 128 0>; /* Reset line */ qca,pwr-supply = <&pma8084_l26>; qca,reset-gpio = <&msmgpio 128 0>; qca,xlna-supply = <&pma8084_l22>; qca,xlna-voltage-level = <3000000 3000000>; qca,xlna-current-level = <90000 100>; }; arch/arm/mach-msm/clock-8084.c +2 −0 Original line number Diff line number Diff line Loading @@ -6589,7 +6589,9 @@ static struct clk_lookup apq_clocks_8084[] = { CLK_LOOKUP("pcie_1_ldo", pcie_1_phy_ldo.c, "msm_pcie.2"), CLK_LOOKUP("", sata_phy_ldo.c, ""), /* QCA1530 clocks */ CLK_LOOKUP("qca,rtc_clk", div_clk3.c, "qca1530.1"), CLK_LOOKUP("qca,tcxo_clk", rf_clk2_pin.c, "qca1530.1"), }; static struct pll_config_regs mmpll0_regs __initdata = { Loading drivers/platform/msm/qca1530.c +132 −71 Original line number Diff line number Diff line Loading @@ -42,6 +42,10 @@ #define QCA1530_OF_CLK_GPIO_NAME "qca,clk-gpio" /* xLNA power regulator prefix for DTS */ #define QCA1530_OF_XLNA_REG_NAME "qca,xlna" /* xLNA voltage property name in DTS */ #define QCA1530_OF_XLNA_POWER_VOLTAGE "qca,xlna-voltage-level" /* xLNA current property name in DTS */ #define QCA1530_OF_XLNA_POWER_CURRENT "qca,xlna-current-level" /* xLNA pin name for DTS */ #define QCA1530_OF_XLNA_GPIO_NAME "qca,xlna-gpio" Loading @@ -51,7 +55,6 @@ * @reset_gpio: Number of GPIO pin for reset control, or -1 * @reset_reg: Handle to power regulator for reset control, or NULL * @rtc_clk: RTC clock handle (32KHz) * @rtc_clk_state: RTC clock state * @rtc_clk_gpio: RTC clock gppio, or -1 * @tcxo_clk: TCXO clock handle * @pwr_reg: Main SoC power regulator handle, or NULL Loading @@ -66,7 +69,6 @@ struct qca1530_static { int reset_gpio; struct regulator *reset_reg; struct clk *rtc_clk; int rtc_clk_state; int rtc_clk_gpio; struct clk *tcxo_clk; struct regulator *pwr_reg; Loading @@ -80,7 +82,6 @@ struct qca1530_static { */ static struct qca1530_static qca1530_data = { .reset_gpio = -1, .rtc_clk_state = -1, .rtc_clk_gpio = -1, .pwr_gpio = -1, .xlna_gpio = -1, Loading @@ -88,6 +89,7 @@ static struct qca1530_static qca1530_data = { /** * qca1530_deinit_gpio() - release GPIO resource * @pdev: platform device data * @pgpio: pointer to GPIO handle * * Function releases GPIO handle allocated by the driver. By default the Loading @@ -96,16 +98,15 @@ static struct qca1530_static qca1530_data = { * * GPIO handle is set to -1. */ static void qca1530_deinit_gpio(int *pgpio) static void qca1530_deinit_gpio(struct platform_device *pdev, int *pgpio) { int gpio = *pgpio; if (gpio >= 0) { pr_debug("Releasing GPIO: %d", gpio); gpio_unexport(gpio); gpio_direction_input(gpio); gpio_free(gpio); devm_gpio_free(&pdev->dev, gpio); *pgpio = -1; } } Loading @@ -119,21 +120,21 @@ static void qca1530_deinit_gpio(int *pgpio) static void qca1530_deinit_regulator(struct regulator **ppwr) { if (*ppwr) { regulator_put(*ppwr); devm_regulator_put(*ppwr); *ppwr = NULL; } } /** * qca1530_clk_set_rtc() - enable or disable clock * qca1530_clk_prepare() - prepare or unprepare clock * @clk: clock handle * @mode: 0 to disable, 1 to enable * @mode: 0 to unprepare, 1 to prepare * * Function turns clock on or off and logs the result. * Function prepares or unprepares clock and logs the result. * * Return: 0 on success, error code on failure */ static int qca1530_clk_set_rtc(struct clk *clk, int mode) static int qca1530_clk_prepare(struct clk *clk, int mode) { int ret = 0; Loading Loading @@ -161,12 +162,12 @@ static void qca1530_clk_set_gpio(int mode) } /** * qca1530_clk_set() - start/stop RTC clocks * qca1530_clk_set() - start/stop initialized clocks * @mode: 1 to start clocks, 0 to stop * * Function turns clocks on or off. Clock configuration is optional, however * when configured, the following order is used: GPIO pin, RTC clock, TCXO * clock. When switching off, the order is reveresed. * when configured, the following order is used: RTC GPIO pin, RTC clock, * TCXO clock. When switching off, the order is reveresed. * * Return: 0 on success, error code on failure. */ Loading @@ -181,18 +182,16 @@ static int qca1530_clk_set(int mode) if (qca1530_data.rtc_clk_gpio >= 0) qca1530_clk_set_gpio(1); if (qca1530_data.rtc_clk) ret = qca1530_clk_set_rtc(qca1530_data.rtc_clk, 1); ret = qca1530_clk_prepare(qca1530_data.rtc_clk, 1); if (!ret && qca1530_data.tcxo_clk) ret = qca1530_clk_set_rtc(qca1530_data.tcxo_clk, 1); qca1530_data.rtc_clk_state = ret ? 0 : 1; ret = qca1530_clk_prepare(qca1530_data.tcxo_clk, 1); } else { if (qca1530_data.tcxo_clk) ret = qca1530_clk_set_rtc(qca1530_data.tcxo_clk, 0); ret = qca1530_clk_prepare(qca1530_data.tcxo_clk, 0); if (!ret && qca1530_data.rtc_clk) ret = qca1530_clk_set_rtc(qca1530_data.rtc_clk, 0); ret = qca1530_clk_prepare(qca1530_data.rtc_clk, 0); if (!ret && qca1530_data.rtc_clk_gpio >= 0) qca1530_clk_set_gpio(0); qca1530_data.rtc_clk_state = 0; } pr_debug("Configured clk: mode=%d ret=%d", mode, ret); Loading @@ -201,21 +200,24 @@ static int qca1530_clk_set(int mode) } /** * qca1530_clk_deinit_rtc() - release clocks * qca1530_clk_release_clocks() - release clocks * @pdev: platform device data * * Function sets clock handle references to NULL. * Function releases initialized clocks and sets clock handle * references to NULL. */ static void qca1530_clk_deinit_rtc(struct platform_device *pdev) static void qca1530_clk_release_clocks(struct platform_device *pdev) { if (qca1530_data.tcxo_clk) { pr_debug("Unregistering CLK: device=%s name=%s", dev_name(&pdev->dev), QCA1530_TCXO_CLK_ID); devm_clk_put(&pdev->dev, qca1530_data.tcxo_clk); qca1530_data.tcxo_clk = NULL; } if (qca1530_data.rtc_clk) { pr_debug("Unregistering CLK: device=%s name=%s", dev_name(&pdev->dev), QCA1530_RTC_CLK_ID); devm_clk_put(&pdev->dev, qca1530_data.rtc_clk); qca1530_data.rtc_clk = NULL; } } Loading Loading @@ -306,12 +308,10 @@ static int qca1530_clk_init(struct platform_device *pdev) return 0; err_2: qca1530_deinit_gpio(&qca1530_data.rtc_clk_gpio); qca1530_deinit_gpio(pdev, &qca1530_data.rtc_clk_gpio); err_1: qca1530_clk_deinit_rtc(pdev); qca1530_clk_release_clocks(pdev); err_0: qca1530_data.rtc_clk_state = -1; pr_err("init error: ret=%d", ret); return ret; Loading @@ -326,9 +326,8 @@ err_0: static void qca1530_clk_deinit(struct platform_device *pdev) { qca1530_clk_set(0); qca1530_deinit_gpio(&qca1530_data.rtc_clk_gpio); qca1530_clk_deinit_rtc(pdev); qca1530_data.rtc_clk_state = -1; qca1530_deinit_gpio(pdev, &qca1530_data.rtc_clk_gpio); qca1530_clk_release_clocks(pdev); } /** Loading Loading @@ -360,33 +359,26 @@ static int qca1530_pwr_set_regulator(struct regulator *reg, int mode) pr_debug("Setting regulator: mode=%d regulator=%p", mode, reg); if (mode) { if (regulator_is_enabled(reg)) { ret = 0; goto done; } ret = regulator_set_mode(reg, REGULATOR_MODE_NORMAL); ret = regulator_enable(reg); if (ret) pr_warn("failed to set regulator mode, ret=%d", ret); pr_err("Failed to enable regulator, rc=%d", ret); else pr_debug("Regulator %p was enabled (%d)", reg, ret); ret = regulator_enable(reg); if (ret) { pr_err("failed to enable regulator, rc=%d", ret); goto done; } } else { if (!regulator_is_enabled(reg)) { ret = 0; goto done; } } else { ret = regulator_disable(reg); if (ret) { pr_err("failed to disable regulator, rc=%d", ret); goto done; if (ret) pr_err("Failed to disable regulator, rc=%d", ret); else pr_debug("Regulator %p was disabled (%d)", reg, ret); } } done: pr_debug("Regulator result: regulator=%p mode=%d ret=%d", reg, mode, ret); Loading @@ -403,7 +395,8 @@ static int qca1530_pwr_init_gpio(struct platform_device *pdev) { int ret; ret = of_get_named_gpio(pdev->dev.of_node, QCA1530_OF_PWR_GPIO_NAME, 0); ret = of_get_named_gpio(pdev->dev.of_node, QCA1530_OF_PWR_GPIO_NAME, 0); if (ret == -ENOENT) { qca1530_data.pwr_gpio = ret; ret = 0; Loading @@ -428,7 +421,8 @@ static int qca1530_pwr_init_gpio(struct platform_device *pdev) * Return: 0 on success, error code otherwise */ static int qca1530_pwr_init_regulator( struct platform_device *pdev, const char *name, struct regulator **ppwr) struct platform_device *pdev, const char *name, struct regulator **ppwr) { int ret; struct regulator *pwr; Loading Loading @@ -517,7 +511,7 @@ static int qca1530_pwr_init(struct platform_device *pdev) return ret; err_2: qca1530_deinit_gpio(&qca1530_data.pwr_gpio); qca1530_deinit_gpio(pdev, &qca1530_data.pwr_gpio); err_1: qca1530_deinit_regulator(&qca1530_data.pwr_reg); err_0: Loading @@ -526,13 +520,14 @@ err_0: /** * qca1530_pwr_deinit() - release main SoC power control * @pdev: platform device data * * Function releases power regulator and power GPIO pin. */ static void qca1530_pwr_deinit(void) static void qca1530_pwr_deinit(struct platform_device *pdev) { qca1530_pwr_set(0); qca1530_deinit_gpio(&qca1530_data.pwr_gpio); qca1530_deinit_gpio(pdev, &qca1530_data.pwr_gpio); qca1530_deinit_regulator(&qca1530_data.pwr_reg); } Loading Loading @@ -597,21 +592,22 @@ static int qca1530_reset_init(struct platform_device *pdev) err_supply_configure: qca1530_deinit_regulator(&qca1530_data.reset_reg); err_gpio_configure: qca1530_deinit_gpio(&qca1530_data.reset_gpio); qca1530_deinit_gpio(pdev, &qca1530_data.reset_gpio); err_gpio_get: return ret; } /** * qca1530_reset_deinit() - release reset control resources * @pdev: platform device data * * Function releases reset line GPIO and switches off and releases power * regulator. */ static void qca1530_reset_deinit(void) static void qca1530_reset_deinit(struct platform_device *pdev) { pr_debug("reset control: releasing"); qca1530_deinit_gpio(&qca1530_data.reset_gpio); qca1530_deinit_gpio(pdev, &qca1530_data.reset_gpio); if (qca1530_data.reset_reg) { qca1530_pwr_set_regulator(qca1530_data.reset_reg, 0); qca1530_deinit_regulator(&qca1530_data.reset_reg); Loading Loading @@ -661,9 +657,11 @@ static int qca1530_xlna_set(int mode) if (!qca1530_data.xlna_reg && qca1530_data.xlna_gpio < 0) ret = -ENOSYS; else if (mode) { if (qca1530_data.xlna_reg) if (qca1530_data.xlna_reg) { ret = qca1530_pwr_set_regulator( qca1530_data.xlna_reg, mode); } if (!ret && qca1530_data.xlna_gpio >= 0) gpio_set_value(qca1530_data.xlna_gpio, 1); } else { Loading @@ -676,12 +674,46 @@ static int qca1530_xlna_set(int mode) return ret; } /** * qca1530_read_u32_arr_property() - read u32 values property * @pdev: platform device data * @pname: property name * @num_values: array size * @values: array to put results to * * Function reads property with given name. Filles passed array of * u32 values. * * Return: 0 on successful read, error code on error. */ static int qca1530_read_u32_arr_property(struct platform_device *pdev, const char *pname, const int num_values, u32 *values) { int len = 0; int ret = 0; if (pdev->dev.of_node) { const void *rp = of_get_property(pdev->dev.of_node, pname, &len); if (NULL != rp && len == sizeof(u32)*num_values) ret = of_property_read_u32_array(pdev->dev.of_node, pname, values, num_values); else ret = -ENODATA; } else{ ret = -EINVAL; } if (ret) pr_err("Error reading property %s, ret:%d", pname, ret); return ret; } /** * qca1530_xlna_init() - allocates xLNA resources * @pdev: platform device data * * Function allocates xLNA resources according to DTS configuration. When * configured, the following facilities are used: * Function allocates xLNA resources according to DTS configuration. * When configured, the following facilities are used: * - power regulator (optionally) * - GPIO pin (optionally) * Loading @@ -692,6 +724,7 @@ static int qca1530_xlna_set(int mode) static int qca1530_xlna_init(struct platform_device *pdev) { int ret = 0; u32 tmp[2]; pr_debug("xLNA control: initializing"); Loading @@ -700,6 +733,33 @@ static int qca1530_xlna_init(struct platform_device *pdev) if (ret) goto err_0; if (qca1530_data.xlna_reg) { ret = qca1530_read_u32_arr_property(pdev, QCA1530_OF_XLNA_POWER_VOLTAGE, 2, tmp); if (!ret) { ret = regulator_set_voltage(qca1530_data.xlna_reg, tmp[0], tmp[1]); if (ret) pr_warn("Failed to set voltage, ret=%d", ret); else pr_debug("Regulator %p voltage was set (%d)", qca1530_data.xlna_reg, ret); } ret = qca1530_read_u32_arr_property(pdev, QCA1530_OF_XLNA_POWER_CURRENT, 2, tmp); if (!ret) { ret = regulator_set_optimum_mode(qca1530_data.xlna_reg, tmp[0]); if (ret < 0) pr_warn("Failed to set optimum mode, ret=%d", ret); else pr_debug("Optimum mode for %p was set (%d)", qca1530_data.xlna_reg, ret); } } ret = qca1530_xlna_init_gpio(pdev); if (ret) goto err_1; Loading @@ -719,7 +779,7 @@ static int qca1530_xlna_init(struct platform_device *pdev) return ret; err_2: qca1530_deinit_gpio(&qca1530_data.xlna_gpio); qca1530_deinit_gpio(pdev, &qca1530_data.xlna_gpio); err_1: qca1530_deinit_regulator(&qca1530_data.xlna_reg); err_0: Loading @@ -728,13 +788,14 @@ err_0: /** * qca1530_xlna_deinit() - release all xLNA resources * @pdev: platform device data * * Function switches off xLNA and releases all allocated resources. */ static void qca1530_xlna_deinit(void) static void qca1530_xlna_deinit(struct platform_device *pdev) { qca1530_xlna_set(0); qca1530_deinit_gpio(&qca1530_data.xlna_gpio); qca1530_deinit_gpio(pdev, &qca1530_data.xlna_gpio); qca1530_deinit_regulator(&qca1530_data.xlna_reg); } Loading Loading @@ -778,18 +839,18 @@ static int qca1530_probe(struct platform_device *pdev) } qca1530_data.pdev = pdev; pr_debug("Probe OK"); return ret; err_pwr_init: qca1530_xlna_deinit(); qca1530_xlna_deinit(pdev); err_xlna_init: qca1530_clk_deinit(pdev); err_clk_init: qca1530_reset_deinit(); qca1530_reset_deinit(pdev); err_reset_init: pr_debug("Probe ret=%d", ret); return ret; } Loading @@ -805,10 +866,10 @@ err_reset_init: */ static int qca1530_remove(struct platform_device *pdev) { qca1530_pwr_deinit(); qca1530_xlna_deinit(); qca1530_pwr_deinit(pdev); qca1530_xlna_deinit(pdev); qca1530_clk_deinit(pdev); qca1530_reset_deinit(); qca1530_reset_deinit(pdev); qca1530_data.pdev = NULL; return 0; } Loading Loading
Documentation/devicetree/bindings/platform/msm/qca1530.txt +9 −2 Original line number Diff line number Diff line Loading @@ -16,11 +16,18 @@ Optional properties - qca,clk-gpio: handle the clock control using GPIO interface - qca,xlna-supply: handle to the regulator for xLNA - qca,xlna-gpio: handle to xLNA power control using GPIO interface - qca,xlna-voltage-level: list containing minimum and maximum voltage levels for xlna regulator - qca,xlna-current-level: list containing current values for active operation and sleep modes Example: gnss_qca1530: qca,qca1530{ compatible = "qca,qca1530"; qca,pwr-supply = <&pma8084_l26>; /* Power regulator */ qca,reset-gpio = <&msmgpio 128 0>; /* Reset line */ qca,pwr-supply = <&pma8084_l26>; qca,reset-gpio = <&msmgpio 128 0>; qca,xlna-supply = <&pma8084_l22>; qca,xlna-voltage-level = <3000000 3000000>; qca,xlna-current-level = <90000 100>; };
arch/arm/mach-msm/clock-8084.c +2 −0 Original line number Diff line number Diff line Loading @@ -6589,7 +6589,9 @@ static struct clk_lookup apq_clocks_8084[] = { CLK_LOOKUP("pcie_1_ldo", pcie_1_phy_ldo.c, "msm_pcie.2"), CLK_LOOKUP("", sata_phy_ldo.c, ""), /* QCA1530 clocks */ CLK_LOOKUP("qca,rtc_clk", div_clk3.c, "qca1530.1"), CLK_LOOKUP("qca,tcxo_clk", rf_clk2_pin.c, "qca1530.1"), }; static struct pll_config_regs mmpll0_regs __initdata = { Loading
drivers/platform/msm/qca1530.c +132 −71 Original line number Diff line number Diff line Loading @@ -42,6 +42,10 @@ #define QCA1530_OF_CLK_GPIO_NAME "qca,clk-gpio" /* xLNA power regulator prefix for DTS */ #define QCA1530_OF_XLNA_REG_NAME "qca,xlna" /* xLNA voltage property name in DTS */ #define QCA1530_OF_XLNA_POWER_VOLTAGE "qca,xlna-voltage-level" /* xLNA current property name in DTS */ #define QCA1530_OF_XLNA_POWER_CURRENT "qca,xlna-current-level" /* xLNA pin name for DTS */ #define QCA1530_OF_XLNA_GPIO_NAME "qca,xlna-gpio" Loading @@ -51,7 +55,6 @@ * @reset_gpio: Number of GPIO pin for reset control, or -1 * @reset_reg: Handle to power regulator for reset control, or NULL * @rtc_clk: RTC clock handle (32KHz) * @rtc_clk_state: RTC clock state * @rtc_clk_gpio: RTC clock gppio, or -1 * @tcxo_clk: TCXO clock handle * @pwr_reg: Main SoC power regulator handle, or NULL Loading @@ -66,7 +69,6 @@ struct qca1530_static { int reset_gpio; struct regulator *reset_reg; struct clk *rtc_clk; int rtc_clk_state; int rtc_clk_gpio; struct clk *tcxo_clk; struct regulator *pwr_reg; Loading @@ -80,7 +82,6 @@ struct qca1530_static { */ static struct qca1530_static qca1530_data = { .reset_gpio = -1, .rtc_clk_state = -1, .rtc_clk_gpio = -1, .pwr_gpio = -1, .xlna_gpio = -1, Loading @@ -88,6 +89,7 @@ static struct qca1530_static qca1530_data = { /** * qca1530_deinit_gpio() - release GPIO resource * @pdev: platform device data * @pgpio: pointer to GPIO handle * * Function releases GPIO handle allocated by the driver. By default the Loading @@ -96,16 +98,15 @@ static struct qca1530_static qca1530_data = { * * GPIO handle is set to -1. */ static void qca1530_deinit_gpio(int *pgpio) static void qca1530_deinit_gpio(struct platform_device *pdev, int *pgpio) { int gpio = *pgpio; if (gpio >= 0) { pr_debug("Releasing GPIO: %d", gpio); gpio_unexport(gpio); gpio_direction_input(gpio); gpio_free(gpio); devm_gpio_free(&pdev->dev, gpio); *pgpio = -1; } } Loading @@ -119,21 +120,21 @@ static void qca1530_deinit_gpio(int *pgpio) static void qca1530_deinit_regulator(struct regulator **ppwr) { if (*ppwr) { regulator_put(*ppwr); devm_regulator_put(*ppwr); *ppwr = NULL; } } /** * qca1530_clk_set_rtc() - enable or disable clock * qca1530_clk_prepare() - prepare or unprepare clock * @clk: clock handle * @mode: 0 to disable, 1 to enable * @mode: 0 to unprepare, 1 to prepare * * Function turns clock on or off and logs the result. * Function prepares or unprepares clock and logs the result. * * Return: 0 on success, error code on failure */ static int qca1530_clk_set_rtc(struct clk *clk, int mode) static int qca1530_clk_prepare(struct clk *clk, int mode) { int ret = 0; Loading Loading @@ -161,12 +162,12 @@ static void qca1530_clk_set_gpio(int mode) } /** * qca1530_clk_set() - start/stop RTC clocks * qca1530_clk_set() - start/stop initialized clocks * @mode: 1 to start clocks, 0 to stop * * Function turns clocks on or off. Clock configuration is optional, however * when configured, the following order is used: GPIO pin, RTC clock, TCXO * clock. When switching off, the order is reveresed. * when configured, the following order is used: RTC GPIO pin, RTC clock, * TCXO clock. When switching off, the order is reveresed. * * Return: 0 on success, error code on failure. */ Loading @@ -181,18 +182,16 @@ static int qca1530_clk_set(int mode) if (qca1530_data.rtc_clk_gpio >= 0) qca1530_clk_set_gpio(1); if (qca1530_data.rtc_clk) ret = qca1530_clk_set_rtc(qca1530_data.rtc_clk, 1); ret = qca1530_clk_prepare(qca1530_data.rtc_clk, 1); if (!ret && qca1530_data.tcxo_clk) ret = qca1530_clk_set_rtc(qca1530_data.tcxo_clk, 1); qca1530_data.rtc_clk_state = ret ? 0 : 1; ret = qca1530_clk_prepare(qca1530_data.tcxo_clk, 1); } else { if (qca1530_data.tcxo_clk) ret = qca1530_clk_set_rtc(qca1530_data.tcxo_clk, 0); ret = qca1530_clk_prepare(qca1530_data.tcxo_clk, 0); if (!ret && qca1530_data.rtc_clk) ret = qca1530_clk_set_rtc(qca1530_data.rtc_clk, 0); ret = qca1530_clk_prepare(qca1530_data.rtc_clk, 0); if (!ret && qca1530_data.rtc_clk_gpio >= 0) qca1530_clk_set_gpio(0); qca1530_data.rtc_clk_state = 0; } pr_debug("Configured clk: mode=%d ret=%d", mode, ret); Loading @@ -201,21 +200,24 @@ static int qca1530_clk_set(int mode) } /** * qca1530_clk_deinit_rtc() - release clocks * qca1530_clk_release_clocks() - release clocks * @pdev: platform device data * * Function sets clock handle references to NULL. * Function releases initialized clocks and sets clock handle * references to NULL. */ static void qca1530_clk_deinit_rtc(struct platform_device *pdev) static void qca1530_clk_release_clocks(struct platform_device *pdev) { if (qca1530_data.tcxo_clk) { pr_debug("Unregistering CLK: device=%s name=%s", dev_name(&pdev->dev), QCA1530_TCXO_CLK_ID); devm_clk_put(&pdev->dev, qca1530_data.tcxo_clk); qca1530_data.tcxo_clk = NULL; } if (qca1530_data.rtc_clk) { pr_debug("Unregistering CLK: device=%s name=%s", dev_name(&pdev->dev), QCA1530_RTC_CLK_ID); devm_clk_put(&pdev->dev, qca1530_data.rtc_clk); qca1530_data.rtc_clk = NULL; } } Loading Loading @@ -306,12 +308,10 @@ static int qca1530_clk_init(struct platform_device *pdev) return 0; err_2: qca1530_deinit_gpio(&qca1530_data.rtc_clk_gpio); qca1530_deinit_gpio(pdev, &qca1530_data.rtc_clk_gpio); err_1: qca1530_clk_deinit_rtc(pdev); qca1530_clk_release_clocks(pdev); err_0: qca1530_data.rtc_clk_state = -1; pr_err("init error: ret=%d", ret); return ret; Loading @@ -326,9 +326,8 @@ err_0: static void qca1530_clk_deinit(struct platform_device *pdev) { qca1530_clk_set(0); qca1530_deinit_gpio(&qca1530_data.rtc_clk_gpio); qca1530_clk_deinit_rtc(pdev); qca1530_data.rtc_clk_state = -1; qca1530_deinit_gpio(pdev, &qca1530_data.rtc_clk_gpio); qca1530_clk_release_clocks(pdev); } /** Loading Loading @@ -360,33 +359,26 @@ static int qca1530_pwr_set_regulator(struct regulator *reg, int mode) pr_debug("Setting regulator: mode=%d regulator=%p", mode, reg); if (mode) { if (regulator_is_enabled(reg)) { ret = 0; goto done; } ret = regulator_set_mode(reg, REGULATOR_MODE_NORMAL); ret = regulator_enable(reg); if (ret) pr_warn("failed to set regulator mode, ret=%d", ret); pr_err("Failed to enable regulator, rc=%d", ret); else pr_debug("Regulator %p was enabled (%d)", reg, ret); ret = regulator_enable(reg); if (ret) { pr_err("failed to enable regulator, rc=%d", ret); goto done; } } else { if (!regulator_is_enabled(reg)) { ret = 0; goto done; } } else { ret = regulator_disable(reg); if (ret) { pr_err("failed to disable regulator, rc=%d", ret); goto done; if (ret) pr_err("Failed to disable regulator, rc=%d", ret); else pr_debug("Regulator %p was disabled (%d)", reg, ret); } } done: pr_debug("Regulator result: regulator=%p mode=%d ret=%d", reg, mode, ret); Loading @@ -403,7 +395,8 @@ static int qca1530_pwr_init_gpio(struct platform_device *pdev) { int ret; ret = of_get_named_gpio(pdev->dev.of_node, QCA1530_OF_PWR_GPIO_NAME, 0); ret = of_get_named_gpio(pdev->dev.of_node, QCA1530_OF_PWR_GPIO_NAME, 0); if (ret == -ENOENT) { qca1530_data.pwr_gpio = ret; ret = 0; Loading @@ -428,7 +421,8 @@ static int qca1530_pwr_init_gpio(struct platform_device *pdev) * Return: 0 on success, error code otherwise */ static int qca1530_pwr_init_regulator( struct platform_device *pdev, const char *name, struct regulator **ppwr) struct platform_device *pdev, const char *name, struct regulator **ppwr) { int ret; struct regulator *pwr; Loading Loading @@ -517,7 +511,7 @@ static int qca1530_pwr_init(struct platform_device *pdev) return ret; err_2: qca1530_deinit_gpio(&qca1530_data.pwr_gpio); qca1530_deinit_gpio(pdev, &qca1530_data.pwr_gpio); err_1: qca1530_deinit_regulator(&qca1530_data.pwr_reg); err_0: Loading @@ -526,13 +520,14 @@ err_0: /** * qca1530_pwr_deinit() - release main SoC power control * @pdev: platform device data * * Function releases power regulator and power GPIO pin. */ static void qca1530_pwr_deinit(void) static void qca1530_pwr_deinit(struct platform_device *pdev) { qca1530_pwr_set(0); qca1530_deinit_gpio(&qca1530_data.pwr_gpio); qca1530_deinit_gpio(pdev, &qca1530_data.pwr_gpio); qca1530_deinit_regulator(&qca1530_data.pwr_reg); } Loading Loading @@ -597,21 +592,22 @@ static int qca1530_reset_init(struct platform_device *pdev) err_supply_configure: qca1530_deinit_regulator(&qca1530_data.reset_reg); err_gpio_configure: qca1530_deinit_gpio(&qca1530_data.reset_gpio); qca1530_deinit_gpio(pdev, &qca1530_data.reset_gpio); err_gpio_get: return ret; } /** * qca1530_reset_deinit() - release reset control resources * @pdev: platform device data * * Function releases reset line GPIO and switches off and releases power * regulator. */ static void qca1530_reset_deinit(void) static void qca1530_reset_deinit(struct platform_device *pdev) { pr_debug("reset control: releasing"); qca1530_deinit_gpio(&qca1530_data.reset_gpio); qca1530_deinit_gpio(pdev, &qca1530_data.reset_gpio); if (qca1530_data.reset_reg) { qca1530_pwr_set_regulator(qca1530_data.reset_reg, 0); qca1530_deinit_regulator(&qca1530_data.reset_reg); Loading Loading @@ -661,9 +657,11 @@ static int qca1530_xlna_set(int mode) if (!qca1530_data.xlna_reg && qca1530_data.xlna_gpio < 0) ret = -ENOSYS; else if (mode) { if (qca1530_data.xlna_reg) if (qca1530_data.xlna_reg) { ret = qca1530_pwr_set_regulator( qca1530_data.xlna_reg, mode); } if (!ret && qca1530_data.xlna_gpio >= 0) gpio_set_value(qca1530_data.xlna_gpio, 1); } else { Loading @@ -676,12 +674,46 @@ static int qca1530_xlna_set(int mode) return ret; } /** * qca1530_read_u32_arr_property() - read u32 values property * @pdev: platform device data * @pname: property name * @num_values: array size * @values: array to put results to * * Function reads property with given name. Filles passed array of * u32 values. * * Return: 0 on successful read, error code on error. */ static int qca1530_read_u32_arr_property(struct platform_device *pdev, const char *pname, const int num_values, u32 *values) { int len = 0; int ret = 0; if (pdev->dev.of_node) { const void *rp = of_get_property(pdev->dev.of_node, pname, &len); if (NULL != rp && len == sizeof(u32)*num_values) ret = of_property_read_u32_array(pdev->dev.of_node, pname, values, num_values); else ret = -ENODATA; } else{ ret = -EINVAL; } if (ret) pr_err("Error reading property %s, ret:%d", pname, ret); return ret; } /** * qca1530_xlna_init() - allocates xLNA resources * @pdev: platform device data * * Function allocates xLNA resources according to DTS configuration. When * configured, the following facilities are used: * Function allocates xLNA resources according to DTS configuration. * When configured, the following facilities are used: * - power regulator (optionally) * - GPIO pin (optionally) * Loading @@ -692,6 +724,7 @@ static int qca1530_xlna_set(int mode) static int qca1530_xlna_init(struct platform_device *pdev) { int ret = 0; u32 tmp[2]; pr_debug("xLNA control: initializing"); Loading @@ -700,6 +733,33 @@ static int qca1530_xlna_init(struct platform_device *pdev) if (ret) goto err_0; if (qca1530_data.xlna_reg) { ret = qca1530_read_u32_arr_property(pdev, QCA1530_OF_XLNA_POWER_VOLTAGE, 2, tmp); if (!ret) { ret = regulator_set_voltage(qca1530_data.xlna_reg, tmp[0], tmp[1]); if (ret) pr_warn("Failed to set voltage, ret=%d", ret); else pr_debug("Regulator %p voltage was set (%d)", qca1530_data.xlna_reg, ret); } ret = qca1530_read_u32_arr_property(pdev, QCA1530_OF_XLNA_POWER_CURRENT, 2, tmp); if (!ret) { ret = regulator_set_optimum_mode(qca1530_data.xlna_reg, tmp[0]); if (ret < 0) pr_warn("Failed to set optimum mode, ret=%d", ret); else pr_debug("Optimum mode for %p was set (%d)", qca1530_data.xlna_reg, ret); } } ret = qca1530_xlna_init_gpio(pdev); if (ret) goto err_1; Loading @@ -719,7 +779,7 @@ static int qca1530_xlna_init(struct platform_device *pdev) return ret; err_2: qca1530_deinit_gpio(&qca1530_data.xlna_gpio); qca1530_deinit_gpio(pdev, &qca1530_data.xlna_gpio); err_1: qca1530_deinit_regulator(&qca1530_data.xlna_reg); err_0: Loading @@ -728,13 +788,14 @@ err_0: /** * qca1530_xlna_deinit() - release all xLNA resources * @pdev: platform device data * * Function switches off xLNA and releases all allocated resources. */ static void qca1530_xlna_deinit(void) static void qca1530_xlna_deinit(struct platform_device *pdev) { qca1530_xlna_set(0); qca1530_deinit_gpio(&qca1530_data.xlna_gpio); qca1530_deinit_gpio(pdev, &qca1530_data.xlna_gpio); qca1530_deinit_regulator(&qca1530_data.xlna_reg); } Loading Loading @@ -778,18 +839,18 @@ static int qca1530_probe(struct platform_device *pdev) } qca1530_data.pdev = pdev; pr_debug("Probe OK"); return ret; err_pwr_init: qca1530_xlna_deinit(); qca1530_xlna_deinit(pdev); err_xlna_init: qca1530_clk_deinit(pdev); err_clk_init: qca1530_reset_deinit(); qca1530_reset_deinit(pdev); err_reset_init: pr_debug("Probe ret=%d", ret); return ret; } Loading @@ -805,10 +866,10 @@ err_reset_init: */ static int qca1530_remove(struct platform_device *pdev) { qca1530_pwr_deinit(); qca1530_xlna_deinit(); qca1530_pwr_deinit(pdev); qca1530_xlna_deinit(pdev); qca1530_clk_deinit(pdev); qca1530_reset_deinit(); qca1530_reset_deinit(pdev); qca1530_data.pdev = NULL; return 0; } Loading