* [PATCH V3 1/4] [SCSI] drivers/scsi/ufs: Seggregate PCI Specific Code
2012-07-26 8:42 [PATCH V3 0/4] [SCSI] ufs: Adds glue drivers to ufshcd Vinayak Holikatti
@ 2012-07-26 8:42 ` Vinayak Holikatti
2012-08-01 14:38 ` Arnd Bergmann
2012-07-26 8:42 ` [PATCH V3 2/4] [SCSI] drivers/scsi/ufs: Separate PCI code into glue driver Vinayak Holikatti
` (4 subsequent siblings)
5 siblings, 1 reply; 13+ messages in thread
From: Vinayak Holikatti @ 2012-07-26 8:42 UTC (permalink / raw)
To: James.Bottomley
Cc: linux-scsi, linux-kernel, patches, linux-samsung-soc, arnd,
girish.shivananjappa, saugata.das, vishak.g, venkat, k.rajesh,
dsaxena, ilho215.lee, nala.la, sreekumar.c, Vinayak Holikatti,
Santosh Yaraganavi
This patch seggregates the PCI specific code in ufshcd.c to make it
ready for splitting into core ufs driver and PCI glue driver.
Reviewed-by: Namjae Jeon <linkinjeon@gmail.com>
Signed-off-by: Vinayak Holikatti <vinholikatti@gmail.com>
Signed-off-by: Santosh Yaraganavi <santoshsy@gmail.com>
---
drivers/scsi/ufs/ufshcd.c | 277 ++++++++++++++++++++++++---------------------
1 file changed, 150 insertions(+), 127 deletions(-)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 6a4fd00..c7b8f4b 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -129,7 +129,7 @@ struct uic_command {
* @utrdl_dma_addr: UTRDL DMA address
* @utmrdl_dma_addr: UTMRDL DMA address
* @host: Scsi_Host instance of the driver
- * @pdev: PCI device handle
+ * @dev: device handle
* @lrb: local reference block
* @outstanding_tasks: Bits representing outstanding task requests
* @outstanding_reqs: Bits representing outstanding transfer requests
@@ -159,7 +159,7 @@ struct ufs_hba {
dma_addr_t utmrdl_dma_addr;
struct Scsi_Host *host;
- struct pci_dev *pdev;
+ struct device *dev;
struct ufshcd_lrb *lrb;
@@ -335,21 +335,21 @@ static inline void ufshcd_free_hba_memory(struct ufs_hba *hba)
if (hba->utmrdl_base_addr) {
utmrdl_size = sizeof(struct utp_task_req_desc) * hba->nutmrs;
- dma_free_coherent(&hba->pdev->dev, utmrdl_size,
+ dma_free_coherent(hba->dev, utmrdl_size,
hba->utmrdl_base_addr, hba->utmrdl_dma_addr);
}
if (hba->utrdl_base_addr) {
utrdl_size =
(sizeof(struct utp_transfer_req_desc) * hba->nutrs);
- dma_free_coherent(&hba->pdev->dev, utrdl_size,
+ dma_free_coherent(hba->dev, utrdl_size,
hba->utrdl_base_addr, hba->utrdl_dma_addr);
}
if (hba->ucdl_base_addr) {
ucdl_size =
(sizeof(struct utp_transfer_cmd_desc) * hba->nutrs);
- dma_free_coherent(&hba->pdev->dev, ucdl_size,
+ dma_free_coherent(hba->dev, ucdl_size,
hba->ucdl_base_addr, hba->ucdl_dma_addr);
}
}
@@ -724,7 +724,7 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba)
/* Allocate memory for UTP command descriptors */
ucdl_size = (sizeof(struct utp_transfer_cmd_desc) * hba->nutrs);
- hba->ucdl_base_addr = dma_alloc_coherent(&hba->pdev->dev,
+ hba->ucdl_base_addr = dma_alloc_coherent(hba->dev,
ucdl_size,
&hba->ucdl_dma_addr,
GFP_KERNEL);
@@ -737,7 +737,7 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba)
*/
if (!hba->ucdl_base_addr ||
WARN_ON(hba->ucdl_dma_addr & (PAGE_SIZE - 1))) {
- dev_err(&hba->pdev->dev,
+ dev_err(hba->dev,
"Command Descriptor Memory allocation failed\n");
goto out;
}
@@ -747,13 +747,13 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba)
* UFSHCI requires 1024 byte alignment of UTRD
*/
utrdl_size = (sizeof(struct utp_transfer_req_desc) * hba->nutrs);
- hba->utrdl_base_addr = dma_alloc_coherent(&hba->pdev->dev,
+ hba->utrdl_base_addr = dma_alloc_coherent(hba->dev,
utrdl_size,
&hba->utrdl_dma_addr,
GFP_KERNEL);
if (!hba->utrdl_base_addr ||
WARN_ON(hba->utrdl_dma_addr & (PAGE_SIZE - 1))) {
- dev_err(&hba->pdev->dev,
+ dev_err(hba->dev,
"Transfer Descriptor Memory allocation failed\n");
goto out;
}
@@ -763,13 +763,13 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba)
* UFSHCI requires 1024 byte alignment of UTMRD
*/
utmrdl_size = sizeof(struct utp_task_req_desc) * hba->nutmrs;
- hba->utmrdl_base_addr = dma_alloc_coherent(&hba->pdev->dev,
+ hba->utmrdl_base_addr = dma_alloc_coherent(hba->dev,
utmrdl_size,
&hba->utmrdl_dma_addr,
GFP_KERNEL);
if (!hba->utmrdl_base_addr ||
WARN_ON(hba->utmrdl_dma_addr & (PAGE_SIZE - 1))) {
- dev_err(&hba->pdev->dev,
+ dev_err(hba->dev,
"Task Management Descriptor Memory allocation failed\n");
goto out;
}
@@ -777,7 +777,7 @@ static int ufshcd_memory_alloc(struct ufs_hba *hba)
/* Allocate memory for local reference block */
hba->lrb = kcalloc(hba->nutrs, sizeof(struct ufshcd_lrb), GFP_KERNEL);
if (!hba->lrb) {
- dev_err(&hba->pdev->dev, "LRB Memory allocation failed\n");
+ dev_err(hba->dev, "LRB Memory allocation failed\n");
goto out;
}
return 0;
@@ -867,7 +867,7 @@ static int ufshcd_dme_link_startup(struct ufs_hba *hba)
/* check if controller is ready to accept UIC commands */
if (((readl(hba->mmio_base + REG_CONTROLLER_STATUS)) &
UIC_COMMAND_READY) == 0x0) {
- dev_err(&hba->pdev->dev,
+ dev_err(hba->dev,
"Controller not ready"
" to accept UIC commands\n");
return -EIO;
@@ -912,7 +912,7 @@ static int ufshcd_make_hba_operational(struct ufs_hba *hba)
/* check if device present */
reg = readl((hba->mmio_base + REG_CONTROLLER_STATUS));
if (ufshcd_is_device_present(reg)) {
- dev_err(&hba->pdev->dev, "cc: Device not present\n");
+ dev_err(hba->dev, "cc: Device not present\n");
err = -ENXIO;
goto out;
}
@@ -924,7 +924,7 @@ static int ufshcd_make_hba_operational(struct ufs_hba *hba)
if (!(ufshcd_get_lists_status(reg))) {
ufshcd_enable_run_stop_reg(hba);
} else {
- dev_err(&hba->pdev->dev,
+ dev_err(hba->dev,
"Host controller not ready to process requests");
err = -EIO;
goto out;
@@ -1005,7 +1005,7 @@ static int ufshcd_hba_enable(struct ufs_hba *hba)
if (retry) {
retry--;
} else {
- dev_err(&hba->pdev->dev,
+ dev_err(hba->dev,
"Controller enable failed\n");
return -EIO;
}
@@ -1084,7 +1084,7 @@ static int ufshcd_do_reset(struct ufs_hba *hba)
/* start the initialization process */
if (ufshcd_initialize_hba(hba)) {
- dev_err(&hba->pdev->dev,
+ dev_err(hba->dev,
"Reset: Controller initialization failed\n");
return FAILED;
}
@@ -1165,7 +1165,7 @@ static int ufshcd_task_req_compl(struct ufs_hba *hba, u32 index)
task_result = FAILED;
} else {
task_result = FAILED;
- dev_err(&hba->pdev->dev,
+ dev_err(hba->dev,
"trc: Invalid ocs = %x\n", ocs_value);
}
spin_unlock_irqrestore(hba->host->host_lock, flags);
@@ -1279,7 +1279,7 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
/* check if the returned transfer response is valid */
result = ufshcd_is_valid_req_rsp(lrbp->ucd_rsp_ptr);
if (result) {
- dev_err(&hba->pdev->dev,
+ dev_err(hba->dev,
"Invalid response = %x\n", result);
break;
}
@@ -1308,7 +1308,7 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
case OCS_FATAL_ERROR:
default:
result |= DID_ERROR << 16;
- dev_err(&hba->pdev->dev,
+ dev_err(hba->dev,
"OCS error from controller = %x\n", ocs);
break;
} /* end of switch */
@@ -1372,7 +1372,7 @@ static void ufshcd_uic_cc_handler (struct work_struct *work)
!(ufshcd_get_uic_cmd_result(hba))) {
if (ufshcd_make_hba_operational(hba))
- dev_err(&hba->pdev->dev,
+ dev_err(hba->dev,
"cc: hba not operational state\n");
return;
}
@@ -1507,7 +1507,7 @@ ufshcd_issue_tm_cmd(struct ufs_hba *hba,
free_slot = ufshcd_get_tm_free_slot(hba);
if (free_slot >= hba->nutmrs) {
spin_unlock_irqrestore(host->host_lock, flags);
- dev_err(&hba->pdev->dev, "Task management queue full\n");
+ dev_err(hba->dev, "Task management queue full\n");
err = FAILED;
goto out;
}
@@ -1550,7 +1550,7 @@ ufshcd_issue_tm_cmd(struct ufs_hba *hba,
&hba->tm_condition) != 0),
60 * HZ);
if (!err) {
- dev_err(&hba->pdev->dev,
+ dev_err(hba->dev,
"Task management command timed-out\n");
err = FAILED;
goto out;
@@ -1686,23 +1686,23 @@ static struct scsi_host_template ufshcd_driver_template = {
};
/**
- * ufshcd_shutdown - main function to put the controller in reset state
+ * ufshcd_pci_shutdown - main function to put the controller in reset state
* @pdev: pointer to PCI device handle
*/
-static void ufshcd_shutdown(struct pci_dev *pdev)
+static void ufshcd_pci_shutdown(struct pci_dev *pdev)
{
ufshcd_hba_stop((struct ufs_hba *)pci_get_drvdata(pdev));
}
#ifdef CONFIG_PM
/**
- * ufshcd_suspend - suspend power management function
+ * ufshcd_pci_suspend - suspend power management function
* @pdev: pointer to PCI device handle
* @state: power state
*
* Returns -ENOSYS
*/
-static int ufshcd_suspend(struct pci_dev *pdev, pm_message_t state)
+static int ufshcd_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{
/*
* TODO:
@@ -1717,12 +1717,12 @@ static int ufshcd_suspend(struct pci_dev *pdev, pm_message_t state)
}
/**
- * ufshcd_resume - resume power management function
+ * ufshcd_pci_resume - resume power management function
* @pdev: pointer to PCI device handle
*
* Returns -ENOSYS
*/
-static int ufshcd_resume(struct pci_dev *pdev)
+static int ufshcd_pci_resume(struct pci_dev *pdev)
{
/*
* TODO:
@@ -1746,27 +1746,38 @@ static void ufshcd_hba_free(struct ufs_hba *hba)
{
iounmap(hba->mmio_base);
ufshcd_free_hba_memory(hba);
- pci_release_regions(hba->pdev);
}
/**
- * ufshcd_remove - de-allocate PCI/SCSI host and host memory space
+ * ufshcd_remove - de-allocate SCSI host and host memory space
* data structure memory
- * @pdev - pointer to PCI handle
+ * @hba - per adapter instance
*/
-static void ufshcd_remove(struct pci_dev *pdev)
+void ufshcd_remove(struct ufs_hba *hba)
{
- struct ufs_hba *hba = pci_get_drvdata(pdev);
-
/* disable interrupts */
ufshcd_int_config(hba, UFSHCD_INT_DISABLE);
- free_irq(pdev->irq, hba);
ufshcd_hba_stop(hba);
ufshcd_hba_free(hba);
scsi_remove_host(hba->host);
scsi_host_put(hba->host);
+}
+EXPORT_SYMBOL(ufshcd_remove);
+
+/**
+ * ufshcd_pci_remove - de-allocate PCI/SCSI host and host memory space
+ * data structure memory
+ * @pdev - pointer to PCI handle
+ */
+static void ufshcd_pci_remove(struct pci_dev *pdev)
+{
+ struct ufs_hba *hba = pci_get_drvdata(pdev);
+
+ free_irq(pdev->irq, hba);
+ ufshcd_remove(hba);
+ pci_release_regions(pdev);
pci_set_drvdata(pdev, NULL);
pci_clear_master(pdev);
pci_disable_device(pdev);
@@ -1779,75 +1790,52 @@ static void ufshcd_remove(struct pci_dev *pdev)
*
* Returns 0 for success, non-zero for failure
*/
-static int ufshcd_set_dma_mask(struct ufs_hba *hba)
+static int ufshcd_set_dma_mask(struct pci_dev *pdev)
{
int err;
- u64 dma_mask;
-
- /*
- * If controller supports 64 bit addressing mode, then set the DMA
- * mask to 64-bit, else set the DMA mask to 32-bit
- */
- if (hba->capabilities & MASK_64_ADDRESSING_SUPPORT)
- dma_mask = DMA_BIT_MASK(64);
- else
- dma_mask = DMA_BIT_MASK(32);
-
- err = pci_set_dma_mask(hba->pdev, dma_mask);
- if (err)
- return err;
-
- err = pci_set_consistent_dma_mask(hba->pdev, dma_mask);
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
+ && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
+ return 0;
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ if (!err)
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
return err;
}
/**
- * ufshcd_probe - probe routine of the driver
- * @pdev: pointer to PCI device handle
- * @id: PCI device id
- *
+ * ufshcd_init - Driver initialization routine
+ * @dev: pointer to device handle
+ * @hba_handle: driver private handle
+ * @mmio_base: base register address
+ * @irq_line: Interrupt line of device
* Returns 0 on success, non-zero value on failure
*/
-static int __devinit
-ufshcd_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+int ufshcd_init(struct device *dev, struct ufs_hba **hba_handle,
+ void __iomem *mmio_base, unsigned int irq_line)
{
struct Scsi_Host *host;
struct ufs_hba *hba;
int err;
- err = pci_enable_device(pdev);
- if (err) {
- dev_err(&pdev->dev, "pci_enable_device failed\n");
+ if (!dev && !mmio_base) {
+ dev_err(dev,
+ "Invalid memory reference for dev or mmio_base NULL\n");
+ err = -ENODEV;
goto out_error;
}
- pci_set_master(pdev);
-
host = scsi_host_alloc(&ufshcd_driver_template,
sizeof(struct ufs_hba));
if (!host) {
- dev_err(&pdev->dev, "scsi_host_alloc failed\n");
+ dev_err(dev, "scsi_host_alloc failed\n");
err = -ENOMEM;
- goto out_disable;
+ goto out_error;
}
hba = shost_priv(host);
-
- err = pci_request_regions(pdev, UFSHCD);
- if (err < 0) {
- dev_err(&pdev->dev, "request regions failed\n");
- goto out_host_put;
- }
-
- hba->mmio_base = pci_ioremap_bar(pdev, 0);
- if (!hba->mmio_base) {
- dev_err(&pdev->dev, "memory map failed\n");
- err = -ENOMEM;
- goto out_release_regions;
- }
-
hba->host = host;
- hba->pdev = pdev;
+ hba->dev = dev;
+ hba->mmio_base = mmio_base;
/* Read capabilities registers */
ufshcd_hba_capabilities(hba);
@@ -1855,17 +1843,11 @@ ufshcd_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* Get UFS version supported by the controller */
hba->ufs_version = ufshcd_get_ufs_version(hba);
- err = ufshcd_set_dma_mask(hba);
- if (err) {
- dev_err(&pdev->dev, "set dma mask failed\n");
- goto out_iounmap;
- }
-
/* Allocate memory for host memory space */
err = ufshcd_memory_alloc(hba);
if (err) {
- dev_err(&pdev->dev, "Memory allocation failed\n");
- goto out_iounmap;
+ dev_err(hba->dev, "Memory allocation failed\n");
+ goto out_disable;
}
/* Configure LRB */
@@ -1887,46 +1869,104 @@ ufshcd_probe(struct pci_dev *pdev, const struct pci_device_id *id)
INIT_WORK(&hba->feh_workq, ufshcd_fatal_err_handler);
/* IRQ registration */
- err = request_irq(pdev->irq, ufshcd_intr, IRQF_SHARED, UFSHCD, hba);
+ err = request_irq(irq_line, ufshcd_intr, IRQF_SHARED, UFSHCD, hba);
if (err) {
- dev_err(&pdev->dev, "request irq failed\n");
+ dev_err(hba->dev, "request irq failed\n");
goto out_lrb_free;
}
/* Enable SCSI tag mapping */
err = scsi_init_shared_tag_map(host, host->can_queue);
if (err) {
- dev_err(&pdev->dev, "init shared queue failed\n");
+ dev_err(hba->dev, "init shared queue failed\n");
goto out_free_irq;
}
- pci_set_drvdata(pdev, hba);
-
- err = scsi_add_host(host, &pdev->dev);
+ err = scsi_add_host(host, hba->dev);
if (err) {
- dev_err(&pdev->dev, "scsi_add_host failed\n");
+ dev_err(hba->dev, "scsi_add_host failed\n");
goto out_free_irq;
}
/* Initialization routine */
err = ufshcd_initialize_hba(hba);
if (err) {
- dev_err(&pdev->dev, "Initialization failed\n");
- goto out_free_irq;
+ dev_err(hba->dev, "Initialization failed\n");
+ goto out_remove_scsi_host;
}
+ *hba_handle = hba;
return 0;
+out_remove_scsi_host:
+ scsi_remove_host(hba->host);
out_free_irq:
- free_irq(pdev->irq, hba);
+ free_irq(irq_line, hba);
out_lrb_free:
ufshcd_free_hba_memory(hba);
+out_disable:
+ scsi_host_put(host);
+out_error:
+ return err;
+}
+EXPORT_SYMBOL(ufshcd_init);
+
+/**
+ * ufshcd_pci_probe - probe routine of the driver
+ * @pdev: pointer to PCI device handle
+ * @id: PCI device id
+ *
+ * Returns 0 on success, non-zero value on failure
+ */
+static int __devinit
+ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ struct ufs_hba *hba;
+ void __iomem *mmio_base;
+ int err;
+
+ err = pci_enable_device(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "pci_enable_device failed\n");
+ goto out_error;
+ }
+
+ pci_set_master(pdev);
+
+ err = pci_request_regions(pdev, UFSHCD);
+ if (err < 0) {
+ dev_err(&pdev->dev, "request regions failed\n");
+ goto out_disable;
+ }
+
+ mmio_base = pci_ioremap_bar(pdev, 0);
+ if (!mmio_base) {
+ dev_err(&pdev->dev, "memory map failed\n");
+ err = -ENOMEM;
+ goto out_release_regions;
+ }
+
+ err = ufshcd_set_dma_mask(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "set dma mask failed\n");
+ goto out_iounmap;
+ }
+
+ err = ufshcd_init(&pdev->dev, &hba, mmio_base, pdev->irq);
+ if (err) {
+ dev_err(&pdev->dev, "%s:%d %sInitialization failed\n",
+ __FILE__, __LINE__, __func__);
+ goto out_iounmap;
+ }
+
+ pci_set_drvdata(pdev, hba);
+
+ return 0;
+
out_iounmap:
- iounmap(hba->mmio_base);
+ iounmap(mmio_base);
out_release_regions:
pci_release_regions(pdev);
-out_host_put:
- scsi_host_put(host);
out_disable:
pci_clear_master(pdev);
pci_disable_device(pdev);
@@ -1944,36 +1984,19 @@ MODULE_DEVICE_TABLE(pci, ufshcd_pci_tbl);
static struct pci_driver ufshcd_pci_driver = {
.name = UFSHCD,
.id_table = ufshcd_pci_tbl,
- .probe = ufshcd_probe,
- .remove = __devexit_p(ufshcd_remove),
- .shutdown = ufshcd_shutdown,
+ .probe = ufshcd_pci_probe,
+ .remove = __devexit_p(ufshcd_pci_remove),
+ .shutdown = ufshcd_pci_shutdown,
#ifdef CONFIG_PM
- .suspend = ufshcd_suspend,
- .resume = ufshcd_resume,
+ .suspend = ufshcd_pci_suspend,
+ .resume = ufshcd_pci_resume,
#endif
};
-/**
- * ufshcd_init - Driver registration routine
- */
-static int __init ufshcd_init(void)
-{
- return pci_register_driver(&ufshcd_pci_driver);
-}
-module_init(ufshcd_init);
-
-/**
- * ufshcd_exit - Driver exit clean-up routine
- */
-static void __exit ufshcd_exit(void)
-{
- pci_unregister_driver(&ufshcd_pci_driver);
-}
-module_exit(ufshcd_exit);
-
+module_pci_driver(ufshcd_pci_driver);
-MODULE_AUTHOR("Santosh Yaragnavi <santosh.sy@samsung.com>, "
- "Vinayak Holikatti <h.vinayak@samsung.com>");
+MODULE_AUTHOR("Santosh Yaragnavi <santosh.sy@samsung.com>");
+MODULE_AUTHOR("Vinayak Holikatti <h.vinayak@samsung.com>");
MODULE_DESCRIPTION("Generic UFS host controller driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(UFSHCD_DRIVER_VERSION);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH V3 1/4] [SCSI] drivers/scsi/ufs: Seggregate PCI Specific Code
2012-07-26 8:42 ` [PATCH V3 1/4] [SCSI] drivers/scsi/ufs: Seggregate PCI Specific Code Vinayak Holikatti
@ 2012-08-01 14:38 ` Arnd Bergmann
2012-08-04 14:45 ` vinayak holikatti
0 siblings, 1 reply; 13+ messages in thread
From: Arnd Bergmann @ 2012-08-01 14:38 UTC (permalink / raw)
To: Vinayak Holikatti
Cc: James.Bottomley, linux-scsi, linux-kernel, patches,
linux-samsung-soc, arnd, girish.shivananjappa, saugata.das,
vishak.g, venkat, k.rajesh, dsaxena, ilho215.lee, nala.la,
sreekumar.c, Santosh Yaraganavi
On Thursday 26 July 2012, Vinayak Holikatti wrote:
> -static void ufshcd_remove(struct pci_dev *pdev)
> +void ufshcd_remove(struct ufs_hba *hba)
> {
> - struct ufs_hba *hba = pci_get_drvdata(pdev);
> -
> /* disable interrupts */
> ufshcd_int_config(hba, UFSHCD_INT_DISABLE);
> - free_irq(pdev->irq, hba);
>
> ufshcd_hba_stop(hba);
> ufshcd_hba_free(hba);
>
> scsi_remove_host(hba->host);
> scsi_host_put(hba->host);
> +}
> +EXPORT_SYMBOL(ufshcd_remove);
For driver internal symbols, you should always use "EXPORT_SYMBOL_GPL"
here.
Arnd
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH V3 1/4] [SCSI] drivers/scsi/ufs: Seggregate PCI Specific Code
2012-08-01 14:38 ` Arnd Bergmann
@ 2012-08-04 14:45 ` vinayak holikatti
0 siblings, 0 replies; 13+ messages in thread
From: vinayak holikatti @ 2012-08-04 14:45 UTC (permalink / raw)
To: Arnd Bergmann
Cc: James.Bottomley, linux-scsi, linux-kernel, patches,
linux-samsung-soc, arnd, girish.shivananjappa, saugata.das,
vishak.g, venkat, k.rajesh, dsaxena, ilho215.lee, nala.la,
sreekumar.c, Santosh Yaraganavi
On Wed, Aug 1, 2012 at 8:08 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Thursday 26 July 2012, Vinayak Holikatti wrote:
>
>> -static void ufshcd_remove(struct pci_dev *pdev)
>> +void ufshcd_remove(struct ufs_hba *hba)
>> {
>> - struct ufs_hba *hba = pci_get_drvdata(pdev);
>> -
>> /* disable interrupts */
>> ufshcd_int_config(hba, UFSHCD_INT_DISABLE);
>> - free_irq(pdev->irq, hba);
>>
>> ufshcd_hba_stop(hba);
>> ufshcd_hba_free(hba);
>>
>> scsi_remove_host(hba->host);
>> scsi_host_put(hba->host);
>> +}
>> +EXPORT_SYMBOL(ufshcd_remove);
>
> For driver internal symbols, you should always use "EXPORT_SYMBOL_GPL"
> here.
Ok, will use EXPORT_SYMBOL_GPL
>
> Arnd
>
--
Regards,
Vinayak Holikatti
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH V3 2/4] [SCSI] drivers/scsi/ufs: Separate PCI code into glue driver
2012-07-26 8:42 [PATCH V3 0/4] [SCSI] ufs: Adds glue drivers to ufshcd Vinayak Holikatti
2012-07-26 8:42 ` [PATCH V3 1/4] [SCSI] drivers/scsi/ufs: Seggregate PCI Specific Code Vinayak Holikatti
@ 2012-07-26 8:42 ` Vinayak Holikatti
2012-08-01 14:43 ` Arnd Bergmann
2012-07-26 8:42 ` [PATCH V3 3/4] [SCSI] ufs: Add Platform glue driver for ufshcd Vinayak Holikatti
` (3 subsequent siblings)
5 siblings, 1 reply; 13+ messages in thread
From: Vinayak Holikatti @ 2012-07-26 8:42 UTC (permalink / raw)
To: James.Bottomley
Cc: linux-scsi, linux-kernel, patches, linux-samsung-soc, arnd,
girish.shivananjappa, saugata.das, vishak.g, venkat, k.rajesh,
dsaxena, ilho215.lee, nala.la, sreekumar.c, Vinayak Holikatti,
Santosh Yaraganavi
This patch separates PCI code from ufshcd.c and makes it as a
core driver module and adds a new file ufshcd-pci.c as PCI glue
driver.
Reviewed-by: Namjae Jeon <linkinjeon@gmail.com>
Signed-off-by: Vinayak Holikatti <vinholikatti@gmail.com>
Signed-off-by: Santosh Yaraganavi <santoshsy@gmail.com>
---
drivers/scsi/ufs/Kconfig | 26 ++-
drivers/scsi/ufs/Makefile | 1 +
drivers/scsi/ufs/ufshcd-pci.c | 228 ++++++++++++++++++++++++++
drivers/scsi/ufs/ufshcd.c | 329 ++------------------------------------
drivers/scsi/ufs/ufshcd.h | 206 ++++++++++++++++++++++++
drivers/scsi/ufs/ufshcd_common.h | 53 ++++++
6 files changed, 521 insertions(+), 322 deletions(-)
create mode 100644 drivers/scsi/ufs/ufshcd-pci.c
create mode 100644 drivers/scsi/ufs/ufshcd.h
create mode 100644 drivers/scsi/ufs/ufshcd_common.h
diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
index 8f27f9d..265a8c8 100644
--- a/drivers/scsi/ufs/Kconfig
+++ b/drivers/scsi/ufs/Kconfig
@@ -43,7 +43,27 @@
# USA.
config SCSI_UFSHCD
- tristate "Universal Flash Storage host controller driver"
- depends on PCI && SCSI
+ tristate "Universal Flash Storage Controller Driver Core"
+ depends on SCSI
---help---
- This is a generic driver which supports PCIe UFS Host controllers.
+ This selects the support for UFS devices in Linux, say Y and make
+ sure that you know the name of your UFS host adapter (the card
+ inside your computer that "speaks" the UFS protocol, also
+ called UFS Host Controller), because you will be asked for it.
+ The module will be called ufshcd.
+
+ To compile this driver as a module, choose M here and read
+ <file:Documentation/scsi/ufs.txt>.
+ However, do not compile this as a module if your root file system
+ (the one containing the directory /) is located on a UFS device.
+
+config SCSI_UFSHCD_PCI
+ tristate "PCI bus based UFS Controller support"
+ depends on SCSI_UFSHCD && PCI
+ ---help---
+ This selects the PCI UFS Host Controller Interface.
+ Most controllers found today are PCI devices.
+
+ If you have a controller with this interface, say Y or M here.
+
+ If unsure, say N.
diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile
index adf7895..9eda0df 100644
--- a/drivers/scsi/ufs/Makefile
+++ b/drivers/scsi/ufs/Makefile
@@ -1,2 +1,3 @@
# UFSHCD makefile
obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o
+obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o
diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c
new file mode 100644
index 0000000..d078744
--- /dev/null
+++ b/drivers/scsi/ufs/ufshcd-pci.c
@@ -0,0 +1,228 @@
+/*
+ * Universal Flash Storage Host controller driver
+ *
+ * This code is based on drivers/scsi/ufs/ufshcd-pci.c
+ * Copyright (C) 2011-2012 Samsung India Software Operations
+ *
+ * Santosh Yaraganavi <santosh.sy@samsung.com>
+ * Vinayak Holikatti <h.vinayak@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * NO WARRANTY
+ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+ * solely responsible for determining the appropriateness of using and
+ * distributing the Program and assumes all risks associated with its
+ * exercise of rights under this Agreement, including but not limited to
+ * the risks and costs of program errors, damage to or loss of data,
+ * programs or equipment, and unavailability or interruption of operations.
+
+ * DISCLAIMER OF LIABILITY
+ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+#include "ufshcd.h"
+#include "ufshcd_common.h"
+#include <linux/pci.h>
+
+#ifdef CONFIG_PM
+/**
+ * ufshcd_pci_suspend - suspend power management function
+ * @pdev: pointer to PCI device handle
+ * @state: power state
+ *
+ * Returns -ENOSYS
+ */
+static int ufshcd_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ /*
+ * TODO:
+ * 1. Block SCSI requests from SCSI midlayer
+ * 2. Change the internal driver state to non operational
+ * 3. Set UTRLRSR and UTMRLRSR bits to zero
+ * 4. Wait until outstanding commands are completed
+ * 5. Set HCE to zero to send the UFS host controller to reset state
+ */
+
+ return -ENOSYS;
+}
+
+/**
+ * ufshcd_pci_resume - resume power management function
+ * @pdev: pointer to PCI device handle
+ *
+ * Returns -ENOSYS
+ */
+static int ufshcd_pci_resume(struct pci_dev *pdev)
+{
+ /*
+ * TODO:
+ * 1. Set HCE to 1, to start the UFS host controller
+ * initialization process
+ * 2. Set UTRLRSR and UTMRLRSR bits to 1
+ * 3. Change the internal driver state to operational
+ * 4. Unblock SCSI requests from SCSI midlayer
+ */
+
+ return -ENOSYS;
+}
+#endif /* CONFIG_PM */
+
+/**
+ * ufshcd_pci_shutdown - main function to put the controller in reset state
+ * @pdev: pointer to PCI device handle
+ */
+static void ufshcd_pci_shutdown(struct pci_dev *pdev)
+{
+ ufshcd_hba_stop((struct ufs_hba *)pci_get_drvdata(pdev));
+}
+
+/**
+ * ufshcd_pci_remove - de-allocate PCI/SCSI host and host memory space
+ * data structure memory
+ * @pdev - pointer to PCI handle
+ */
+static void ufshcd_pci_remove(struct pci_dev *pdev)
+{
+ struct ufs_hba *hba = pci_get_drvdata(pdev);
+
+ free_irq(pdev->irq, hba);
+ ufshcd_remove(hba);
+ pci_release_regions(pdev);
+ pci_set_drvdata(pdev, NULL);
+ pci_clear_master(pdev);
+ pci_disable_device(pdev);
+}
+
+/**
+ * ufshcd_set_dma_mask - Set dma mask based on the controller
+ * addressing capability
+ * @pdev: PCI device structure
+ *
+ * Returns 0 for success, non-zero for failure
+ */
+static int ufshcd_set_dma_mask(struct pci_dev *pdev)
+{
+ int err;
+
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
+ && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
+ return 0;
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ if (!err)
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+ return err;
+}
+
+/**
+ * ufshcd_pci_probe - probe routine of the driver
+ * @pdev: pointer to PCI device handle
+ * @id: PCI device id
+ *
+ * Returns 0 on success, non-zero value on failure
+ */
+static int __devinit
+ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ struct ufs_hba *hba;
+ void __iomem *mmio_base;
+ int err;
+
+ err = pci_enable_device(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "pci_enable_device failed\n");
+ goto out_error;
+ }
+
+ pci_set_master(pdev);
+
+
+ err = pci_request_regions(pdev, UFSHCD);
+ if (err < 0) {
+ dev_err(&pdev->dev, "request regions failed\n");
+ goto out_disable;
+ }
+
+ mmio_base = pci_ioremap_bar(pdev, 0);
+ if (!mmio_base) {
+ dev_err(&pdev->dev, "memory map failed\n");
+ err = -ENOMEM;
+ goto out_release_regions;
+ }
+
+ err = ufshcd_set_dma_mask(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "set dma mask failed\n");
+ goto out_iounmap;
+ }
+
+ err = ufshcd_init(&pdev->dev, &hba, mmio_base, pdev->irq);
+ if (err) {
+ dev_err(&pdev->dev, "%s:%d %sInitialization failed\n",
+ __FILE__, __LINE__, __func__);
+ goto out_iounmap;
+ }
+
+ pci_set_drvdata(pdev, hba);
+
+ return 0;
+
+out_iounmap:
+ iounmap(mmio_base);
+out_release_regions:
+ pci_release_regions(pdev);
+out_disable:
+ pci_clear_master(pdev);
+ pci_disable_device(pdev);
+out_error:
+ return err;
+}
+
+static DEFINE_PCI_DEVICE_TABLE(ufshcd_pci_tbl) = {
+ { PCI_VENDOR_ID_SAMSUNG, 0xC00C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ { } /* terminate list */
+};
+
+MODULE_DEVICE_TABLE(pci, ufshcd_pci_tbl);
+
+static struct pci_driver ufshcd_pci_driver = {
+ .name = UFSHCD,
+ .id_table = ufshcd_pci_tbl,
+ .probe = ufshcd_pci_probe,
+ .remove = __devexit_p(ufshcd_pci_remove),
+ .shutdown = ufshcd_pci_shutdown,
+#ifdef CONFIG_PM
+ .suspend = ufshcd_pci_suspend,
+ .resume = ufshcd_pci_resume,
+#endif
+};
+
+module_pci_driver(ufshcd_pci_driver);
+
+MODULE_AUTHOR("Santosh Yaragnavi <santosh.sy@samsung.com>");
+MODULE_AUTHOR("Vinayak Holikatti <h.vinayak@samsung.com>");
+MODULE_DESCRIPTION("PCI based UFS host controller driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(UFSHCD_DRIVER_VERSION);
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index c7b8f4b..dfc3e85 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -43,35 +43,7 @@
* USA.
*/
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/workqueue.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/wait.h>
-#include <linux/bitops.h>
-
-#include <asm/irq.h>
-#include <asm/byteorder.h>
-#include <scsi/scsi.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_host.h>
-#include <scsi/scsi_tcq.h>
-#include <scsi/scsi_dbg.h>
-#include <scsi/scsi_eh.h>
-
-#include "ufs.h"
-#include "ufshci.h"
-
-#define UFSHCD "ufshcd"
-#define UFSHCD_DRIVER_VERSION "0.1"
+#include "ufshcd.h"
enum {
UFSHCD_MAX_CHANNEL = 0,
@@ -102,121 +74,6 @@ enum {
};
/**
- * struct uic_command - UIC command structure
- * @command: UIC command
- * @argument1: UIC command argument 1
- * @argument2: UIC command argument 2
- * @argument3: UIC command argument 3
- * @cmd_active: Indicate if UIC command is outstanding
- * @result: UIC command result
- */
-struct uic_command {
- u32 command;
- u32 argument1;
- u32 argument2;
- u32 argument3;
- int cmd_active;
- int result;
-};
-
-/**
- * struct ufs_hba - per adapter private structure
- * @mmio_base: UFSHCI base register address
- * @ucdl_base_addr: UFS Command Descriptor base address
- * @utrdl_base_addr: UTP Transfer Request Descriptor base address
- * @utmrdl_base_addr: UTP Task Management Descriptor base address
- * @ucdl_dma_addr: UFS Command Descriptor DMA address
- * @utrdl_dma_addr: UTRDL DMA address
- * @utmrdl_dma_addr: UTMRDL DMA address
- * @host: Scsi_Host instance of the driver
- * @dev: device handle
- * @lrb: local reference block
- * @outstanding_tasks: Bits representing outstanding task requests
- * @outstanding_reqs: Bits representing outstanding transfer requests
- * @capabilities: UFS Controller Capabilities
- * @nutrs: Transfer Request Queue depth supported by controller
- * @nutmrs: Task Management Queue depth supported by controller
- * @active_uic_cmd: handle of active UIC command
- * @ufshcd_tm_wait_queue: wait queue for task management
- * @tm_condition: condition variable for task management
- * @ufshcd_state: UFSHCD states
- * @int_enable_mask: Interrupt Mask Bits
- * @uic_workq: Work queue for UIC completion handling
- * @feh_workq: Work queue for fatal controller error handling
- * @errors: HBA errors
- */
-struct ufs_hba {
- void __iomem *mmio_base;
-
- /* Virtual memory reference */
- struct utp_transfer_cmd_desc *ucdl_base_addr;
- struct utp_transfer_req_desc *utrdl_base_addr;
- struct utp_task_req_desc *utmrdl_base_addr;
-
- /* DMA memory reference */
- dma_addr_t ucdl_dma_addr;
- dma_addr_t utrdl_dma_addr;
- dma_addr_t utmrdl_dma_addr;
-
- struct Scsi_Host *host;
- struct device *dev;
-
- struct ufshcd_lrb *lrb;
-
- unsigned long outstanding_tasks;
- unsigned long outstanding_reqs;
-
- u32 capabilities;
- int nutrs;
- int nutmrs;
- u32 ufs_version;
-
- struct uic_command active_uic_cmd;
- wait_queue_head_t ufshcd_tm_wait_queue;
- unsigned long tm_condition;
-
- u32 ufshcd_state;
- u32 int_enable_mask;
-
- /* Work Queues */
- struct work_struct uic_workq;
- struct work_struct feh_workq;
-
- /* HBA Errors */
- u32 errors;
-};
-
-/**
- * struct ufshcd_lrb - local reference block
- * @utr_descriptor_ptr: UTRD address of the command
- * @ucd_cmd_ptr: UCD address of the command
- * @ucd_rsp_ptr: Response UPIU address for this command
- * @ucd_prdt_ptr: PRDT address of the command
- * @cmd: pointer to SCSI command
- * @sense_buffer: pointer to sense buffer address of the SCSI command
- * @sense_bufflen: Length of the sense buffer
- * @scsi_status: SCSI status of the command
- * @command_type: SCSI, UFS, Query.
- * @task_tag: Task tag of the command
- * @lun: LUN of the command
- */
-struct ufshcd_lrb {
- struct utp_transfer_req_desc *utr_descriptor_ptr;
- struct utp_upiu_cmd *ucd_cmd_ptr;
- struct utp_upiu_rsp *ucd_rsp_ptr;
- struct ufshcd_sg_entry *ucd_prdt_ptr;
-
- struct scsi_cmnd *cmd;
- u8 *sense_buffer;
- unsigned int sense_bufflen;
- int scsi_status;
-
- int command_type;
- int task_tag;
- unsigned int lun;
-};
-
-/**
* ufshcd_get_ufs_version - Get the UFS version supported by the HBA
* @hba - Pointer to adapter instance
*
@@ -429,15 +286,6 @@ static void ufshcd_enable_run_stop_reg(struct ufs_hba *hba)
}
/**
- * ufshcd_hba_stop - Send controller to reset state
- * @hba: per adapter instance
- */
-static inline void ufshcd_hba_stop(struct ufs_hba *hba)
-{
- writel(CONTROLLER_DISABLE, (hba->mmio_base + REG_CONTROLLER_ENABLE));
-}
-
-/**
* ufshcd_hba_start - Start controller initialization sequence
* @hba: per adapter instance
*/
@@ -1685,57 +1533,6 @@ static struct scsi_host_template ufshcd_driver_template = {
.can_queue = UFSHCD_CAN_QUEUE,
};
-/**
- * ufshcd_pci_shutdown - main function to put the controller in reset state
- * @pdev: pointer to PCI device handle
- */
-static void ufshcd_pci_shutdown(struct pci_dev *pdev)
-{
- ufshcd_hba_stop((struct ufs_hba *)pci_get_drvdata(pdev));
-}
-
-#ifdef CONFIG_PM
-/**
- * ufshcd_pci_suspend - suspend power management function
- * @pdev: pointer to PCI device handle
- * @state: power state
- *
- * Returns -ENOSYS
- */
-static int ufshcd_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- /*
- * TODO:
- * 1. Block SCSI requests from SCSI midlayer
- * 2. Change the internal driver state to non operational
- * 3. Set UTRLRSR and UTMRLRSR bits to zero
- * 4. Wait until outstanding commands are completed
- * 5. Set HCE to zero to send the UFS host controller to reset state
- */
-
- return -ENOSYS;
-}
-
-/**
- * ufshcd_pci_resume - resume power management function
- * @pdev: pointer to PCI device handle
- *
- * Returns -ENOSYS
- */
-static int ufshcd_pci_resume(struct pci_dev *pdev)
-{
- /*
- * TODO:
- * 1. Set HCE to 1, to start the UFS host controller
- * initialization process
- * 2. Set UTRLRSR and UTMRLRSR bits to 1
- * 3. Change the internal driver state to operational
- * 4. Unblock SCSI requests from SCSI midlayer
- */
-
- return -ENOSYS;
-}
-#endif /* CONFIG_PM */
/**
* ufshcd_hba_free - free allocated memory for
@@ -1767,43 +1564,6 @@ void ufshcd_remove(struct ufs_hba *hba)
EXPORT_SYMBOL(ufshcd_remove);
/**
- * ufshcd_pci_remove - de-allocate PCI/SCSI host and host memory space
- * data structure memory
- * @pdev - pointer to PCI handle
- */
-static void ufshcd_pci_remove(struct pci_dev *pdev)
-{
- struct ufs_hba *hba = pci_get_drvdata(pdev);
-
- free_irq(pdev->irq, hba);
- ufshcd_remove(hba);
- pci_release_regions(pdev);
- pci_set_drvdata(pdev, NULL);
- pci_clear_master(pdev);
- pci_disable_device(pdev);
-}
-
-/**
- * ufshcd_set_dma_mask - Set dma mask based on the controller
- * addressing capability
- * @pdev: PCI device structure
- *
- * Returns 0 for success, non-zero for failure
- */
-static int ufshcd_set_dma_mask(struct pci_dev *pdev)
-{
- int err;
-
- if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
- && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
- return 0;
- err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
- if (!err)
- err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
- return err;
-}
-
-/**
* ufshcd_init - Driver initialization routine
* @dev: pointer to device handle
* @hba_handle: driver private handle
@@ -1911,92 +1671,23 @@ out_error:
}
EXPORT_SYMBOL(ufshcd_init);
-/**
- * ufshcd_pci_probe - probe routine of the driver
- * @pdev: pointer to PCI device handle
- * @id: PCI device id
- *
- * Returns 0 on success, non-zero value on failure
- */
-static int __devinit
-ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+static int __init ufshcd_module_init(void)
{
- struct ufs_hba *hba;
- void __iomem *mmio_base;
- int err;
-
- err = pci_enable_device(pdev);
- if (err) {
- dev_err(&pdev->dev, "pci_enable_device failed\n");
- goto out_error;
- }
-
- pci_set_master(pdev);
-
- err = pci_request_regions(pdev, UFSHCD);
- if (err < 0) {
- dev_err(&pdev->dev, "request regions failed\n");
- goto out_disable;
- }
-
- mmio_base = pci_ioremap_bar(pdev, 0);
- if (!mmio_base) {
- dev_err(&pdev->dev, "memory map failed\n");
- err = -ENOMEM;
- goto out_release_regions;
- }
-
- err = ufshcd_set_dma_mask(pdev);
- if (err) {
- dev_err(&pdev->dev, "set dma mask failed\n");
- goto out_iounmap;
- }
-
- err = ufshcd_init(&pdev->dev, &hba, mmio_base, pdev->irq);
- if (err) {
- dev_err(&pdev->dev, "%s:%d %sInitialization failed\n",
- __FILE__, __LINE__, __func__);
- goto out_iounmap;
- }
-
- pci_set_drvdata(pdev, hba);
-
+ pr_info("UFS Host Driver Core loaded\n");
return 0;
-
-out_iounmap:
- iounmap(mmio_base);
-out_release_regions:
- pci_release_regions(pdev);
-out_disable:
- pci_clear_master(pdev);
- pci_disable_device(pdev);
-out_error:
- return err;
}
-static DEFINE_PCI_DEVICE_TABLE(ufshcd_pci_tbl) = {
- { PCI_VENDOR_ID_SAMSUNG, 0xC00C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { } /* terminate list */
-};
+static void __exit ufshcd_module_exit(void)
+{
+ pr_info("UFS Host Driver Core unloaded\n");
+}
-MODULE_DEVICE_TABLE(pci, ufshcd_pci_tbl);
-
-static struct pci_driver ufshcd_pci_driver = {
- .name = UFSHCD,
- .id_table = ufshcd_pci_tbl,
- .probe = ufshcd_pci_probe,
- .remove = __devexit_p(ufshcd_pci_remove),
- .shutdown = ufshcd_pci_shutdown,
-#ifdef CONFIG_PM
- .suspend = ufshcd_pci_suspend,
- .resume = ufshcd_pci_resume,
-#endif
-};
+module_init(ufshcd_module_init);
+module_exit(ufshcd_module_exit);
-module_pci_driver(ufshcd_pci_driver);
MODULE_AUTHOR("Santosh Yaragnavi <santosh.sy@samsung.com>");
MODULE_AUTHOR("Vinayak Holikatti <h.vinayak@samsung.com>");
-MODULE_DESCRIPTION("Generic UFS host controller driver");
+MODULE_DESCRIPTION("Generic Core UFS host controller driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(UFSHCD_DRIVER_VERSION);
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
new file mode 100644
index 0000000..40cb1f7
--- /dev/null
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -0,0 +1,206 @@
+/*
+ * Universal Flash Storage Host controller driver
+ *
+ * This code is based on drivers/scsi/ufs/ufshcd.h
+ * Copyright (C) 2011-2012 Samsung India Software Operations
+ *
+ * Santosh Yaraganavi <santosh.sy@samsung.com>
+ * Vinayak Holikatti <h.vinayak@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * NO WARRANTY
+ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+ * solely responsible for determining the appropriateness of using and
+ * distributing the Program and assumes all risks associated with its
+ * exercise of rights under this Agreement, including but not limited to
+ * the risks and costs of program errors, damage to or loss of data,
+ * programs or equipment, and unavailability or interruption of operations.
+
+ * DISCLAIMER OF LIABILITY
+ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+#ifndef _UFSHCD_H
+#define _UFSHCD_H
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/bitops.h>
+#include <linux/pm_runtime.h>
+#include <linux/clk.h>
+
+#include <asm/irq.h>
+#include <asm/byteorder.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_dbg.h>
+#include <scsi/scsi_eh.h>
+
+#include "ufs.h"
+#include "ufshci.h"
+
+#define UFSHCD "ufshcd"
+#define UFSHCD_DRIVER_VERSION "0.2"
+
+/**
+ * struct uic_command - UIC command structure
+ * @command: UIC command
+ * @argument1: UIC command argument 1
+ * @argument2: UIC command argument 2
+ * @argument3: UIC command argument 3
+ * @cmd_active: Indicate if UIC command is outstanding
+ * @result: UIC command result
+ */
+struct uic_command {
+ u32 command;
+ u32 argument1;
+ u32 argument2;
+ u32 argument3;
+ int cmd_active;
+ int result;
+};
+
+/**
+ * struct ufshcd_lrb - local reference block
+ * @utr_descriptor_ptr: UTRD address of the command
+ * @ucd_cmd_ptr: UCD address of the command
+ * @ucd_rsp_ptr: Response UPIU address for this command
+ * @ucd_prdt_ptr: PRDT address of the command
+ * @cmd: pointer to SCSI command
+ * @sense_buffer: pointer to sense buffer address of the SCSI command
+ * @sense_bufflen: Length of the sense buffer
+ * @scsi_status: SCSI status of the command
+ * @command_type: SCSI, UFS, Query.
+ * @task_tag: Task tag of the command
+ * @lun: LUN of the command
+ */
+struct ufshcd_lrb {
+ struct utp_transfer_req_desc *utr_descriptor_ptr;
+ struct utp_upiu_cmd *ucd_cmd_ptr;
+ struct utp_upiu_rsp *ucd_rsp_ptr;
+ struct ufshcd_sg_entry *ucd_prdt_ptr;
+
+ struct scsi_cmnd *cmd;
+ u8 *sense_buffer;
+ unsigned int sense_bufflen;
+ int scsi_status;
+
+ int command_type;
+ int task_tag;
+ unsigned int lun;
+};
+
+
+/**
+ * struct ufs_hba - per adapter private structure
+ * @mmio_base: UFSHCI base register address
+ * @ucdl_base_addr: UFS Command Descriptor base address
+ * @utrdl_base_addr: UTP Transfer Request Descriptor base address
+ * @utmrdl_base_addr: UTP Task Management Descriptor base address
+ * @ucdl_dma_addr: UFS Command Descriptor DMA address
+ * @utrdl_dma_addr: UTRDL DMA address
+ * @utmrdl_dma_addr: UTMRDL DMA address
+ * @host: Scsi_Host instance of the driver
+ * @dev: device handle
+ * @lrb: local reference block
+ * @outstanding_tasks: Bits representing outstanding task requests
+ * @outstanding_reqs: Bits representing outstanding transfer requests
+ * @capabilities: UFS Controller Capabilities
+ * @nutrs: Transfer Request Queue depth supported by controller
+ * @nutmrs: Task Management Queue depth supported by controller
+ * @active_uic_cmd: handle of active UIC command
+ * @ufshcd_tm_wait_queue: wait queue for task management
+ * @tm_condition: condition variable for task management
+ * @ufshcd_state: UFSHCD states
+ * @int_enable_mask: Interrupt Mask Bits
+ * @uic_workq: Work queue for UIC completion handling
+ * @feh_workq: Work queue for fatal controller error handling
+ * @errors: HBA errors
+ */
+struct ufs_hba {
+ void __iomem *mmio_base;
+
+ /* Virtual memory reference */
+ struct utp_transfer_cmd_desc *ucdl_base_addr;
+ struct utp_transfer_req_desc *utrdl_base_addr;
+ struct utp_task_req_desc *utmrdl_base_addr;
+
+ /* DMA memory reference */
+ dma_addr_t ucdl_dma_addr;
+ dma_addr_t utrdl_dma_addr;
+ dma_addr_t utmrdl_dma_addr;
+
+ struct Scsi_Host *host;
+ struct device *dev;
+
+ struct ufshcd_lrb *lrb;
+
+ unsigned long outstanding_tasks;
+ unsigned long outstanding_reqs;
+
+ u32 capabilities;
+ int nutrs;
+ int nutmrs;
+ unsigned int irq;
+ u32 ufs_version;
+
+ struct uic_command active_uic_cmd;
+ wait_queue_head_t ufshcd_tm_wait_queue;
+ unsigned long tm_condition;
+
+ u32 ufshcd_state;
+ u32 int_enable_mask;
+
+ /* Work Queues */
+ struct work_struct uic_workq;
+ struct work_struct feh_workq;
+
+ /* HBA Errors */
+ u32 errors;
+};
+
+/**
+ * ufshcd_hba_stop - Send controller to reset state
+ * @hba: per adapter instance
+ */
+static inline void ufshcd_hba_stop(struct ufs_hba *hba)
+{
+ writel(CONTROLLER_DISABLE, (hba->mmio_base + REG_CONTROLLER_ENABLE));
+}
+
+#endif /* End of Header */
diff --git a/drivers/scsi/ufs/ufshcd_common.h b/drivers/scsi/ufs/ufshcd_common.h
new file mode 100644
index 0000000..e027727
--- /dev/null
+++ b/drivers/scsi/ufs/ufshcd_common.h
@@ -0,0 +1,53 @@
+/*
+ * Universal Flash Storage Host controller driver
+ *
+ * This code is based on drivers/scsi/ufs/ufshcd_common.h
+ * Copyright (C) 2011-2012 Samsung India Software Operations
+ *
+ * Santosh Yaraganavi <santosh.sy@samsung.com>
+ * Vinayak Holikatti <h.vinayak@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * NO WARRANTY
+ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+ * solely responsible for determining the appropriateness of using and
+ * distributing the Program and assumes all risks associated with its
+ * exercise of rights under this Agreement, including but not limited to
+ * the risks and costs of program errors, damage to or loss of data,
+ * programs or equipment, and unavailability or interruption of operations.
+
+ * DISCLAIMER OF LIABILITY
+ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+#ifndef _UFSHCD_COMMON_H
+#define _UFSHCD_COMMON_H
+
+extern int ufshcd_init(struct device *, struct ufs_hba ** , void __iomem * ,
+ int);
+extern int ufshcd_remove(struct ufs_hba *);
+
+#endif /* END of Header */
--
1.7.9.5
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH V3 2/4] [SCSI] drivers/scsi/ufs: Separate PCI code into glue driver
2012-07-26 8:42 ` [PATCH V3 2/4] [SCSI] drivers/scsi/ufs: Separate PCI code into glue driver Vinayak Holikatti
@ 2012-08-01 14:43 ` Arnd Bergmann
0 siblings, 0 replies; 13+ messages in thread
From: Arnd Bergmann @ 2012-08-01 14:43 UTC (permalink / raw)
To: Vinayak Holikatti
Cc: James.Bottomley, linux-scsi, linux-kernel, patches,
linux-samsung-soc, arnd, girish.shivananjappa, saugata.das,
vishak.g, venkat, k.rajesh, dsaxena, ilho215.lee, nala.la,
sreekumar.c, Santosh Yaraganavi
On Thursday 26 July 2012, Vinayak Holikatti wrote:
> diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c
> new file mode 100644
> index 0000000..d078744
> --- /dev/null
> +++ b/drivers/scsi/ufs/ufshcd-pci.c
> @@ -0,0 +1,228 @@
> +/*
> + * Universal Flash Storage Host controller driver
> + *
> + * This code is based on drivers/scsi/ufs/ufshcd-pci.c
> + * Copyright (C) 2011-2012 Samsung India Software Operations
> + *
> + * Santosh Yaraganavi <santosh.sy@samsung.com>
> + * Vinayak Holikatti <h.vinayak@samsung.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * NO WARRANTY
> + * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
> + * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
> + * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
> + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
> + * solely responsible for determining the appropriateness of using and
> + * distributing the Program and assumes all risks associated with its
> + * exercise of rights under this Agreement, including but not limited to
> + * the risks and costs of program errors, damage to or loss of data,
> + * programs or equipment, and unavailability or interruption of operations.
> +
> + * DISCLAIMER OF LIABILITY
> + * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
> + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> + * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
> + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
> + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
> + * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
> + * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
It's a bit unusual to have three separate warranty disclaimers. Unless you've
specifically been asked to include all of them by your legal department to
do it like this, I would suggest you remove all but on of them.
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
> + * USA.
These statements also get outdated frequently when the FSF moves its
offices. We have the same thing in the global COPYING file of the kernel,
so most people don't carry their own copy.
> +static int __init ufshcd_module_init(void)
> {
> + pr_info("UFS Host Driver Core loaded\n");
> return 0;
> }
>
> +static void __exit ufshcd_module_exit(void)
> +{
> + pr_info("UFS Host Driver Core unloaded\n");
> +}
> +
> +module_init(ufshcd_module_init);
> +module_exit(ufshcd_module_exit);
The pr_info statements do not add any real value here. I would just drop
the module_init/module_exit functions entirely as they are not required.
Arnd
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH V3 3/4] [SCSI] ufs: Add Platform glue driver for ufshcd
2012-07-26 8:42 [PATCH V3 0/4] [SCSI] ufs: Adds glue drivers to ufshcd Vinayak Holikatti
2012-07-26 8:42 ` [PATCH V3 1/4] [SCSI] drivers/scsi/ufs: Seggregate PCI Specific Code Vinayak Holikatti
2012-07-26 8:42 ` [PATCH V3 2/4] [SCSI] drivers/scsi/ufs: Separate PCI code into glue driver Vinayak Holikatti
@ 2012-07-26 8:42 ` Vinayak Holikatti
2012-07-26 8:42 ` [PATCH V3 4/4] [SCSI] ufs: Correct the expected data transfer size Vinayak Holikatti
` (2 subsequent siblings)
5 siblings, 0 replies; 13+ messages in thread
From: Vinayak Holikatti @ 2012-07-26 8:42 UTC (permalink / raw)
To: James.Bottomley
Cc: linux-scsi, linux-kernel, patches, linux-samsung-soc, arnd,
girish.shivananjappa, saugata.das, vishak.g, venkat, k.rajesh,
dsaxena, ilho215.lee, nala.la, sreekumar.c, Vinayak Holikatti,
Santosh Yaraganavi
This patch adds Platform glue driver for ufshcd.
Reviewed-by: Namjae Jeon <linkinjeon@gmail.com>
Signed-off-by: Vinayak Holikatti <vinholikatti@gmail.com>
Signed-off-by: Santosh Yaraganavi <santoshsy@gmail.com>
---
drivers/scsi/ufs/Kconfig | 11 ++
drivers/scsi/ufs/Makefile | 1 +
drivers/scsi/ufs/ufshcd-pltfrm.c | 222 ++++++++++++++++++++++++++++++++++++++
3 files changed, 234 insertions(+)
create mode 100644 drivers/scsi/ufs/ufshcd-pltfrm.c
diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
index 265a8c8..8c06330 100644
--- a/drivers/scsi/ufs/Kconfig
+++ b/drivers/scsi/ufs/Kconfig
@@ -67,3 +67,14 @@ config SCSI_UFSHCD_PCI
If you have a controller with this interface, say Y or M here.
If unsure, say N.
+
+config SCSI_UFSHCD_PLATFORM
+ tristate "Platform based UFS Controller support"
+ depends on SCSI_UFSHCD
+ ---help---
+ This selects the UFS host controller support. If you have a
+ platform with UFS controller, say Y or M here.
+
+ If you have a controller with this interface, say Y or M here.
+
+ If unsure, say N.
diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile
index 9eda0df..1e5bd48 100644
--- a/drivers/scsi/ufs/Makefile
+++ b/drivers/scsi/ufs/Makefile
@@ -1,3 +1,4 @@
# UFSHCD makefile
obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o
obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o
+obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c
new file mode 100644
index 0000000..68e1675
--- /dev/null
+++ b/drivers/scsi/ufs/ufshcd-pltfrm.c
@@ -0,0 +1,222 @@
+/*
+ * Universal Flash Storage Host controller driver
+ *
+ * This code is based on drivers/scsi/ufs/ufshcd-pltfm.c
+ * Copyright (C) 2011-2012 Samsung India Software Operations
+ *
+ * Santosh Yaraganavi <santosh.sy@samsung.com>
+ * Vinayak Holikatti <h.vinayak@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * NO WARRANTY
+ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+ * solely responsible for determining the appropriateness of using and
+ * distributing the Program and assumes all risks associated with its
+ * exercise of rights under this Agreement, including but not limited to
+ * the risks and costs of program errors, damage to or loss of data,
+ * programs or equipment, and unavailability or interruption of operations.
+
+ * DISCLAIMER OF LIABILITY
+ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+#include "ufshcd.h"
+#include "ufshcd_common.h"
+#include <linux/platform_device.h>
+
+#ifdef CONFIG_PM
+/**
+ * ufshcd_pltfrm_suspend - suspend power management function
+ * @pdev: pointer to Platform device handle
+ * @mesg: power state
+ *
+ * Returns -ENOSYS
+ */
+static int ufshcd_pltfrm_suspend(struct platform_device *pdev,
+ pm_message_t mesg)
+{
+ /*
+ * TODO:
+ * 1. Block SCSI requests from SCSI midlayer
+ * 2. Change the internal driver state to non operational
+ * 3. Set UTRLRSR and UTMRLRSR bits to zero
+ * 4. Wait until outstanding commands are completed
+ * 5. Set HCE to zero to send the UFS host controller to reset state
+ */
+
+ return -ENOSYS;
+}
+
+/**
+ * ufshcd_pltfrm_resume - resume power management function
+ * @pdev: pointer to Platform device handle
+ *
+ * Returns -ENOSYS
+ */
+static int ufshcd_pltfrm_resume(struct platform_device *pdev)
+{
+ /*
+ * TODO:
+ * 1. Set HCE to 1, to start the UFS host controller
+ * initialization process
+ * 2. Set UTRLRSR and UTMRLRSR bits to 1
+ * 3. Change the internal driver state to operational
+ * 4. Unblock SCSI requests from SCSI midlayer
+ */
+
+ return -ENOSYS;
+}
+#endif
+
+/**
+ * ufshcd_pltfrm_probe - probe routine of the driver
+ * @pdev: pointer to Platform device handle
+ *
+ * Returns 0 on success, non-zero value on failure
+ */
+static int __devinit
+ufshcd_pltfrm_probe(struct platform_device *pdev)
+{
+ struct ufs_hba *hba;
+ void __iomem *mmio_base;
+ struct resource *mem_res;
+ struct resource *irq_res;
+ resource_size_t mem_size;
+ int err;
+ struct device *dev = &pdev->dev;
+
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem_res) {
+ dev_err(&pdev->dev,
+ "%s: Memory resource not available\n", __FILE__);
+ err = -ENODEV;
+ goto out_error;
+ }
+
+ mem_size = resource_size(mem_res);
+ if (!request_mem_region(mem_res->start, mem_size, "ufshcd")) {
+ dev_err(&pdev->dev,
+ "ufshcd: Cannot reserve the memory resource\n");
+ err = -EBUSY;
+ goto out_error;
+ }
+
+ mmio_base = ioremap_nocache(mem_res->start, mem_size);
+ if (!mmio_base) {
+ dev_err(&pdev->dev, "memory map failed\n");
+ err = -ENOMEM;
+ goto out_release_regions;
+ }
+
+ irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!irq_res) {
+ dev_err(&pdev->dev, "ufshcd: IRQ resource not available\n");
+ err = -ENODEV;
+ goto out_iounmap;
+ }
+
+ err = dma_set_coherent_mask(dev, dev->coherent_dma_mask);
+ if (err) {
+ dev_err(&pdev->dev, "set dma mask failed\n");
+ goto out_iounmap;
+ }
+
+ err = ufshcd_init(&pdev->dev, &hba, mmio_base, irq_res->start);
+ if (err) {
+ dev_err(&pdev->dev, "%s: Intialization failed\n",
+ __FILE__);
+ goto out_iounmap;
+ }
+
+ platform_set_drvdata(pdev, hba);
+
+ return 0;
+
+out_iounmap:
+ iounmap(mmio_base);
+out_release_regions:
+ release_mem_region(mem_res->start, mem_size);
+out_error:
+ return err;
+}
+
+/**
+ * ufshcd_pltfrm_remove - remove platform driver routine
+ * @pdev: pointer to platform device handle
+ *
+ * Returns 0 on success, non-zero value on failure
+ */
+static int __devexit ufshcd_pltfrm_remove(struct platform_device *pdev)
+{
+ struct resource *mem_res;
+ struct resource *irq_res;
+ resource_size_t mem_size;
+ struct ufs_hba *hba = platform_get_drvdata(pdev);
+
+ irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+
+ if (!irq_res)
+ dev_err(&pdev->dev, "ufshcd: IRQ resource not available\n");
+ else
+ free_irq(irq_res->start, hba);
+
+ ufshcd_remove(hba);
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem_res)
+ dev_err(&pdev->dev, "ufshcd: Memory resource not available\n");
+ else {
+ mem_size = resource_size(mem_res);
+ release_mem_region(mem_res->start, mem_size);
+ }
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+static const struct of_device_id ufs_of_match[] = {
+ { .compatible = "jedec,ufs-1.1"},
+};
+
+static struct platform_driver ufshcd_pltfrm_driver = {
+ .probe = ufshcd_pltfrm_probe,
+ .remove = __devexit_p(ufshcd_pltfrm_remove),
+#ifdef CONFIG_PM
+ .suspend = ufshcd_pltfrm_suspend,
+ .resume = ufshcd_pltfrm_resume,
+#endif
+ .driver = {
+ .name = "ufshcd",
+ .owner = THIS_MODULE,
+ .of_match_table = ufs_of_match,
+ },
+};
+
+module_platform_driver(ufshcd_pltfrm_driver);
+
+MODULE_AUTHOR("Santosh Yaragnavi <santosh.sy@samsung.com>");
+MODULE_AUTHOR("Vinayak Holikatti <h.vinayak@samsung.com>");
+MODULE_DESCRIPTION("Platform based UFS host controller driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(UFSHCD_DRIVER_VERSION);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH V3 4/4] [SCSI] ufs: Correct the expected data transfer size
2012-07-26 8:42 [PATCH V3 0/4] [SCSI] ufs: Adds glue drivers to ufshcd Vinayak Holikatti
` (2 preceding siblings ...)
2012-07-26 8:42 ` [PATCH V3 3/4] [SCSI] ufs: Add Platform glue driver for ufshcd Vinayak Holikatti
@ 2012-07-26 8:42 ` Vinayak Holikatti
2012-07-26 10:32 ` [PATCH V3 0/4] [SCSI] ufs: Adds glue drivers to ufshcd S, Venkatraman
2012-08-01 14:44 ` Arnd Bergmann
5 siblings, 0 replies; 13+ messages in thread
From: Vinayak Holikatti @ 2012-07-26 8:42 UTC (permalink / raw)
To: James.Bottomley
Cc: linux-scsi, linux-kernel, patches, linux-samsung-soc, arnd,
girish.shivananjappa, saugata.das, vishak.g, venkat, k.rajesh,
dsaxena, ilho215.lee, nala.la, sreekumar.c, Vinayak Holikatti,
Santosh Yaraganavi
This patch corrects the expected data transfer size of the
command UPIU. The current implementation of cmd->transfersize
is wrong as it probably equal to sector size. With this
implementation the transfer size is updated correctly
Reported-by: KOBAYASHI Yoshitake <yoshitake.kobayashi@toshiba.co.jp>
Reviewed-by: Namjae Jeon <linkinjeon@gmail.com>
Signed-off-by: Santosh Yaraganavi <santoshsy@gmail.com>
Signed-off-by: Vinayak Holikatti <vinholikatti@gmail.com>
---
drivers/scsi/ufs/ufshcd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index dfc3e85..5e732c3 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -488,7 +488,7 @@ static void ufshcd_compose_upiu(struct ufshcd_lrb *lrbp)
ucd_cmd_ptr->header.dword_2 = 0;
ucd_cmd_ptr->exp_data_transfer_len =
- cpu_to_be32(lrbp->cmd->transfersize);
+ cpu_to_be32(lrbp->cmd->sdb.length);
memcpy(ucd_cmd_ptr->cdb,
lrbp->cmd->cmnd,
--
1.7.9.5
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH V3 0/4] [SCSI] ufs: Adds glue drivers to ufshcd
2012-07-26 8:42 [PATCH V3 0/4] [SCSI] ufs: Adds glue drivers to ufshcd Vinayak Holikatti
` (3 preceding siblings ...)
2012-07-26 8:42 ` [PATCH V3 4/4] [SCSI] ufs: Correct the expected data transfer size Vinayak Holikatti
@ 2012-07-26 10:32 ` S, Venkatraman
2012-07-26 11:12 ` vinayak holikatti
2012-08-01 14:44 ` Arnd Bergmann
5 siblings, 1 reply; 13+ messages in thread
From: S, Venkatraman @ 2012-07-26 10:32 UTC (permalink / raw)
To: Vinayak Holikatti
Cc: James.Bottomley, linux-scsi, linux-kernel, patches,
linux-samsung-soc, arnd, girish.shivananjappa, saugata.das,
vishak.g, venkat, k.rajesh, dsaxena, ilho215.lee, nala.la,
sreekumar.c
On Thu, Jul 26, 2012 at 2:12 PM, Vinayak Holikatti
<vinholikatti@gmail.com> wrote:
> This patch set adds following features
> - Seggregate PCI specific code in ufshcd.c
> - Adds PCI glue driver ufshcd-pci.c and ufshcd.c become core module
> - Adds Platform glue driver ufshcd-pltfrm.c
> - Update correct transfer size in Command UPIU
>
> Vinayak Holikatti (4):
> [SCSI] drivers/scsi/ufs: Seggregate PCI Specific Code
> [SCSI] drivers/scsi/ufs: Separate PCI code into glue driver
> [SCSI] ufs: Add Platform glue driver for ufshcd
> [SCSI] ufs: Correct the expected data transfer size
>
> drivers/scsi/ufs/Kconfig | 37 +++-
> drivers/scsi/ufs/Makefile | 2 +
> drivers/scsi/ufs/ufshcd-pci.c | 228 ++++++++++++++++++++
> drivers/scsi/ufs/ufshcd-pltfrm.c | 222 ++++++++++++++++++++
> drivers/scsi/ufs/ufshcd.c | 422 ++++++--------------------------------
> drivers/scsi/ufs/ufshcd.h | 206 +++++++++++++++++++
> drivers/scsi/ufs/ufshcd_common.h | 53 +++++
> 7 files changed, 813 insertions(+), 357 deletions(-)
Two minor observations..
1) If both pci and platform have to do the exact same thing in their
_suspend() and _resume() routines, perhaps there is scope for making
them as common (the steps outlined in them should be done in core
ufshcd) ?
2) Need to include ufshcd_common.h in ufshcd.c so that the prototypes
are supplied for the exported functions.
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH V3 0/4] [SCSI] ufs: Adds glue drivers to ufshcd
2012-07-26 10:32 ` [PATCH V3 0/4] [SCSI] ufs: Adds glue drivers to ufshcd S, Venkatraman
@ 2012-07-26 11:12 ` vinayak holikatti
2012-07-26 11:35 ` S, Venkatraman
0 siblings, 1 reply; 13+ messages in thread
From: vinayak holikatti @ 2012-07-26 11:12 UTC (permalink / raw)
To: S, Venkatraman
Cc: James.Bottomley, linux-scsi, linux-kernel, patches,
linux-samsung-soc, arnd, girish.shivananjappa, saugata.das,
vishak.g, venkat, k.rajesh, dsaxena, ilho215.lee, nala.la,
sreekumar.c
On Thu, Jul 26, 2012 at 4:02 PM, S, Venkatraman <svenkatr@ti.com> wrote:
> On Thu, Jul 26, 2012 at 2:12 PM, Vinayak Holikatti
> <vinholikatti@gmail.com> wrote:
>> This patch set adds following features
>> - Seggregate PCI specific code in ufshcd.c
>> - Adds PCI glue driver ufshcd-pci.c and ufshcd.c become core module
>> - Adds Platform glue driver ufshcd-pltfrm.c
>> - Update correct transfer size in Command UPIU
>>
>> Vinayak Holikatti (4):
>> [SCSI] drivers/scsi/ufs: Seggregate PCI Specific Code
>> [SCSI] drivers/scsi/ufs: Separate PCI code into glue driver
>> [SCSI] ufs: Add Platform glue driver for ufshcd
>> [SCSI] ufs: Correct the expected data transfer size
>>
>> drivers/scsi/ufs/Kconfig | 37 +++-
>> drivers/scsi/ufs/Makefile | 2 +
>> drivers/scsi/ufs/ufshcd-pci.c | 228 ++++++++++++++++++++
>> drivers/scsi/ufs/ufshcd-pltfrm.c | 222 ++++++++++++++++++++
>> drivers/scsi/ufs/ufshcd.c | 422 ++++++--------------------------------
>> drivers/scsi/ufs/ufshcd.h | 206 +++++++++++++++++++
>> drivers/scsi/ufs/ufshcd_common.h | 53 +++++
>> 7 files changed, 813 insertions(+), 357 deletions(-)
>
> Two minor observations..
> 1) If both pci and platform have to do the exact same thing in their
> _suspend() and _resume() routines, perhaps there is scope for making
> them as common (the steps outlined in them should be done in core
> ufshcd) ?
Both will not have to do the exact same thing. We have plan to implement
ufshcd_suspend and ufshcd_resume which will be generic and will be part
of ufshcd core, as you said.
>
> 2) Need to include ufshcd_common.h in ufshcd.c so that the prototypes
> are supplied for the exported functions.
Thank you, I will make necessary changes in next version of patches.
--
Regards,
Vinayak Holikatti
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH V3 0/4] [SCSI] ufs: Adds glue drivers to ufshcd
2012-07-26 11:12 ` vinayak holikatti
@ 2012-07-26 11:35 ` S, Venkatraman
2012-07-26 11:44 ` vinayak holikatti
0 siblings, 1 reply; 13+ messages in thread
From: S, Venkatraman @ 2012-07-26 11:35 UTC (permalink / raw)
To: vinayak holikatti
Cc: James.Bottomley, linux-scsi, linux-kernel, patches,
linux-samsung-soc, arnd, girish.shivananjappa, saugata.das,
vishak.g, venkat, k.rajesh, dsaxena, ilho215.lee, nala.la,
sreekumar.c
On Thu, Jul 26, 2012 at 4:42 PM, vinayak holikatti
<vinholikatti@gmail.com> wrote:
> On Thu, Jul 26, 2012 at 4:02 PM, S, Venkatraman <svenkatr@ti.com> wrote:
>> On Thu, Jul 26, 2012 at 2:12 PM, Vinayak Holikatti
>> <vinholikatti@gmail.com> wrote:
>>> This patch set adds following features
>>> - Seggregate PCI specific code in ufshcd.c
>>> - Adds PCI glue driver ufshcd-pci.c and ufshcd.c become core module
>>> - Adds Platform glue driver ufshcd-pltfrm.c
>>> - Update correct transfer size in Command UPIU
>>>
>>> Vinayak Holikatti (4):
>>> [SCSI] drivers/scsi/ufs: Seggregate PCI Specific Code
>>> [SCSI] drivers/scsi/ufs: Separate PCI code into glue driver
>>> [SCSI] ufs: Add Platform glue driver for ufshcd
>>> [SCSI] ufs: Correct the expected data transfer size
>>>
>>> drivers/scsi/ufs/Kconfig | 37 +++-
>>> drivers/scsi/ufs/Makefile | 2 +
>>> drivers/scsi/ufs/ufshcd-pci.c | 228 ++++++++++++++++++++
>>> drivers/scsi/ufs/ufshcd-pltfrm.c | 222 ++++++++++++++++++++
>>> drivers/scsi/ufs/ufshcd.c | 422 ++++++--------------------------------
>>> drivers/scsi/ufs/ufshcd.h | 206 +++++++++++++++++++
>>> drivers/scsi/ufs/ufshcd_common.h | 53 +++++
>>> 7 files changed, 813 insertions(+), 357 deletions(-)
>>
>> Two minor observations..
>> 1) If both pci and platform have to do the exact same thing in their
>> _suspend() and _resume() routines, perhaps there is scope for making
>> them as common (the steps outlined in them should be done in core
>> ufshcd) ?
> Both will not have to do the exact same thing. We have plan to implement
> ufshcd_suspend and ufshcd_resume which will be generic and will be part
> of ufshcd core, as you said.
Thanks. The comments in the driver files don't reflect this; it'd be
wise to create
the placeholder for core_suspend()/resume() in ufshcd.c, instead of
the platform drivers.
>>
>> 2) Need to include ufshcd_common.h in ufshcd.c so that the prototypes
>> are supplied for the exported functions.
> Thank you, I will make necessary changes in next version of patches.
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH V3 0/4] [SCSI] ufs: Adds glue drivers to ufshcd
2012-07-26 11:35 ` S, Venkatraman
@ 2012-07-26 11:44 ` vinayak holikatti
0 siblings, 0 replies; 13+ messages in thread
From: vinayak holikatti @ 2012-07-26 11:44 UTC (permalink / raw)
To: S, Venkatraman
Cc: James.Bottomley, linux-scsi, linux-kernel, patches,
linux-samsung-soc, arnd, girish.shivananjappa, saugata.das,
vishak.g, venkat, k.rajesh, dsaxena, ilho215.lee, nala.la,
sreekumar.c
On Thu, Jul 26, 2012 at 5:05 PM, S, Venkatraman <svenkatr@ti.com> wrote:
> On Thu, Jul 26, 2012 at 4:42 PM, vinayak holikatti
> <vinholikatti@gmail.com> wrote:
>> On Thu, Jul 26, 2012 at 4:02 PM, S, Venkatraman <svenkatr@ti.com> wrote:
>>> On Thu, Jul 26, 2012 at 2:12 PM, Vinayak Holikatti
>>> <vinholikatti@gmail.com> wrote:
>>>> This patch set adds following features
>>>> - Seggregate PCI specific code in ufshcd.c
>>>> - Adds PCI glue driver ufshcd-pci.c and ufshcd.c become core module
>>>> - Adds Platform glue driver ufshcd-pltfrm.c
>>>> - Update correct transfer size in Command UPIU
>>>>
>>>> Vinayak Holikatti (4):
>>>> [SCSI] drivers/scsi/ufs: Seggregate PCI Specific Code
>>>> [SCSI] drivers/scsi/ufs: Separate PCI code into glue driver
>>>> [SCSI] ufs: Add Platform glue driver for ufshcd
>>>> [SCSI] ufs: Correct the expected data transfer size
>>>>
>>>> drivers/scsi/ufs/Kconfig | 37 +++-
>>>> drivers/scsi/ufs/Makefile | 2 +
>>>> drivers/scsi/ufs/ufshcd-pci.c | 228 ++++++++++++++++++++
>>>> drivers/scsi/ufs/ufshcd-pltfrm.c | 222 ++++++++++++++++++++
>>>> drivers/scsi/ufs/ufshcd.c | 422 ++++++--------------------------------
>>>> drivers/scsi/ufs/ufshcd.h | 206 +++++++++++++++++++
>>>> drivers/scsi/ufs/ufshcd_common.h | 53 +++++
>>>> 7 files changed, 813 insertions(+), 357 deletions(-)
>>>
>>> Two minor observations..
>>> 1) If both pci and platform have to do the exact same thing in their
>>> _suspend() and _resume() routines, perhaps there is scope for making
>>> them as common (the steps outlined in them should be done in core
>>> ufshcd) ?
>> Both will not have to do the exact same thing. We have plan to implement
>> ufshcd_suspend and ufshcd_resume which will be generic and will be part
>> of ufshcd core, as you said.
>
> Thanks. The comments in the driver files don't reflect this; it'd be
> wise to create
> the placeholder for core_suspend()/resume() in ufshcd.c, instead of
> the platform drivers.
Ok, I will make a place holder in ufshcd.c in next version of patch.
>
>>>
>>> 2) Need to include ufshcd_common.h in ufshcd.c so that the prototypes
>>> are supplied for the exported functions.
>> Thank you, I will make necessary changes in next version of patches.
>>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH V3 0/4] [SCSI] ufs: Adds glue drivers to ufshcd
2012-07-26 8:42 [PATCH V3 0/4] [SCSI] ufs: Adds glue drivers to ufshcd Vinayak Holikatti
` (4 preceding siblings ...)
2012-07-26 10:32 ` [PATCH V3 0/4] [SCSI] ufs: Adds glue drivers to ufshcd S, Venkatraman
@ 2012-08-01 14:44 ` Arnd Bergmann
5 siblings, 0 replies; 13+ messages in thread
From: Arnd Bergmann @ 2012-08-01 14:44 UTC (permalink / raw)
To: Vinayak Holikatti
Cc: James.Bottomley, linux-scsi, linux-kernel, patches,
linux-samsung-soc, arnd, girish.shivananjappa, saugata.das,
vishak.g, venkat, k.rajesh, dsaxena, ilho215.lee, nala.la,
sreekumar.c
On Thursday 26 July 2012, Vinayak Holikatti wrote:
>
> This patch set adds following features
> - Seggregate PCI specific code in ufshcd.c
> - Adds PCI glue driver ufshcd-pci.c and ufshcd.c become core module
> - Adds Platform glue driver ufshcd-pltfrm.c
> - Update correct transfer size in Command UPIU
I've found a few trivial issues that I just replied on. Other than that,
please add my
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
^ permalink raw reply [flat|nested] 13+ messages in thread