diff options
author | Yaniv Gardi <ygardi@codeaurora.org> | 2015-10-28 07:15:49 -0400 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2015-11-09 18:00:02 -0500 |
commit | 47555a5c8a11a423e6767f942941c745766c99a2 (patch) | |
tree | aabb08b80d01dc9e4d38e302a615fbafcf0ddeac | |
parent | 0263bcd0e8319642440fa29c184b0d7f4b2d5857 (diff) |
scsi: ufs: make the UFS variant a platform device
This change turns the UFS variant (SCSI_UFS_QCOM) into a UFS
a platform device.
In order to do so a few additional changes are required:
1. The ufshcd-pltfrm is no longer serves as a platform device.
Now it only serves as a group of platform APIs such as PM APIs
(runtime suspend/resume, system suspend/resume etc), parsers of
clocks, regulators and pm_levels from DT.
2. What used to be the old platform "probe" is now "only"
a pltfrm_init() routine, that does exactly the same, but only
being called by the new probe function of the UFS variant.
Reviewed-by: Rob Herring <robherring2@gmail.com>
Reviewed-by: Gilad Broner <gbroner@codeaurora.org>
Signed-off-by: Yaniv Gardi <ygardi@codeaurora.org>
Tested-by: Alim Akhtar <alim.akhtar@samsung.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | Documentation/devicetree/bindings/ufs/ufs-qcom.txt | 58 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt | 11 | ||||
-rw-r--r-- | drivers/scsi/ufs/ufs-qcom.c | 62 | ||||
-rw-r--r-- | drivers/scsi/ufs/ufshcd-pltfrm.c | 98 | ||||
-rw-r--r-- | drivers/scsi/ufs/ufshcd-pltfrm.h | 41 | ||||
-rw-r--r-- | drivers/scsi/ufs/ufshcd.c | 10 | ||||
-rw-r--r-- | drivers/scsi/ufs/ufshcd.h | 1 |
7 files changed, 207 insertions, 74 deletions
diff --git a/Documentation/devicetree/bindings/ufs/ufs-qcom.txt b/Documentation/devicetree/bindings/ufs/ufs-qcom.txt new file mode 100644 index 000000000000..070baf4d7d97 --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/ufs-qcom.txt | |||
@@ -0,0 +1,58 @@ | |||
1 | * Qualcomm Technologies Inc Universal Flash Storage (UFS) PHY | ||
2 | |||
3 | UFSPHY nodes are defined to describe on-chip UFS PHY hardware macro. | ||
4 | Each UFS PHY node should have its own node. | ||
5 | |||
6 | To bind UFS PHY with UFS host controller, the controller node should | ||
7 | contain a phandle reference to UFS PHY node. | ||
8 | |||
9 | Required properties: | ||
10 | - compatible : compatible list, contains "qcom,ufs-phy-qmp-20nm" | ||
11 | or "qcom,ufs-phy-qmp-14nm" according to the relevant phy in use. | ||
12 | - reg : should contain PHY register address space (mandatory), | ||
13 | - reg-names : indicates various resources passed to driver (via reg proptery) by name. | ||
14 | Required "reg-names" is "phy_mem". | ||
15 | - #phy-cells : This property shall be set to 0 | ||
16 | - vdda-phy-supply : phandle to main PHY supply for analog domain | ||
17 | - vdda-pll-supply : phandle to PHY PLL and Power-Gen block power supply | ||
18 | - clocks : List of phandle and clock specifier pairs | ||
19 | - clock-names : List of clock input name strings sorted in the same | ||
20 | order as the clocks property. "ref_clk_src", "ref_clk", | ||
21 | "tx_iface_clk" & "rx_iface_clk" are mandatory but | ||
22 | "ref_clk_parent" is optional | ||
23 | |||
24 | Optional properties: | ||
25 | - vdda-phy-max-microamp : specifies max. load that can be drawn from phy supply | ||
26 | - vdda-pll-max-microamp : specifies max. load that can be drawn from pll supply | ||
27 | - vddp-ref-clk-supply : phandle to UFS device ref_clk pad power supply | ||
28 | - vddp-ref-clk-max-microamp : specifies max. load that can be drawn from this supply | ||
29 | - vddp-ref-clk-always-on : specifies if this supply needs to be kept always on | ||
30 | |||
31 | Example: | ||
32 | |||
33 | ufsphy1: ufsphy@0xfc597000 { | ||
34 | compatible = "qcom,ufs-phy-qmp-20nm"; | ||
35 | reg = <0xfc597000 0x800>; | ||
36 | reg-names = "phy_mem"; | ||
37 | #phy-cells = <0>; | ||
38 | vdda-phy-supply = <&pma8084_l4>; | ||
39 | vdda-pll-supply = <&pma8084_l12>; | ||
40 | vdda-phy-max-microamp = <50000>; | ||
41 | vdda-pll-max-microamp = <1000>; | ||
42 | clock-names = "ref_clk_src", | ||
43 | "ref_clk_parent", | ||
44 | "ref_clk", | ||
45 | "tx_iface_clk", | ||
46 | "rx_iface_clk"; | ||
47 | clocks = <&clock_rpm clk_ln_bb_clk>, | ||
48 | <&clock_gcc clk_pcie_1_phy_ldo >, | ||
49 | <&clock_gcc clk_ufs_phy_ldo>, | ||
50 | <&clock_gcc clk_gcc_ufs_tx_cfg_clk>, | ||
51 | <&clock_gcc clk_gcc_ufs_rx_cfg_clk>; | ||
52 | }; | ||
53 | |||
54 | ufshc@0xfc598000 { | ||
55 | ... | ||
56 | phys = <&ufsphy1>; | ||
57 | phy-names = "ufsphy"; | ||
58 | }; | ||
diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt index 53579197eca2..03c0e989e020 100644 --- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt +++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt | |||
@@ -4,11 +4,18 @@ UFSHC nodes are defined to describe on-chip UFS host controllers. | |||
4 | Each UFS controller instance should have its own node. | 4 | Each UFS controller instance should have its own node. |
5 | 5 | ||
6 | Required properties: | 6 | Required properties: |
7 | - compatible : compatible list, contains "jedec,ufs-1.1" | 7 | - compatible : must contain "jedec,ufs-1.1", may also list one or more |
8 | of the following: | ||
9 | "qcom,msm8994-ufshc" | ||
10 | "qcom,msm8996-ufshc" | ||
11 | "qcom,ufshc" | ||
8 | - interrupts : <interrupt mapping for UFS host controller IRQ> | 12 | - interrupts : <interrupt mapping for UFS host controller IRQ> |
9 | - reg : <registers mapping> | 13 | - reg : <registers mapping> |
10 | 14 | ||
11 | Optional properties: | 15 | Optional properties: |
16 | - phys : phandle to UFS PHY node | ||
17 | - phy-names : the string "ufsphy" when is found in a node, along | ||
18 | with "phys" attribute, provides phandle to UFS PHY node | ||
12 | - vdd-hba-supply : phandle to UFS host controller supply regulator node | 19 | - vdd-hba-supply : phandle to UFS host controller supply regulator node |
13 | - vcc-supply : phandle to VCC supply regulator node | 20 | - vcc-supply : phandle to VCC supply regulator node |
14 | - vccq-supply : phandle to VCCQ supply regulator node | 21 | - vccq-supply : phandle to VCCQ supply regulator node |
@@ -54,4 +61,6 @@ Example: | |||
54 | clocks = <&core 0>, <&ref 0>, <&iface 0>; | 61 | clocks = <&core 0>, <&ref 0>, <&iface 0>; |
55 | clock-names = "core_clk", "ref_clk", "iface_clk"; | 62 | clock-names = "core_clk", "ref_clk", "iface_clk"; |
56 | freq-table-hz = <100000000 200000000>, <0 0>, <0 0>; | 63 | freq-table-hz = <100000000 200000000>, <0 0>, <0 0>; |
64 | phys = <&ufsphy1>; | ||
65 | phy-names = "ufsphy"; | ||
57 | }; | 66 | }; |
diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index 329ac846befe..b275a9a3b4d5 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include <linux/phy/phy-qcom-ufs.h> | 20 | #include <linux/phy/phy-qcom-ufs.h> |
21 | #include "ufshcd.h" | 21 | #include "ufshcd.h" |
22 | #include "ufshcd-pltfrm.h" | ||
22 | #include "unipro.h" | 23 | #include "unipro.h" |
23 | #include "ufs-qcom.h" | 24 | #include "ufs-qcom.h" |
24 | #include "ufshci.h" | 25 | #include "ufshci.h" |
@@ -1036,7 +1037,7 @@ void ufs_qcom_clk_scale_notify(struct ufs_hba *hba) | |||
1036 | * The variant operations configure the necessary controller and PHY | 1037 | * The variant operations configure the necessary controller and PHY |
1037 | * handshake during initialization. | 1038 | * handshake during initialization. |
1038 | */ | 1039 | */ |
1039 | static const struct ufs_hba_variant_ops ufs_hba_qcom_vops = { | 1040 | static struct ufs_hba_variant_ops ufs_hba_qcom_vops = { |
1040 | .name = "qcom", | 1041 | .name = "qcom", |
1041 | .init = ufs_qcom_init, | 1042 | .init = ufs_qcom_init, |
1042 | .exit = ufs_qcom_exit, | 1043 | .exit = ufs_qcom_exit, |
@@ -1050,4 +1051,63 @@ static const struct ufs_hba_variant_ops ufs_hba_qcom_vops = { | |||
1050 | .resume = ufs_qcom_resume, | 1051 | .resume = ufs_qcom_resume, |
1051 | }; | 1052 | }; |
1052 | 1053 | ||
1054 | /** | ||
1055 | * ufs_qcom_probe - probe routine of the driver | ||
1056 | * @pdev: pointer to Platform device handle | ||
1057 | * | ||
1058 | * Return zero for success and non-zero for failure | ||
1059 | */ | ||
1060 | static int ufs_qcom_probe(struct platform_device *pdev) | ||
1061 | { | ||
1062 | int err; | ||
1063 | struct device *dev = &pdev->dev; | ||
1064 | |||
1065 | /* Perform generic probe */ | ||
1066 | err = ufshcd_pltfrm_init(pdev, &ufs_hba_qcom_vops); | ||
1067 | if (err) | ||
1068 | dev_err(dev, "ufshcd_pltfrm_init() failed %d\n", err); | ||
1069 | |||
1070 | return err; | ||
1071 | } | ||
1072 | |||
1073 | /** | ||
1074 | * ufs_qcom_remove - set driver_data of the device to NULL | ||
1075 | * @pdev: pointer to platform device handle | ||
1076 | * | ||
1077 | * Always return 0 | ||
1078 | */ | ||
1079 | static int ufs_qcom_remove(struct platform_device *pdev) | ||
1080 | { | ||
1081 | struct ufs_hba *hba = platform_get_drvdata(pdev); | ||
1082 | |||
1083 | pm_runtime_get_sync(&(pdev)->dev); | ||
1084 | ufshcd_remove(hba); | ||
1085 | return 0; | ||
1086 | } | ||
1087 | |||
1088 | static const struct of_device_id ufs_qcom_of_match[] = { | ||
1089 | { .compatible = "qcom,ufshc"}, | ||
1090 | {}, | ||
1091 | }; | ||
1092 | |||
1093 | static const struct dev_pm_ops ufs_qcom_pm_ops = { | ||
1094 | .suspend = ufshcd_pltfrm_suspend, | ||
1095 | .resume = ufshcd_pltfrm_resume, | ||
1096 | .runtime_suspend = ufshcd_pltfrm_runtime_suspend, | ||
1097 | .runtime_resume = ufshcd_pltfrm_runtime_resume, | ||
1098 | .runtime_idle = ufshcd_pltfrm_runtime_idle, | ||
1099 | }; | ||
1100 | |||
1101 | static struct platform_driver ufs_qcom_pltform = { | ||
1102 | .probe = ufs_qcom_probe, | ||
1103 | .remove = ufs_qcom_remove, | ||
1104 | .shutdown = ufshcd_pltfrm_shutdown, | ||
1105 | .driver = { | ||
1106 | .name = "ufshcd-qcom", | ||
1107 | .pm = &ufs_qcom_pm_ops, | ||
1108 | .of_match_table = of_match_ptr(ufs_qcom_of_match), | ||
1109 | }, | ||
1110 | }; | ||
1111 | module_platform_driver(ufs_qcom_pltform); | ||
1112 | |||
1053 | MODULE_LICENSE("GPL v2"); | 1113 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 7db9564f507d..9714f2a8b329 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c | |||
@@ -38,20 +38,7 @@ | |||
38 | #include <linux/of.h> | 38 | #include <linux/of.h> |
39 | 39 | ||
40 | #include "ufshcd.h" | 40 | #include "ufshcd.h" |
41 | 41 | #include "ufshcd-pltfrm.h" | |
42 | static const struct of_device_id ufs_of_match[]; | ||
43 | static struct ufs_hba_variant_ops *get_variant_ops(struct device *dev) | ||
44 | { | ||
45 | if (dev->of_node) { | ||
46 | const struct of_device_id *match; | ||
47 | |||
48 | match = of_match_node(ufs_of_match, dev->of_node); | ||
49 | if (match) | ||
50 | return (struct ufs_hba_variant_ops *)match->data; | ||
51 | } | ||
52 | |||
53 | return NULL; | ||
54 | } | ||
55 | 42 | ||
56 | static int ufshcd_parse_clock_info(struct ufs_hba *hba) | 43 | static int ufshcd_parse_clock_info(struct ufs_hba *hba) |
57 | { | 44 | { |
@@ -245,10 +232,11 @@ out: | |||
245 | * Returns 0 if successful | 232 | * Returns 0 if successful |
246 | * Returns non-zero otherwise | 233 | * Returns non-zero otherwise |
247 | */ | 234 | */ |
248 | static int ufshcd_pltfrm_suspend(struct device *dev) | 235 | int ufshcd_pltfrm_suspend(struct device *dev) |
249 | { | 236 | { |
250 | return ufshcd_system_suspend(dev_get_drvdata(dev)); | 237 | return ufshcd_system_suspend(dev_get_drvdata(dev)); |
251 | } | 238 | } |
239 | EXPORT_SYMBOL_GPL(ufshcd_pltfrm_suspend); | ||
252 | 240 | ||
253 | /** | 241 | /** |
254 | * ufshcd_pltfrm_resume - resume power management function | 242 | * ufshcd_pltfrm_resume - resume power management function |
@@ -257,43 +245,47 @@ static int ufshcd_pltfrm_suspend(struct device *dev) | |||
257 | * Returns 0 if successful | 245 | * Returns 0 if successful |
258 | * Returns non-zero otherwise | 246 | * Returns non-zero otherwise |
259 | */ | 247 | */ |
260 | static int ufshcd_pltfrm_resume(struct device *dev) | 248 | int ufshcd_pltfrm_resume(struct device *dev) |
261 | { | 249 | { |
262 | return ufshcd_system_resume(dev_get_drvdata(dev)); | 250 | return ufshcd_system_resume(dev_get_drvdata(dev)); |
263 | } | 251 | } |
252 | EXPORT_SYMBOL_GPL(ufshcd_pltfrm_resume); | ||
264 | 253 | ||
265 | static int ufshcd_pltfrm_runtime_suspend(struct device *dev) | 254 | int ufshcd_pltfrm_runtime_suspend(struct device *dev) |
266 | { | 255 | { |
267 | return ufshcd_runtime_suspend(dev_get_drvdata(dev)); | 256 | return ufshcd_runtime_suspend(dev_get_drvdata(dev)); |
268 | } | 257 | } |
269 | static int ufshcd_pltfrm_runtime_resume(struct device *dev) | 258 | EXPORT_SYMBOL_GPL(ufshcd_pltfrm_runtime_suspend); |
259 | |||
260 | int ufshcd_pltfrm_runtime_resume(struct device *dev) | ||
270 | { | 261 | { |
271 | return ufshcd_runtime_resume(dev_get_drvdata(dev)); | 262 | return ufshcd_runtime_resume(dev_get_drvdata(dev)); |
272 | } | 263 | } |
273 | static int ufshcd_pltfrm_runtime_idle(struct device *dev) | 264 | EXPORT_SYMBOL_GPL(ufshcd_pltfrm_runtime_resume); |
265 | |||
266 | int ufshcd_pltfrm_runtime_idle(struct device *dev) | ||
274 | { | 267 | { |
275 | return ufshcd_runtime_idle(dev_get_drvdata(dev)); | 268 | return ufshcd_runtime_idle(dev_get_drvdata(dev)); |
276 | } | 269 | } |
277 | #else /* !CONFIG_PM */ | 270 | EXPORT_SYMBOL_GPL(ufshcd_pltfrm_runtime_idle); |
278 | #define ufshcd_pltfrm_suspend NULL | 271 | |
279 | #define ufshcd_pltfrm_resume NULL | ||
280 | #define ufshcd_pltfrm_runtime_suspend NULL | ||
281 | #define ufshcd_pltfrm_runtime_resume NULL | ||
282 | #define ufshcd_pltfrm_runtime_idle NULL | ||
283 | #endif /* CONFIG_PM */ | 272 | #endif /* CONFIG_PM */ |
284 | 273 | ||
285 | static void ufshcd_pltfrm_shutdown(struct platform_device *pdev) | 274 | void ufshcd_pltfrm_shutdown(struct platform_device *pdev) |
286 | { | 275 | { |
287 | ufshcd_shutdown((struct ufs_hba *)platform_get_drvdata(pdev)); | 276 | ufshcd_shutdown((struct ufs_hba *)platform_get_drvdata(pdev)); |
288 | } | 277 | } |
278 | EXPORT_SYMBOL_GPL(ufshcd_pltfrm_shutdown); | ||
289 | 279 | ||
290 | /** | 280 | /** |
291 | * ufshcd_pltfrm_probe - probe routine of the driver | 281 | * ufshcd_pltfrm_init - probe routine of the driver |
292 | * @pdev: pointer to Platform device handle | 282 | * @pdev: pointer to Platform device handle |
283 | * @vops: pointer to variant ops | ||
293 | * | 284 | * |
294 | * Returns 0 on success, non-zero value on failure | 285 | * Returns 0 on success, non-zero value on failure |
295 | */ | 286 | */ |
296 | static int ufshcd_pltfrm_probe(struct platform_device *pdev) | 287 | int ufshcd_pltfrm_init(struct platform_device *pdev, |
288 | struct ufs_hba_variant_ops *vops) | ||
297 | { | 289 | { |
298 | struct ufs_hba *hba; | 290 | struct ufs_hba *hba; |
299 | void __iomem *mmio_base; | 291 | void __iomem *mmio_base; |
@@ -321,19 +313,19 @@ static int ufshcd_pltfrm_probe(struct platform_device *pdev) | |||
321 | goto out; | 313 | goto out; |
322 | } | 314 | } |
323 | 315 | ||
324 | hba->vops = get_variant_ops(&pdev->dev); | 316 | hba->vops = vops; |
325 | 317 | ||
326 | err = ufshcd_parse_clock_info(hba); | 318 | err = ufshcd_parse_clock_info(hba); |
327 | if (err) { | 319 | if (err) { |
328 | dev_err(&pdev->dev, "%s: clock parse failed %d\n", | 320 | dev_err(&pdev->dev, "%s: clock parse failed %d\n", |
329 | __func__, err); | 321 | __func__, err); |
330 | goto out; | 322 | goto dealloc_host; |
331 | } | 323 | } |
332 | err = ufshcd_parse_regulator_info(hba); | 324 | err = ufshcd_parse_regulator_info(hba); |
333 | if (err) { | 325 | if (err) { |
334 | dev_err(&pdev->dev, "%s: regulator init failed %d\n", | 326 | dev_err(&pdev->dev, "%s: regulator init failed %d\n", |
335 | __func__, err); | 327 | __func__, err); |
336 | goto out; | 328 | goto dealloc_host; |
337 | } | 329 | } |
338 | 330 | ||
339 | pm_runtime_set_active(&pdev->dev); | 331 | pm_runtime_set_active(&pdev->dev); |
@@ -352,50 +344,12 @@ static int ufshcd_pltfrm_probe(struct platform_device *pdev) | |||
352 | out_disable_rpm: | 344 | out_disable_rpm: |
353 | pm_runtime_disable(&pdev->dev); | 345 | pm_runtime_disable(&pdev->dev); |
354 | pm_runtime_set_suspended(&pdev->dev); | 346 | pm_runtime_set_suspended(&pdev->dev); |
347 | dealloc_host: | ||
348 | ufshcd_dealloc_host(hba); | ||
355 | out: | 349 | out: |
356 | return err; | 350 | return err; |
357 | } | 351 | } |
358 | 352 | EXPORT_SYMBOL_GPL(ufshcd_pltfrm_init); | |
359 | /** | ||
360 | * ufshcd_pltfrm_remove - remove platform driver routine | ||
361 | * @pdev: pointer to platform device handle | ||
362 | * | ||
363 | * Returns 0 on success, non-zero value on failure | ||
364 | */ | ||
365 | static int ufshcd_pltfrm_remove(struct platform_device *pdev) | ||
366 | { | ||
367 | struct ufs_hba *hba = platform_get_drvdata(pdev); | ||
368 | |||
369 | pm_runtime_get_sync(&(pdev)->dev); | ||
370 | ufshcd_remove(hba); | ||
371 | return 0; | ||
372 | } | ||
373 | |||
374 | static const struct of_device_id ufs_of_match[] = { | ||
375 | { .compatible = "jedec,ufs-1.1"}, | ||
376 | {}, | ||
377 | }; | ||
378 | |||
379 | static const struct dev_pm_ops ufshcd_dev_pm_ops = { | ||
380 | .suspend = ufshcd_pltfrm_suspend, | ||
381 | .resume = ufshcd_pltfrm_resume, | ||
382 | .runtime_suspend = ufshcd_pltfrm_runtime_suspend, | ||
383 | .runtime_resume = ufshcd_pltfrm_runtime_resume, | ||
384 | .runtime_idle = ufshcd_pltfrm_runtime_idle, | ||
385 | }; | ||
386 | |||
387 | static struct platform_driver ufshcd_pltfrm_driver = { | ||
388 | .probe = ufshcd_pltfrm_probe, | ||
389 | .remove = ufshcd_pltfrm_remove, | ||
390 | .shutdown = ufshcd_pltfrm_shutdown, | ||
391 | .driver = { | ||
392 | .name = "ufshcd", | ||
393 | .pm = &ufshcd_dev_pm_ops, | ||
394 | .of_match_table = ufs_of_match, | ||
395 | }, | ||
396 | }; | ||
397 | |||
398 | module_platform_driver(ufshcd_pltfrm_driver); | ||
399 | 353 | ||
400 | MODULE_AUTHOR("Santosh Yaragnavi <santosh.sy@samsung.com>"); | 354 | MODULE_AUTHOR("Santosh Yaragnavi <santosh.sy@samsung.com>"); |
401 | MODULE_AUTHOR("Vinayak Holikatti <h.vinayak@samsung.com>"); | 355 | MODULE_AUTHOR("Vinayak Holikatti <h.vinayak@samsung.com>"); |
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.h b/drivers/scsi/ufs/ufshcd-pltfrm.h new file mode 100644 index 000000000000..df64c4180340 --- /dev/null +++ b/drivers/scsi/ufs/ufshcd-pltfrm.h | |||
@@ -0,0 +1,41 @@ | |||
1 | /* Copyright (c) 2015, The Linux Foundation. All rights reserved. | ||
2 | * | ||
3 | * This program is free software; you can redistribute it and/or modify | ||
4 | * it under the terms of the GNU General Public License version 2 and | ||
5 | * only version 2 as published by the Free Software Foundation. | ||
6 | * | ||
7 | * This program is distributed in the hope that it will be useful, | ||
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | * GNU General Public License for more details. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #ifndef UFSHCD_PLTFRM_H_ | ||
15 | #define UFSHCD_PLTFRM_H_ | ||
16 | |||
17 | #include "ufshcd.h" | ||
18 | |||
19 | int ufshcd_pltfrm_init(struct platform_device *pdev, | ||
20 | struct ufs_hba_variant_ops *vops); | ||
21 | void ufshcd_pltfrm_shutdown(struct platform_device *pdev); | ||
22 | |||
23 | #ifdef CONFIG_PM | ||
24 | |||
25 | int ufshcd_pltfrm_suspend(struct device *dev); | ||
26 | int ufshcd_pltfrm_resume(struct device *dev); | ||
27 | int ufshcd_pltfrm_runtime_suspend(struct device *dev); | ||
28 | int ufshcd_pltfrm_runtime_resume(struct device *dev); | ||
29 | int ufshcd_pltfrm_runtime_idle(struct device *dev); | ||
30 | |||
31 | #else /* !CONFIG_PM */ | ||
32 | |||
33 | #define ufshcd_pltfrm_suspend NULL | ||
34 | #define ufshcd_pltfrm_resume NULL | ||
35 | #define ufshcd_pltfrm_runtime_suspend NULL | ||
36 | #define ufshcd_pltfrm_runtime_resume NULL | ||
37 | #define ufshcd_pltfrm_runtime_idle NULL | ||
38 | |||
39 | #endif /* CONFIG_PM */ | ||
40 | |||
41 | #endif /* UFSHCD_PLTFRM_H_ */ | ||
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 9e79c33ea897..2ef98346dc6e 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c | |||
@@ -5348,6 +5348,16 @@ void ufshcd_remove(struct ufs_hba *hba) | |||
5348 | EXPORT_SYMBOL_GPL(ufshcd_remove); | 5348 | EXPORT_SYMBOL_GPL(ufshcd_remove); |
5349 | 5349 | ||
5350 | /** | 5350 | /** |
5351 | * ufshcd_dealloc_host - deallocate Host Bus Adapter (HBA) | ||
5352 | * @hba: pointer to Host Bus Adapter (HBA) | ||
5353 | */ | ||
5354 | void ufshcd_dealloc_host(struct ufs_hba *hba) | ||
5355 | { | ||
5356 | scsi_host_put(hba->host); | ||
5357 | } | ||
5358 | EXPORT_SYMBOL_GPL(ufshcd_dealloc_host); | ||
5359 | |||
5360 | /** | ||
5351 | * ufshcd_set_dma_mask - Set dma mask based on the controller | 5361 | * ufshcd_set_dma_mask - Set dma mask based on the controller |
5352 | * addressing capability | 5362 | * addressing capability |
5353 | * @hba: per adapter instance | 5363 | * @hba: per adapter instance |
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index ce756266b0af..f2aa47e15b13 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h | |||
@@ -576,6 +576,7 @@ static inline void ufshcd_rmwl(struct ufs_hba *hba, u32 mask, u32 val, u32 reg) | |||
576 | } | 576 | } |
577 | 577 | ||
578 | int ufshcd_alloc_host(struct device *, struct ufs_hba **); | 578 | int ufshcd_alloc_host(struct device *, struct ufs_hba **); |
579 | void ufshcd_dealloc_host(struct ufs_hba *); | ||
579 | int ufshcd_init(struct ufs_hba * , void __iomem * , unsigned int); | 580 | int ufshcd_init(struct ufs_hba * , void __iomem * , unsigned int); |
580 | void ufshcd_remove(struct ufs_hba *); | 581 | void ufshcd_remove(struct ufs_hba *); |
581 | 582 | ||