return 1;
 }
 
+static void ulp_read_write(struct rsi_hw *adapter, u16 addr, u32 data,
+                          u16 len_in_bits)
+{
+       rsi_sdio_master_reg_write(adapter, RSI_GSPI_DATA_REG1,
+                                 ((addr << 6) | ((data >> 16) & 0xffff)), 2);
+       rsi_sdio_master_reg_write(adapter, RSI_GSPI_DATA_REG0,
+                                 (data & 0xffff), 2);
+       rsi_sdio_master_reg_write(adapter, RSI_GSPI_CTRL_REG0,
+                                 RSI_GSPI_CTRL_REG0_VALUE, 2);
+       rsi_sdio_master_reg_write(adapter, RSI_GSPI_CTRL_REG1,
+                                 ((len_in_bits - 1) | RSI_GSPI_TRIG), 2);
+       msleep(20);
+}
+
+/*This function resets and re-initializes the chip.*/
+static void rsi_reset_chip(struct rsi_hw *adapter)
+{
+       __le32 data;
+       u8 sdio_interrupt_status = 0;
+       u8 request = 1;
+       int ret;
+
+       rsi_dbg(INFO_ZONE, "Writing disable to wakeup register\n");
+       ret =  rsi_sdio_write_register(adapter, 0, SDIO_WAKEUP_REG, &request);
+       if (ret < 0) {
+               rsi_dbg(ERR_ZONE,
+                       "%s: Failed to write SDIO wakeup register\n", __func__);
+               return;
+       }
+       msleep(20);
+       ret =  rsi_sdio_read_register(adapter, RSI_FN1_INT_REGISTER,
+                                     &sdio_interrupt_status);
+       if (ret < 0) {
+               rsi_dbg(ERR_ZONE, "%s: Failed to Read Intr Status Register\n",
+                       __func__);
+               return;
+       }
+       rsi_dbg(INFO_ZONE, "%s: Intr Status Register value = %d\n",
+               __func__, sdio_interrupt_status);
+
+       /* Put Thread-Arch processor on hold */
+       if (rsi_sdio_master_access_msword(adapter, TA_BASE_ADDR)) {
+               rsi_dbg(ERR_ZONE,
+                       "%s: Unable to set ms word to common reg\n",
+                       __func__);
+               return;
+       }
+
+       data = TA_HOLD_THREAD_VALUE;
+       if (rsi_sdio_write_register_multiple(adapter, TA_HOLD_THREAD_REG |
+                                            RSI_SD_REQUEST_MASTER,
+                                            (u8 *)&data, 4)) {
+               rsi_dbg(ERR_ZONE,
+                       "%s: Unable to hold Thread-Arch processor threads\n",
+                       __func__);
+               return;
+       }
+
+       /* This msleep will ensure Thread-Arch processor to go to hold
+        * and any pending dma transfers to rf spi in device to finish.
+        */
+       msleep(100);
+
+       ulp_read_write(adapter, RSI_ULP_RESET_REG, RSI_ULP_WRITE_0, 32);
+       ulp_read_write(adapter, RSI_WATCH_DOG_TIMER_1, RSI_ULP_WRITE_2, 32);
+       ulp_read_write(adapter, RSI_WATCH_DOG_TIMER_2, RSI_ULP_WRITE_0, 32);
+       ulp_read_write(adapter, RSI_WATCH_DOG_DELAY_TIMER_1, RSI_ULP_WRITE_50,
+                      32);
+       ulp_read_write(adapter, RSI_WATCH_DOG_DELAY_TIMER_2, RSI_ULP_WRITE_0,
+                      32);
+       ulp_read_write(adapter, RSI_WATCH_DOG_TIMER_ENABLE,
+                      RSI_ULP_TIMER_ENABLE, 32);
+       /* This msleep will be sufficient for the ulp
+        * read write operations to complete for chip reset.
+        */
+       msleep(500);
+}
+
 /**
  * rsi_disconnect() - This function performs the reverse of the probe function.
  * @pfunction: Pointer to the sdio_func structure.
        sdio_release_irq(pfunction);
        sdio_disable_func(pfunction);
        rsi_91x_deinit(adapter);
-       /* Resetting to take care of the case, where-in driver is re-loaded */
+       rsi_reset_chip(adapter);
        rsi_reset_card(pfunction);
        sdio_release_host(pfunction);
 }
 
 #define FW_LOADING_SUCCESSFUL          'S'
 #define LOADING_INITIATED              '1'
 
+#define RSI_ULP_RESET_REG              0x161
+#define RSI_WATCH_DOG_TIMER_1          0x16c
+#define RSI_WATCH_DOG_TIMER_2          0x16d
+#define RSI_WATCH_DOG_DELAY_TIMER_1            0x16e
+#define RSI_WATCH_DOG_DELAY_TIMER_2            0x16f
+#define RSI_WATCH_DOG_TIMER_ENABLE             0x170
+
+#define RSI_ULP_WRITE_0                        00
+#define RSI_ULP_WRITE_2                        02
+#define RSI_ULP_WRITE_50               50
+
+#define RSI_RESTART_WDT                        BIT(11)
+#define RSI_BYPASS_ULP_ON_WDT          BIT(1)
+
+#define RSI_ULP_TIMER_ENABLE           ((0xaa000) | RSI_RESTART_WDT |  \
+                                        RSI_BYPASS_ULP_ON_WDT)
+#define RSI_RF_SPI_PROG_REG_BASE_ADDR  0x40080000
+
+#define RSI_GSPI_CTRL_REG0             (RSI_RF_SPI_PROG_REG_BASE_ADDR)
+#define RSI_GSPI_CTRL_REG1             (RSI_RF_SPI_PROG_REG_BASE_ADDR + 0x2)
+#define RSI_GSPI_DATA_REG0             (RSI_RF_SPI_PROG_REG_BASE_ADDR + 0x4)
+#define RSI_GSPI_DATA_REG1             (RSI_RF_SPI_PROG_REG_BASE_ADDR + 0x6)
+#define RSI_GSPI_DATA_REG2             (RSI_RF_SPI_PROG_REG_BASE_ADDR + 0x8)
+
+#define RSI_GSPI_CTRL_REG0_VALUE               0x340
+
+#define RSI_GSPI_DMA_MODE                      BIT(13)
+
+#define RSI_GSPI_2_ULP                 BIT(12)
+#define RSI_GSPI_TRIG                  BIT(7)
+#define RSI_GSPI_READ                  BIT(6)
+#define RSI_GSPI_RF_SPI_ACTIVE         BIT(8)
+
 /* Boot loader commands */
 #define SEND_RPS_FILE                  '2'