diff options
-rw-r--r-- | drivers/scsi/ufs/ufshcd-pci.c | 8 | ||||
-rw-r--r-- | drivers/scsi/ufs/ufshcd-pltfrm.c | 29 | ||||
-rw-r--r-- | drivers/scsi/ufs/ufshcd.c | 161 | ||||
-rw-r--r-- | drivers/scsi/ufs/ufshcd.h | 34 |
4 files changed, 194 insertions, 38 deletions
diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c index afaabe2aeac8..7a6edbc55f92 100644 --- a/drivers/scsi/ufs/ufshcd-pci.c +++ b/drivers/scsi/ufs/ufshcd-pci.c | |||
@@ -164,7 +164,13 @@ ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
164 | 164 | ||
165 | mmio_base = pcim_iomap_table(pdev)[0]; | 165 | mmio_base = pcim_iomap_table(pdev)[0]; |
166 | 166 | ||
167 | err = ufshcd_init(&pdev->dev, &hba, mmio_base, pdev->irq); | 167 | err = ufshcd_alloc_host(&pdev->dev, &hba); |
168 | if (err) { | ||
169 | dev_err(&pdev->dev, "Allocation failed\n"); | ||
170 | return err; | ||
171 | } | ||
172 | |||
173 | err = ufshcd_init(hba, mmio_base, pdev->irq); | ||
168 | if (err) { | 174 | if (err) { |
169 | dev_err(&pdev->dev, "Initialization failed\n"); | 175 | dev_err(&pdev->dev, "Initialization failed\n"); |
170 | return err; | 176 | return err; |
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 5e4623225422..d727b1a83e95 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c | |||
@@ -35,9 +35,24 @@ | |||
35 | 35 | ||
36 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
37 | #include <linux/pm_runtime.h> | 37 | #include <linux/pm_runtime.h> |
38 | #include <linux/of.h> | ||
38 | 39 | ||
39 | #include "ufshcd.h" | 40 | #include "ufshcd.h" |
40 | 41 | ||
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 | |||
41 | #ifdef CONFIG_PM | 56 | #ifdef CONFIG_PM |
42 | /** | 57 | /** |
43 | * ufshcd_pltfrm_suspend - suspend power management function | 58 | * ufshcd_pltfrm_suspend - suspend power management function |
@@ -138,8 +153,8 @@ static int ufshcd_pltfrm_probe(struct platform_device *pdev) | |||
138 | 153 | ||
139 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 154 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
140 | mmio_base = devm_ioremap_resource(dev, mem_res); | 155 | mmio_base = devm_ioremap_resource(dev, mem_res); |
141 | if (IS_ERR(mmio_base)) { | 156 | if (IS_ERR(*(void **)&mmio_base)) { |
142 | err = PTR_ERR(mmio_base); | 157 | err = PTR_ERR(*(void **)&mmio_base); |
143 | goto out; | 158 | goto out; |
144 | } | 159 | } |
145 | 160 | ||
@@ -150,10 +165,18 @@ static int ufshcd_pltfrm_probe(struct platform_device *pdev) | |||
150 | goto out; | 165 | goto out; |
151 | } | 166 | } |
152 | 167 | ||
168 | err = ufshcd_alloc_host(dev, &hba); | ||
169 | if (err) { | ||
170 | dev_err(&pdev->dev, "Allocation failed\n"); | ||
171 | goto out; | ||
172 | } | ||
173 | |||
174 | hba->vops = get_variant_ops(&pdev->dev); | ||
175 | |||
153 | pm_runtime_set_active(&pdev->dev); | 176 | pm_runtime_set_active(&pdev->dev); |
154 | pm_runtime_enable(&pdev->dev); | 177 | pm_runtime_enable(&pdev->dev); |
155 | 178 | ||
156 | err = ufshcd_init(dev, &hba, mmio_base, irq); | 179 | err = ufshcd_init(hba, mmio_base, irq); |
157 | if (err) { | 180 | if (err) { |
158 | dev_err(dev, "Intialization failed\n"); | 181 | dev_err(dev, "Intialization failed\n"); |
159 | goto out_disable_rpm; | 182 | goto out_disable_rpm; |
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index ba27215b8034..d0565b07dc8a 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * This code is based on drivers/scsi/ufs/ufshcd.c | 4 | * This code is based on drivers/scsi/ufs/ufshcd.c |
5 | * Copyright (C) 2011-2013 Samsung India Software Operations | 5 | * Copyright (C) 2011-2013 Samsung India Software Operations |
6 | * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. | ||
6 | * | 7 | * |
7 | * Authors: | 8 | * Authors: |
8 | * Santosh Yaraganavi <santosh.sy@samsung.com> | 9 | * Santosh Yaraganavi <santosh.sy@samsung.com> |
@@ -31,6 +32,9 @@ | |||
31 | * circumstances will the contributor of this Program be liable for | 32 | * circumstances will the contributor of this Program be liable for |
32 | * any damages of any kind arising from your use or distribution of | 33 | * any damages of any kind arising from your use or distribution of |
33 | * this program. | 34 | * this program. |
35 | * | ||
36 | * The Linux Foundation chooses to take subject only to the GPLv2 | ||
37 | * license terms, and distributes only under these terms. | ||
34 | */ | 38 | */ |
35 | 39 | ||
36 | #include <linux/async.h> | 40 | #include <linux/async.h> |
@@ -175,13 +179,14 @@ static inline u32 ufshcd_get_ufs_version(struct ufs_hba *hba) | |||
175 | /** | 179 | /** |
176 | * ufshcd_is_device_present - Check if any device connected to | 180 | * ufshcd_is_device_present - Check if any device connected to |
177 | * the host controller | 181 | * the host controller |
178 | * @reg_hcs - host controller status register value | 182 | * @hba: pointer to adapter instance |
179 | * | 183 | * |
180 | * Returns 1 if device present, 0 if no device detected | 184 | * Returns 1 if device present, 0 if no device detected |
181 | */ | 185 | */ |
182 | static inline int ufshcd_is_device_present(u32 reg_hcs) | 186 | static inline int ufshcd_is_device_present(struct ufs_hba *hba) |
183 | { | 187 | { |
184 | return (DEVICE_PRESENT & reg_hcs) ? 1 : 0; | 188 | return (ufshcd_readl(hba, REG_CONTROLLER_STATUS) & |
189 | DEVICE_PRESENT) ? 1 : 0; | ||
185 | } | 190 | } |
186 | 191 | ||
187 | /** | 192 | /** |
@@ -1798,11 +1803,10 @@ out: | |||
1798 | * @hba: per adapter instance | 1803 | * @hba: per adapter instance |
1799 | * | 1804 | * |
1800 | * To bring UFS host controller to operational state, | 1805 | * To bring UFS host controller to operational state, |
1801 | * 1. Check if device is present | 1806 | * 1. Enable required interrupts |
1802 | * 2. Enable required interrupts | 1807 | * 2. Configure interrupt aggregation |
1803 | * 3. Configure interrupt aggregation | 1808 | * 3. Program UTRL and UTMRL base addres |
1804 | * 4. Program UTRL and UTMRL base addres | 1809 | * 4. Configure run-stop-registers |
1805 | * 5. Configure run-stop-registers | ||
1806 | * | 1810 | * |
1807 | * Returns 0 on success, non-zero value on failure | 1811 | * Returns 0 on success, non-zero value on failure |
1808 | */ | 1812 | */ |
@@ -1811,14 +1815,6 @@ static int ufshcd_make_hba_operational(struct ufs_hba *hba) | |||
1811 | int err = 0; | 1815 | int err = 0; |
1812 | u32 reg; | 1816 | u32 reg; |
1813 | 1817 | ||
1814 | /* check if device present */ | ||
1815 | reg = ufshcd_readl(hba, REG_CONTROLLER_STATUS); | ||
1816 | if (!ufshcd_is_device_present(reg)) { | ||
1817 | dev_err(hba->dev, "cc: Device not present\n"); | ||
1818 | err = -ENXIO; | ||
1819 | goto out; | ||
1820 | } | ||
1821 | |||
1822 | /* Enable required interrupts */ | 1818 | /* Enable required interrupts */ |
1823 | ufshcd_enable_intr(hba, UFSHCD_ENABLE_INTRS); | 1819 | ufshcd_enable_intr(hba, UFSHCD_ENABLE_INTRS); |
1824 | 1820 | ||
@@ -1839,6 +1835,7 @@ static int ufshcd_make_hba_operational(struct ufs_hba *hba) | |||
1839 | * UCRDY, UTMRLDY and UTRLRDY bits must be 1 | 1835 | * UCRDY, UTMRLDY and UTRLRDY bits must be 1 |
1840 | * DEI, HEI bits must be 0 | 1836 | * DEI, HEI bits must be 0 |
1841 | */ | 1837 | */ |
1838 | reg = ufshcd_readl(hba, REG_CONTROLLER_STATUS); | ||
1842 | if (!(ufshcd_get_lists_status(reg))) { | 1839 | if (!(ufshcd_get_lists_status(reg))) { |
1843 | ufshcd_enable_run_stop_reg(hba); | 1840 | ufshcd_enable_run_stop_reg(hba); |
1844 | } else { | 1841 | } else { |
@@ -1885,6 +1882,9 @@ static int ufshcd_hba_enable(struct ufs_hba *hba) | |||
1885 | msleep(5); | 1882 | msleep(5); |
1886 | } | 1883 | } |
1887 | 1884 | ||
1885 | if (hba->vops && hba->vops->hce_enable_notify) | ||
1886 | hba->vops->hce_enable_notify(hba, PRE_CHANGE); | ||
1887 | |||
1888 | /* start controller initialization sequence */ | 1888 | /* start controller initialization sequence */ |
1889 | ufshcd_hba_start(hba); | 1889 | ufshcd_hba_start(hba); |
1890 | 1890 | ||
@@ -1912,6 +1912,10 @@ static int ufshcd_hba_enable(struct ufs_hba *hba) | |||
1912 | } | 1912 | } |
1913 | msleep(5); | 1913 | msleep(5); |
1914 | } | 1914 | } |
1915 | |||
1916 | if (hba->vops && hba->vops->hce_enable_notify) | ||
1917 | hba->vops->hce_enable_notify(hba, POST_CHANGE); | ||
1918 | |||
1915 | return 0; | 1919 | return 0; |
1916 | } | 1920 | } |
1917 | 1921 | ||
@@ -1928,12 +1932,28 @@ static int ufshcd_link_startup(struct ufs_hba *hba) | |||
1928 | /* enable UIC related interrupts */ | 1932 | /* enable UIC related interrupts */ |
1929 | ufshcd_enable_intr(hba, UIC_COMMAND_COMPL); | 1933 | ufshcd_enable_intr(hba, UIC_COMMAND_COMPL); |
1930 | 1934 | ||
1935 | if (hba->vops && hba->vops->link_startup_notify) | ||
1936 | hba->vops->link_startup_notify(hba, PRE_CHANGE); | ||
1937 | |||
1931 | ret = ufshcd_dme_link_startup(hba); | 1938 | ret = ufshcd_dme_link_startup(hba); |
1932 | if (ret) | 1939 | if (ret) |
1933 | goto out; | 1940 | goto out; |
1934 | 1941 | ||
1935 | ret = ufshcd_make_hba_operational(hba); | 1942 | /* check if device is detected by inter-connect layer */ |
1943 | if (!ufshcd_is_device_present(hba)) { | ||
1944 | dev_err(hba->dev, "%s: Device not present\n", __func__); | ||
1945 | ret = -ENXIO; | ||
1946 | goto out; | ||
1947 | } | ||
1948 | |||
1949 | /* Include any host controller configuration via UIC commands */ | ||
1950 | if (hba->vops && hba->vops->link_startup_notify) { | ||
1951 | ret = hba->vops->link_startup_notify(hba, POST_CHANGE); | ||
1952 | if (ret) | ||
1953 | goto out; | ||
1954 | } | ||
1936 | 1955 | ||
1956 | ret = ufshcd_make_hba_operational(hba); | ||
1937 | out: | 1957 | out: |
1938 | if (ret) | 1958 | if (ret) |
1939 | dev_err(hba->dev, "link startup failed %d\n", ret); | 1959 | dev_err(hba->dev, "link startup failed %d\n", ret); |
@@ -3173,6 +3193,61 @@ static struct scsi_host_template ufshcd_driver_template = { | |||
3173 | .can_queue = UFSHCD_CAN_QUEUE, | 3193 | .can_queue = UFSHCD_CAN_QUEUE, |
3174 | }; | 3194 | }; |
3175 | 3195 | ||
3196 | static int ufshcd_variant_hba_init(struct ufs_hba *hba) | ||
3197 | { | ||
3198 | int err = 0; | ||
3199 | |||
3200 | if (!hba->vops) | ||
3201 | goto out; | ||
3202 | |||
3203 | if (hba->vops->init) { | ||
3204 | err = hba->vops->init(hba); | ||
3205 | if (err) | ||
3206 | goto out; | ||
3207 | } | ||
3208 | |||
3209 | if (hba->vops->setup_clocks) { | ||
3210 | err = hba->vops->setup_clocks(hba, true); | ||
3211 | if (err) | ||
3212 | goto out_exit; | ||
3213 | } | ||
3214 | |||
3215 | if (hba->vops->setup_regulators) { | ||
3216 | err = hba->vops->setup_regulators(hba, true); | ||
3217 | if (err) | ||
3218 | goto out_clks; | ||
3219 | } | ||
3220 | |||
3221 | goto out; | ||
3222 | |||
3223 | out_clks: | ||
3224 | if (hba->vops->setup_clocks) | ||
3225 | hba->vops->setup_clocks(hba, false); | ||
3226 | out_exit: | ||
3227 | if (hba->vops->exit) | ||
3228 | hba->vops->exit(hba); | ||
3229 | out: | ||
3230 | if (err) | ||
3231 | dev_err(hba->dev, "%s: variant %s init failed err %d\n", | ||
3232 | __func__, hba->vops ? hba->vops->name : "", err); | ||
3233 | return err; | ||
3234 | } | ||
3235 | |||
3236 | static void ufshcd_variant_hba_exit(struct ufs_hba *hba) | ||
3237 | { | ||
3238 | if (!hba->vops) | ||
3239 | return; | ||
3240 | |||
3241 | if (hba->vops->setup_clocks) | ||
3242 | hba->vops->setup_clocks(hba, false); | ||
3243 | |||
3244 | if (hba->vops->setup_regulators) | ||
3245 | hba->vops->setup_regulators(hba, false); | ||
3246 | |||
3247 | if (hba->vops->exit) | ||
3248 | hba->vops->exit(hba); | ||
3249 | } | ||
3250 | |||
3176 | /** | 3251 | /** |
3177 | * ufshcd_suspend - suspend power management function | 3252 | * ufshcd_suspend - suspend power management function |
3178 | * @hba: per adapter instance | 3253 | * @hba: per adapter instance |
@@ -3257,6 +3332,8 @@ void ufshcd_remove(struct ufs_hba *hba) | |||
3257 | ufshcd_hba_stop(hba); | 3332 | ufshcd_hba_stop(hba); |
3258 | 3333 | ||
3259 | scsi_host_put(hba->host); | 3334 | scsi_host_put(hba->host); |
3335 | |||
3336 | ufshcd_variant_hba_exit(hba); | ||
3260 | } | 3337 | } |
3261 | EXPORT_SYMBOL_GPL(ufshcd_remove); | 3338 | EXPORT_SYMBOL_GPL(ufshcd_remove); |
3262 | 3339 | ||
@@ -3277,19 +3354,16 @@ static int ufshcd_set_dma_mask(struct ufs_hba *hba) | |||
3277 | } | 3354 | } |
3278 | 3355 | ||
3279 | /** | 3356 | /** |
3280 | * ufshcd_init - Driver initialization routine | 3357 | * ufshcd_alloc_host - allocate Host Bus Adapter (HBA) |
3281 | * @dev: pointer to device handle | 3358 | * @dev: pointer to device handle |
3282 | * @hba_handle: driver private handle | 3359 | * @hba_handle: driver private handle |
3283 | * @mmio_base: base register address | ||
3284 | * @irq: Interrupt line of device | ||
3285 | * Returns 0 on success, non-zero value on failure | 3360 | * Returns 0 on success, non-zero value on failure |
3286 | */ | 3361 | */ |
3287 | int ufshcd_init(struct device *dev, struct ufs_hba **hba_handle, | 3362 | int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle) |
3288 | void __iomem *mmio_base, unsigned int irq) | ||
3289 | { | 3363 | { |
3290 | struct Scsi_Host *host; | 3364 | struct Scsi_Host *host; |
3291 | struct ufs_hba *hba; | 3365 | struct ufs_hba *hba; |
3292 | int err; | 3366 | int err = 0; |
3293 | 3367 | ||
3294 | if (!dev) { | 3368 | if (!dev) { |
3295 | dev_err(dev, | 3369 | dev_err(dev, |
@@ -3298,13 +3372,6 @@ int ufshcd_init(struct device *dev, struct ufs_hba **hba_handle, | |||
3298 | goto out_error; | 3372 | goto out_error; |
3299 | } | 3373 | } |
3300 | 3374 | ||
3301 | if (!mmio_base) { | ||
3302 | dev_err(dev, | ||
3303 | "Invalid memory reference for mmio_base is NULL\n"); | ||
3304 | err = -ENODEV; | ||
3305 | goto out_error; | ||
3306 | } | ||
3307 | |||
3308 | host = scsi_host_alloc(&ufshcd_driver_template, | 3375 | host = scsi_host_alloc(&ufshcd_driver_template, |
3309 | sizeof(struct ufs_hba)); | 3376 | sizeof(struct ufs_hba)); |
3310 | if (!host) { | 3377 | if (!host) { |
@@ -3315,9 +3382,40 @@ int ufshcd_init(struct device *dev, struct ufs_hba **hba_handle, | |||
3315 | hba = shost_priv(host); | 3382 | hba = shost_priv(host); |
3316 | hba->host = host; | 3383 | hba->host = host; |
3317 | hba->dev = dev; | 3384 | hba->dev = dev; |
3385 | *hba_handle = hba; | ||
3386 | |||
3387 | out_error: | ||
3388 | return err; | ||
3389 | } | ||
3390 | EXPORT_SYMBOL(ufshcd_alloc_host); | ||
3391 | |||
3392 | /** | ||
3393 | * ufshcd_init - Driver initialization routine | ||
3394 | * @hba: per-adapter instance | ||
3395 | * @mmio_base: base register address | ||
3396 | * @irq: Interrupt line of device | ||
3397 | * Returns 0 on success, non-zero value on failure | ||
3398 | */ | ||
3399 | int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) | ||
3400 | { | ||
3401 | int err; | ||
3402 | struct Scsi_Host *host = hba->host; | ||
3403 | struct device *dev = hba->dev; | ||
3404 | |||
3405 | if (!mmio_base) { | ||
3406 | dev_err(hba->dev, | ||
3407 | "Invalid memory reference for mmio_base is NULL\n"); | ||
3408 | err = -ENODEV; | ||
3409 | goto out_error; | ||
3410 | } | ||
3411 | |||
3318 | hba->mmio_base = mmio_base; | 3412 | hba->mmio_base = mmio_base; |
3319 | hba->irq = irq; | 3413 | hba->irq = irq; |
3320 | 3414 | ||
3415 | err = ufshcd_variant_hba_init(hba); | ||
3416 | if (err) | ||
3417 | goto out_error; | ||
3418 | |||
3321 | /* Read capabilities registers */ | 3419 | /* Read capabilities registers */ |
3322 | ufshcd_hba_capabilities(hba); | 3420 | ufshcd_hba_capabilities(hba); |
3323 | 3421 | ||
@@ -3395,8 +3493,6 @@ int ufshcd_init(struct device *dev, struct ufs_hba **hba_handle, | |||
3395 | goto out_remove_scsi_host; | 3493 | goto out_remove_scsi_host; |
3396 | } | 3494 | } |
3397 | 3495 | ||
3398 | *hba_handle = hba; | ||
3399 | |||
3400 | /* Hold auto suspend until async scan completes */ | 3496 | /* Hold auto suspend until async scan completes */ |
3401 | pm_runtime_get_sync(dev); | 3497 | pm_runtime_get_sync(dev); |
3402 | 3498 | ||
@@ -3408,6 +3504,7 @@ out_remove_scsi_host: | |||
3408 | scsi_remove_host(hba->host); | 3504 | scsi_remove_host(hba->host); |
3409 | out_disable: | 3505 | out_disable: |
3410 | scsi_host_put(host); | 3506 | scsi_host_put(host); |
3507 | ufshcd_variant_hba_exit(hba); | ||
3411 | out_error: | 3508 | out_error: |
3412 | return err; | 3509 | return err; |
3413 | } | 3510 | } |
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index acf318e338ed..8c6bec05283e 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h | |||
@@ -68,6 +68,8 @@ | |||
68 | #define UFSHCD "ufshcd" | 68 | #define UFSHCD "ufshcd" |
69 | #define UFSHCD_DRIVER_VERSION "0.2" | 69 | #define UFSHCD_DRIVER_VERSION "0.2" |
70 | 70 | ||
71 | struct ufs_hba; | ||
72 | |||
71 | enum dev_cmd_type { | 73 | enum dev_cmd_type { |
72 | DEV_CMD_TYPE_NOP = 0x0, | 74 | DEV_CMD_TYPE_NOP = 0x0, |
73 | DEV_CMD_TYPE_QUERY = 0x1, | 75 | DEV_CMD_TYPE_QUERY = 0x1, |
@@ -152,6 +154,30 @@ struct ufs_dev_cmd { | |||
152 | struct ufs_query query; | 154 | struct ufs_query query; |
153 | }; | 155 | }; |
154 | 156 | ||
157 | #define PRE_CHANGE 0 | ||
158 | #define POST_CHANGE 1 | ||
159 | /** | ||
160 | * struct ufs_hba_variant_ops - variant specific callbacks | ||
161 | * @name: variant name | ||
162 | * @init: called when the driver is initialized | ||
163 | * @exit: called to cleanup everything done in init | ||
164 | * @setup_clocks: called before touching any of the controller registers | ||
165 | * @setup_regulators: called before accessing the host controller | ||
166 | * @hce_enable_notify: called before and after HCE enable bit is set to allow | ||
167 | * variant specific Uni-Pro initialization. | ||
168 | * @link_startup_notify: called before and after Link startup is carried out | ||
169 | * to allow variant specific Uni-Pro initialization. | ||
170 | */ | ||
171 | struct ufs_hba_variant_ops { | ||
172 | const char *name; | ||
173 | int (*init)(struct ufs_hba *); | ||
174 | void (*exit)(struct ufs_hba *); | ||
175 | int (*setup_clocks)(struct ufs_hba *, bool); | ||
176 | int (*setup_regulators)(struct ufs_hba *, bool); | ||
177 | int (*hce_enable_notify)(struct ufs_hba *, bool); | ||
178 | int (*link_startup_notify)(struct ufs_hba *, bool); | ||
179 | }; | ||
180 | |||
155 | /** | 181 | /** |
156 | * struct ufs_hba - per adapter private structure | 182 | * struct ufs_hba - per adapter private structure |
157 | * @mmio_base: UFSHCI base register address | 183 | * @mmio_base: UFSHCI base register address |
@@ -171,6 +197,8 @@ struct ufs_dev_cmd { | |||
171 | * @nutrs: Transfer Request Queue depth supported by controller | 197 | * @nutrs: Transfer Request Queue depth supported by controller |
172 | * @nutmrs: Task Management Queue depth supported by controller | 198 | * @nutmrs: Task Management Queue depth supported by controller |
173 | * @ufs_version: UFS Version to which controller complies | 199 | * @ufs_version: UFS Version to which controller complies |
200 | * @vops: pointer to variant specific operations | ||
201 | * @priv: pointer to variant specific private data | ||
174 | * @irq: Irq number of the controller | 202 | * @irq: Irq number of the controller |
175 | * @active_uic_cmd: handle of active UIC command | 203 | * @active_uic_cmd: handle of active UIC command |
176 | * @uic_cmd_mutex: mutex for uic command | 204 | * @uic_cmd_mutex: mutex for uic command |
@@ -218,6 +246,8 @@ struct ufs_hba { | |||
218 | int nutrs; | 246 | int nutrs; |
219 | int nutmrs; | 247 | int nutmrs; |
220 | u32 ufs_version; | 248 | u32 ufs_version; |
249 | struct ufs_hba_variant_ops *vops; | ||
250 | void *priv; | ||
221 | unsigned int irq; | 251 | unsigned int irq; |
222 | 252 | ||
223 | struct uic_command *active_uic_cmd; | 253 | struct uic_command *active_uic_cmd; |
@@ -256,8 +286,8 @@ struct ufs_hba { | |||
256 | #define ufshcd_readl(hba, reg) \ | 286 | #define ufshcd_readl(hba, reg) \ |
257 | readl((hba)->mmio_base + (reg)) | 287 | readl((hba)->mmio_base + (reg)) |
258 | 288 | ||
259 | int ufshcd_init(struct device *, struct ufs_hba ** , void __iomem * , | 289 | int ufshcd_alloc_host(struct device *, struct ufs_hba **); |
260 | unsigned int); | 290 | int ufshcd_init(struct ufs_hba * , void __iomem * , unsigned int); |
261 | void ufshcd_remove(struct ufs_hba *); | 291 | void ufshcd_remove(struct ufs_hba *); |
262 | 292 | ||
263 | /** | 293 | /** |