From c634ff11e8c5e087d784219698bea29abbc1697a Mon Sep 17 00:00:00 2001
From: Holger Freyther <zecke@openmoko.org>
Date: Wed, 30 Jul 2008 16:25:47 +0200
Subject: [PATCH] [a6k/sdio] Use pnp_alloc_dev to properly initialize the struct pnp_dev
     pnp_alloc_dev will set the bus_id and various other resources to properly
     setup the pnp_dev so that pnp_add_device will work.
     The SlotNumber usage in OS_InitializeDevice is a bit hacky and used to
     have unique names for kobject.

Signed-Off-Number: Holger Freyther <zecke@openmoko.org>
---
 drivers/sdio/function/wlan/ar6000/hif/hif.c |    2 +-
 drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c      |    6 +-
 drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h      |    4 +-
 drivers/sdio/stack/busdriver/sdio_bus_os.c  |   78 ++++++++++++++-------------
 include/linux/sdio/sdio_busdriver.h         |    2 +-
 include/linux/sdio/sdio_hcd_defs.h          |    2 +-
 6 files changed, 48 insertions(+), 46 deletions(-)

diff --git a/drivers/sdio/function/wlan/ar6000/hif/hif.c b/drivers/sdio/function/wlan/ar6000/hif/hif.c
index 3d6d792..5171157 100644
--- a/drivers/sdio/function/wlan/ar6000/hif/hif.c
+++ b/drivers/sdio/function/wlan/ar6000/hif/hif.c
@@ -782,7 +782,7 @@ delHifDevice(SDDEVICE *handle)
 struct device*
 HIFGetOSDevice(HIF_DEVICE *device)
 {
-    return &device->handle->Device.dev;
+    return &device->handle->Device->dev;
 }
 
 static void ResetAllCards(void)
diff --git a/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c b/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c
index edb8523..09d81ee 100644
--- a/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c
+++ b/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c
@@ -1296,7 +1296,6 @@ struct s3c24xx_hcd_context hcd_context = {
 	.hcd.pContext = &hcd_context,
 	.hcd.pRequest = s3c24xx_hcd_request,
 	.hcd.pConfigure = s3c24xx_hcd_config,
-	.device.pnp_device.name = "sdio_s3c24xx_hcd",
 	.device.pnp_driver.name = "sdio_s3c24xx_hcd",
 	.device.pnp_driver.probe  = s3c24xx_hcd_pnp_probe,
 	.device.pnp_driver.remove = s3c24xx_hcd_pnp_remove,
@@ -1348,7 +1347,7 @@ static int s3c24xx_hcd_probe(struct platform_device * pdev)
 
 	status = SDIO_BusAddOSDevice(&hcd_context.device.dma,
 				     &hcd_context.device.pnp_driver,
-				     &hcd_context.device.pnp_device);
+				     &hcd_context.device.pnp_device, "sdio_s3c24xx_hcd");
 
  out:
 
@@ -1360,7 +1359,8 @@ static int s3c24xx_hcd_probe(struct platform_device * pdev)
  */
 static int s3c24xx_hcd_remove(struct platform_device * pdev) {
 	printk("S3C2440 SDIO host controller unloaded\n");
-	SDIO_BusRemoveOSDevice(&hcd_context.device.pnp_driver, &hcd_context.device.pnp_device);
+	SDIO_BusRemoveOSDevice(&hcd_context.device.pnp_driver, hcd_context.device.pnp_device);
+	kfree(hcd_context.device.pnp_device);
 
 	return 0;
 }
diff --git a/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h b/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h
index 47fdd33..f8b0912 100644
--- a/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h
+++ b/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h
@@ -8,8 +8,8 @@
 #define S3C24XX_HCD_DATA_WRITE      5
 
 struct s3c24xx_hcd_device {
-	OS_PNPDEVICE   pnp_device;     /* the OS device for this HCD */
-	OS_PNPDRIVER   pnp_driver;     /* the OS driver for this HCD */
+	OS_PNPDEVICE *pnp_device;     /* the OS device for this HCD */
+	OS_PNPDRIVER  pnp_driver;     /* the OS driver for this HCD */
 	SDDMA_DESCRIPTION dma;
 	struct clk * clock;
 	unsigned long max_clock_rate;
diff --git a/drivers/sdio/stack/busdriver/sdio_bus_os.c b/drivers/sdio/stack/busdriver/sdio_bus_os.c
index 2650d93..c6f68e6 100644
--- a/drivers/sdio/stack/busdriver/sdio_bus_os.c
+++ b/drivers/sdio/stack/busdriver/sdio_bus_os.c
@@ -415,8 +415,8 @@ struct pnp_protocol sdio_protocol = {
 */
 static int driver_probe(struct pnp_dev* pOSDevice, const struct pnp_device_id *pId)
 {
-    PSDDEVICE pDevice = SDDEVICE_FROM_OSDEVICE(pOSDevice);
-    PSDFUNCTION pFunction = pDevice->Device.dev.driver_data;
+    PSDDEVICE pDevice = SDDEVICE_FROM_OSDEVICE(&pOSDevice);
+    PSDFUNCTION pFunction = pDevice->Device->dev.driver_data;
 
     if (pFunction == NULL) {
         return -1;
@@ -496,34 +496,32 @@ static int UnregisterDriver(PSDFUNCTION pFunction)
 */
 SDIO_STATUS OS_InitializeDevice(PSDDEVICE pDevice, PSDFUNCTION pFunction)
 {
-	char id_name[20];
+    char id_name[20];
 
-    memset(&pDevice->Device, 0, sizeof(pDevice->Device));
-    pDevice->Device.dev.driver_data = (PVOID)pFunction;
+    /* set the id as slot number/function number */
+    snprintf(id_name, sizeof(id_name) - 1, "SD_%02X%02X",
+             pDevice->pHcd->SlotNumber, (UINT)SDDEVICE_GET_SDIO_FUNCNO(pDevice));
+
+    pDevice->Device = pnp_alloc_dev(&sdio_protocol, pDevice->pHcd->SlotNumber + 1, id_name);
+    pDevice->Device->dev.driver_data = (PVOID)pFunction;
 //??    pDevice->Device.data = (PVOID)pFunction;
 //??    pDevice->Device.dev.driver = &pFunction->Driver.driver;
 //??    pDevice->Device.driver = &pFunction->Driver;
 //??    pDevice->Device.dev.release = release;
     /* get a unique device number, must be done with locks held */
     spin_lock(&InUseDevicesLock);
-    pDevice->Device.number = FirstClearBit(&InUseDevices);
-    SetBit(&InUseDevices, pDevice->Device.number);
+    pDevice->Device->number = FirstClearBit(&InUseDevices);
+    SetBit(&InUseDevices, pDevice->Device->number);
     spin_unlock(&InUseDevicesLock);
-    pDevice->Device.capabilities = PNP_REMOVABLE | PNP_DISABLE;
-    pDevice->Device.protocol = &sdio_protocol;
-    pDevice->Device.active = 1;
+    pDevice->Device->capabilities = PNP_REMOVABLE | PNP_DISABLE;
+    pDevice->Device->active = 1;
 
-    /* set the id as slot number/function number */
-    snprintf(id_name, sizeof(id_name) - 1, "SD_%02X%02X",
-             pDevice->pHcd->SlotNumber, (UINT)SDDEVICE_GET_SDIO_FUNCNO(pDevice));
     DBG_PRINT(SDDBG_TRACE, ("SDIO BusDriver - OS_InitializeDevice adding id: %s\n",
                              id_name));
-    pnp_add_id(&pDevice->Device, id_name);
-
-        /* deal with DMA settings */
+    /* deal with DMA settings */
     if (pDevice->pHcd->pDmaDescription != NULL) {
-        pDevice->Device.dev.dma_mask = &pDevice->pHcd->pDmaDescription->Mask;
-        pDevice->Device.dev.coherent_dma_mask = pDevice->pHcd->pDmaDescription->Mask;
+        pDevice->Device->dev.dma_mask = &pDevice->pHcd->pDmaDescription->Mask;
+        pDevice->Device->dev.coherent_dma_mask = pDevice->pHcd->pDmaDescription->Mask;
     }
 
     return SDIO_STATUS_SUCCESS;
@@ -537,13 +535,13 @@ SDIO_STATUS OS_AddDevice(PSDDEVICE pDevice, PSDFUNCTION pFunction)
     int error;
     DBG_PRINT(SDDBG_TRACE, ("SDIO BusDriver - OS_AddDevice adding function: %s\n",
                                pFunction->pName));
-    error = pnp_add_device(&pDevice->Device);
+    error = pnp_add_device(pDevice->Device);
     if (error < 0) {
         DBG_PRINT(SDDBG_ERROR, ("SDIO BusDriver - OS_AddDevice failed pnp_add_device: %d\n",
                                error));
     }
         /* replace the buggy pnp's release */
-    pDevice->Device.dev.release = release;
+    pDevice->Device->dev.release = release;
 
     return OSErrorToSDIOError(error);
 }
@@ -554,15 +552,17 @@ SDIO_STATUS OS_AddDevice(PSDDEVICE pDevice, PSDFUNCTION pFunction)
 void OS_RemoveDevice(PSDDEVICE pDevice)
 {
     DBG_PRINT(SDDBG_TRACE, ("SDIO BusDriver - OS_RemoveDevice \n"));
-    pnp_remove_card_device(&pDevice->Device);
+    pnp_remove_card_device(pDevice->Device);
     spin_lock(&InUseDevicesLock);
-    ClearBit(&InUseDevices, pDevice->Device.number);
+    ClearBit(&InUseDevices, pDevice->Device->number);
     spin_unlock(&InUseDevicesLock);
 
-    if (pDevice->Device.id != NULL) {
-        KernelFree(pDevice->Device.id);
-        pDevice->Device.id = NULL;
+    if (pDevice->Device->id != NULL) {
+        KernelFree(pDevice->Device->id);
+        pDevice->Device->id = NULL;
     }
+
+    KernelFree(pDevice->Device);
 }
 
 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -612,20 +612,13 @@ void OS_RemoveDevice(PSDDEVICE pDevice)
   @see also: SDIO_BusRemoveOSDevice
 
 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS SDIO_BusAddOSDevice(PSDDMA_DESCRIPTION pDma, POS_PNPDRIVER pDriver, POS_PNPDEVICE pDevice)
+SDIO_STATUS SDIO_BusAddOSDevice(PSDDMA_DESCRIPTION pDma, POS_PNPDRIVER pDriver, POS_PNPDEVICE *outDevice, const char* name)
 {
     int err;
     struct pnp_device_id *pFdid;
     static int slotNumber = 0; /* we just use an increasing count for the slots number */
-	char id_name[20];
+    struct pnp_dev* pDevice;
 
-    if (pDma != NULL) {
-        pDevice->dev.dma_mask = &pDma->Mask;
-        pDevice->dev.coherent_dma_mask = pDma->Mask;
-    }
-    DBG_PRINT(SDDBG_ERROR,
-            ("SDIO BusDriver - SDIO_GetBusOSDevice, registering driver: %s DMAmask: 0x%x\n",
-            pDriver->name, (UINT)*pDevice->dev.dma_mask));
     pFdid = KernelAlloc(sizeof(struct pnp_device_id)*2);
     /* set the id as slot number/function number */
     snprintf(pFdid[0].id, sizeof(pFdid[0].id), "SD_%02X08",
@@ -644,14 +637,22 @@ SDIO_STATUS SDIO_BusAddOSDevice(PSDDMA_DESCRIPTION pDma, POS_PNPDRIVER pDriver,
         return OSErrorToSDIOError(err);
     }
 
+    pDevice = pnp_alloc_dev(&sdio_protocol, slotNumber - 1, pFdid[0].id);
+    if (!pDevice)
+        return -EINVAL;
+
+    if (pDma != NULL) {
+        pDevice->dev.dma_mask = &pDma->Mask;
+        pDevice->dev.coherent_dma_mask = pDma->Mask;
+    }
+    DBG_PRINT(SDDBG_ERROR,
+            ("SDIO BusDriver - SDIO_GetBusOSDevice, registering driver: %s DMAmask: 0x%x\n",
+            pDriver->name, (UINT)*pDevice->dev.dma_mask));
+
     pDevice->protocol = &sdio_protocol;
     pDevice->capabilities = PNP_REMOVABLE | PNP_DISABLE;
     pDevice->active = 1;
 
-    /* set the id as slot number/function number */
-    snprintf(id_name, sizeof(id_name) - 1, "SD_%02X08",
-             0); //??pDevice->pHcd->SlotNumber);//?????fix this, slotnumber isn't vaialble yet
-    pnp_add_id(pDevice, id_name);
 
     /* get a unique device number */
     spin_lock(&InUseDevicesLock);
@@ -667,6 +668,7 @@ SDIO_STATUS SDIO_BusAddOSDevice(PSDDMA_DESCRIPTION pDma, POS_PNPDRIVER pDriver,
     }
     /* replace the buggy pnp's release */
     pDevice->dev.release = release;
+    *outDevice = pDevice;
     return OSErrorToSDIOError(err);
 }
 
diff --git a/include/linux/sdio/sdio_busdriver.h b/include/linux/sdio/sdio_busdriver.h
index b431d3d..35e3ebb 100644
--- a/include/linux/sdio/sdio_busdriver.h
+++ b/include/linux/sdio/sdio_busdriver.h
@@ -477,7 +477,7 @@ typedef struct _SDDEVICE {
     struct _SDHCD  *pHcd;           /* host controller this device is on (internal use) */
     SDDEVICE_INFO   DeviceInfo;     /* device info */
     SD_PNP_INFO pId[1];             /* id of this device  */
-    OS_PNPDEVICE Device;            /* device registration with base system */
+    OS_PNPDEVICE *Device;           /* device registration with base system */
     SD_SLOT_CURRENT  SlotCurrentAlloc; /* allocated slot current for this device/function (internal use) */
     SD_DEVICE_FLAGS Flags;          /* internal use flags */
     CT_VERSION_CODE Version;        /* version code of the bus driver */
diff --git a/include/linux/sdio/sdio_hcd_defs.h b/include/linux/sdio/sdio_hcd_defs.h
index 1782469..e6115a2 100644
--- a/include/linux/sdio/sdio_hcd_defs.h
+++ b/include/linux/sdio/sdio_hcd_defs.h
@@ -213,7 +213,7 @@ SDIO_STATUS SDIO_RegisterHostController(PSDHCD pHcd);
 SDIO_STATUS SDIO_UnregisterHostController(PSDHCD pHcd);
 SDIO_STATUS SDIO_HandleHcdEvent(PSDHCD pHcd, HCD_EVENT Event);
 SDIO_STATUS SDIO_CheckResponse(PSDHCD pHcd, PSDREQUEST pReq, SDHCD_RESPONSE_CHECK_MODE CheckMode);
-SDIO_STATUS SDIO_BusAddOSDevice(PSDDMA_DESCRIPTION pDma, POS_PNPDRIVER pDriver, POS_PNPDEVICE pDevice);
+SDIO_STATUS SDIO_BusAddOSDevice(PSDDMA_DESCRIPTION pDma, POS_PNPDRIVER pDriver, POS_PNPDEVICE *pDevice, const char* name);
 void SDIO_BusRemoveOSDevice(POS_PNPDRIVER pDriver, POS_PNPDEVICE pDevice);
 
 #endif /* __SDIO_BUSDRIVER_H___ */
-- 
1.5.4.3

