{
        struct spi_device *spi = to_spi_device(dev);
        struct spi_device *new_spi = data;
-
-       if (spi->controller == new_spi->controller &&
-           spi_get_chipselect(spi, 0) == spi_get_chipselect(new_spi, 0))
-               return -EBUSY;
+       int idx, nw_idx;
+       u8 cs, cs_nw;
+
+       if (spi->controller == new_spi->controller) {
+               for (idx = 0; idx < SPI_CS_CNT_MAX; idx++) {
+                       cs = spi_get_chipselect(spi, idx);
+                       for (nw_idx = 0; nw_idx < SPI_CS_CNT_MAX; nw_idx++) {
+                               cs_nw = spi_get_chipselect(new_spi, nw_idx);
+                               if (cs != 0xFF && cs_nw != 0xFF && cs == cs_nw) {
+                                       dev_err(dev, "chipselect %d already in use\n", cs_nw);
+                                       return -EBUSY;
+                               }
+                       }
+               }
+       }
        return 0;
 }
 
 {
        struct spi_controller *ctlr = spi->controller;
        struct device *dev = ctlr->dev.parent;
-       int status;
+       int status, idx, nw_idx;
+       u8 cs, nw_cs;
+
+       for (idx = 0; idx < SPI_CS_CNT_MAX; idx++) {
+               /* Chipselects are numbered 0..max; validate. */
+               cs = spi_get_chipselect(spi, idx);
+               if (cs != 0xFF && cs >= ctlr->num_chipselect) {
+                       dev_err(dev, "cs%d >= max %d\n", spi_get_chipselect(spi, idx),
+                               ctlr->num_chipselect);
+                       return -EINVAL;
+               }
+       }
 
-       /* Chipselects are numbered 0..max; validate. */
-       if (spi_get_chipselect(spi, 0) >= ctlr->num_chipselect) {
-               dev_err(dev, "cs%d >= max %d\n", spi_get_chipselect(spi, 0),
-                       ctlr->num_chipselect);
-               return -EINVAL;
+       /*
+        * Make sure that multiple logical CS doesn't map to the same physical CS.
+        * For example, spi->chip_select[0] != spi->chip_select[1] and so on.
+        */
+       for (idx = 0; idx < SPI_CS_CNT_MAX; idx++) {
+               cs = spi_get_chipselect(spi, idx);
+               for (nw_idx = idx + 1; nw_idx < SPI_CS_CNT_MAX; nw_idx++) {
+                       nw_cs = spi_get_chipselect(spi, nw_idx);
+                       if (cs != 0xFF && nw_cs != 0xFF && cs == nw_cs) {
+                               dev_err(dev, "chipselect %d already in use\n", nw_cs);
+                               return -EBUSY;
+                       }
+               }
        }
 
        /* Set the bus ID string */
         * its configuration.
         */
        status = bus_for_each_dev(&spi_bus_type, NULL, spi, spi_dev_check);
-       if (status) {
-               dev_err(dev, "chipselect %d already in use\n",
-                               spi_get_chipselect(spi, 0));
+       if (status)
                return status;
-       }
 
        /* Controller may unregister concurrently */
        if (IS_ENABLED(CONFIG_SPI_DYNAMIC) &&
                return -ENODEV;
        }
 
-       if (ctlr->cs_gpiods)
-               spi_set_csgpiod(spi, 0, ctlr->cs_gpiods[spi_get_chipselect(spi, 0)]);
+       if (ctlr->cs_gpiods) {
+               u8 cs;
+
+               for (idx = 0; idx < SPI_CS_CNT_MAX; idx++) {
+                       cs = spi_get_chipselect(spi, idx);
+                       if (cs != 0xFF)
+                               spi_set_csgpiod(spi, idx, ctlr->cs_gpiods[cs]);
+               }
+       }
 
        /*
         * Drivers may modify this initial i/o setup, but will
        struct spi_controller *ctlr = spi->controller;
        int status;
 
+       /* Set the bus ID string */
+       spi_dev_set_name(spi);
+
        mutex_lock(&ctlr->add_lock);
        status = __spi_add_device(spi);
        mutex_unlock(&ctlr->add_lock);
 {
        struct spi_device       *proxy;
        int                     status;
+       u8                      idx;
 
        /*
         * NOTE:  caller did any chip->bus_num checks necessary.
 
        WARN_ON(strlen(chip->modalias) >= sizeof(proxy->modalias));
 
+       /*
+        * Zero(0) is a valid physical CS value and can be located at any
+        * logical CS in the spi->chip_select[]. If all the physical CS
+        * are initialized to 0 then It would be difficult to differentiate
+        * between a valid physical CS 0 & an unused logical CS whose physical
+        * CS can be 0. As a solution to this issue initialize all the CS to 0xFF.
+        * Now all the unused logical CS will have 0xFF physical CS value & can be
+        * ignore while performing physical CS validity checks.
+        */
+       for (idx = 0; idx < SPI_CS_CNT_MAX; idx++)
+               spi_set_chipselect(proxy, idx, 0xFF);
+
        spi_set_chipselect(proxy, 0, chip->chip_select);
        proxy->max_speed_hz = chip->max_speed_hz;
        proxy->mode = chip->mode;
        proxy->dev.platform_data = (void *) chip->platform_data;
        proxy->controller_data = chip->controller_data;
        proxy->controller_state = NULL;
+       /*
+        * spi->chip_select[i] gives the corresponding physical CS for logical CS i
+        * logical CS number is represented by setting the ith bit in spi->cs_index_mask
+        * So, for example, if spi->cs_index_mask = 0x01 then logical CS number is 0 and
+        * spi->chip_select[0] will give the physical CS.
+        * By default spi->chip_select[0] will hold the physical CS number so, set
+        * spi->cs_index_mask as 0x01.
+        */
+       proxy->cs_index_mask = 0x01;
 
        if (chip->swnode) {
                status = device_add_software_node(&proxy->dev, chip->swnode);
 }
 
 /*-------------------------------------------------------------------------*/
+static inline bool spi_is_last_cs(struct spi_device *spi)
+{
+       u8 idx;
+       bool last = false;
+
+       for (idx = 0; idx < SPI_CS_CNT_MAX; idx++) {
+               if ((spi->cs_index_mask >> idx) & 0x01) {
+                       if (spi->controller->last_cs[idx] == spi_get_chipselect(spi, idx))
+                               last = true;
+               }
+       }
+       return last;
+}
+
 
 static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
 {
        bool activate = enable;
+       u8 idx;
 
        /*
         * Avoid calling into the driver (or doing delays) if the chip select
         * isn't actually changing from the last time this was called.
         */
-       if (!force && ((enable && spi->controller->last_cs == spi_get_chipselect(spi, 0)) ||
-                      (!enable && spi->controller->last_cs != spi_get_chipselect(spi, 0))) &&
+       if (!force && ((enable && spi->controller->last_cs_index_mask == spi->cs_index_mask &&
+                       spi_is_last_cs(spi)) ||
+                      (!enable && spi->controller->last_cs_index_mask == spi->cs_index_mask &&
+                       !spi_is_last_cs(spi))) &&
            (spi->controller->last_cs_mode_high == (spi->mode & SPI_CS_HIGH)))
                return;
 
        trace_spi_set_cs(spi, activate);
 
-       spi->controller->last_cs = enable ? spi_get_chipselect(spi, 0) : -1;
+       spi->controller->last_cs_index_mask = spi->cs_index_mask;
+       for (idx = 0; idx < SPI_CS_CNT_MAX; idx++)
+               spi->controller->last_cs[idx] = enable ? spi_get_chipselect(spi, 0) : -1;
        spi->controller->last_cs_mode_high = spi->mode & SPI_CS_HIGH;
 
-       if ((spi_get_csgpiod(spi, 0) || !spi->controller->set_cs_timing) && !activate)
-               spi_delay_exec(&spi->cs_hold, NULL);
-
        if (spi->mode & SPI_CS_HIGH)
                enable = !enable;
 
-       if (spi_get_csgpiod(spi, 0)) {
+       if (spi_is_csgpiod(spi)) {
+               if (!spi->controller->set_cs_timing && !activate)
+                       spi_delay_exec(&spi->cs_hold, NULL);
+
                if (!(spi->mode & SPI_NO_CS)) {
                        /*
                         * Historically ACPI has no means of the GPIO polarity and
                         * ambiguity. That's why we use enable, that takes SPI_CS_HIGH
                         * into account.
                         */
-                       if (has_acpi_companion(&spi->dev))
-                               gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), !enable);
-                       else
-                               /* Polarity handled by GPIO library */
-                               gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), activate);
+                       for (idx = 0; idx < SPI_CS_CNT_MAX; idx++) {
+                               if (((spi->cs_index_mask >> idx) & 0x01) &&
+                                   spi_get_csgpiod(spi, idx)) {
+                                       if (has_acpi_companion(&spi->dev))
+                                               gpiod_set_value_cansleep(spi_get_csgpiod(spi, idx),
+                                                                        !enable);
+                                       else
+                                               /* Polarity handled by GPIO library */
+                                               gpiod_set_value_cansleep(spi_get_csgpiod(spi, idx),
+                                                                        activate);
+
+                                       if (activate)
+                                               spi_delay_exec(&spi->cs_setup, NULL);
+                                       else
+                                               spi_delay_exec(&spi->cs_inactive, NULL);
+                               }
+                       }
                }
                /* Some SPI masters need both GPIO CS & slave_select */
                if ((spi->controller->flags & SPI_CONTROLLER_GPIO_SS) &&
                    spi->controller->set_cs)
                        spi->controller->set_cs(spi, !enable);
+
+               if (!spi->controller->set_cs_timing) {
+                       if (activate)
+                               spi_delay_exec(&spi->cs_setup, NULL);
+                       else
+                               spi_delay_exec(&spi->cs_inactive, NULL);
+               }
        } else if (spi->controller->set_cs) {
                spi->controller->set_cs(spi, !enable);
        }
-
-       if (spi_get_csgpiod(spi, 0) || !spi->controller->set_cs_timing) {
-               if (activate)
-                       spi_delay_exec(&spi->cs_setup, NULL);
-               else
-                       spi_delay_exec(&spi->cs_inactive, NULL);
-       }
 }
 
 #ifdef CONFIG_HAS_DMA
 static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
                           struct device_node *nc)
 {
-       u32 value;
-       int rc;
+       u32 value, cs[SPI_CS_CNT_MAX];
+       int rc, idx;
 
        /* Mode (clock phase/polarity/etc.) */
        if (of_property_read_bool(nc, "spi-cpha"))
                return 0;
        }
 
+       if (ctlr->num_chipselect > SPI_CS_CNT_MAX) {
+               dev_err(&ctlr->dev, "No. of CS is more than max. no. of supported CS\n");
+               return -EINVAL;
+       }
+
+       /*
+        * Zero(0) is a valid physical CS value and can be located at any
+        * logical CS in the spi->chip_select[]. If all the physical CS
+        * are initialized to 0 then It would be difficult to differentiate
+        * between a valid physical CS 0 & an unused logical CS whose physical
+        * CS can be 0. As a solution to this issue initialize all the CS to 0xFF.
+        * Now all the unused logical CS will have 0xFF physical CS value & can be
+        * ignore while performing physical CS validity checks.
+        */
+       for (idx = 0; idx < SPI_CS_CNT_MAX; idx++)
+               spi_set_chipselect(spi, idx, 0xFF);
+
        /* Device address */
-       rc = of_property_read_u32(nc, "reg", &value);
-       if (rc) {
+       rc = of_property_read_variable_u32_array(nc, "reg", &cs[0], 1,
+                                                SPI_CS_CNT_MAX);
+       if (rc < 0) {
                dev_err(&ctlr->dev, "%pOF has no valid 'reg' property (%d)\n",
                        nc, rc);
                return rc;
        }
-       spi_set_chipselect(spi, 0, value);
+       if (rc > ctlr->num_chipselect) {
+               dev_err(&ctlr->dev, "%pOF has number of CS > ctlr->num_chipselect (%d)\n",
+                       nc, rc);
+               return rc;
+       }
+       if ((of_property_read_bool(nc, "parallel-memories")) &&
+           (!(ctlr->flags & SPI_CONTROLLER_MULTI_CS))) {
+               dev_err(&ctlr->dev, "SPI controller doesn't support multi CS\n");
+               return -EINVAL;
+       }
+       for (idx = 0; idx < rc; idx++)
+               spi_set_chipselect(spi, idx, cs[idx]);
+
+       /*
+        * spi->chip_select[i] gives the corresponding physical CS for logical CS i
+        * logical CS number is represented by setting the ith bit in spi->cs_index_mask
+        * So, for example, if spi->cs_index_mask = 0x01 then logical CS number is 0 and
+        * spi->chip_select[0] will give the physical CS.
+        * By default spi->chip_select[0] will hold the physical CS number so, set
+        * spi->cs_index_mask as 0x01.
+        */
+       spi->cs_index_mask = 0x01;
 
        /* Device speed */
        if (!of_property_read_u32(nc, "spi-max-frequency", &value))
        struct spi_controller *ctlr = spi->controller;
        struct spi_device *ancillary;
        int rc = 0;
+       u8 idx;
 
        /* Alloc an spi_device */
        ancillary = spi_alloc_device(ctlr);
 
        strscpy(ancillary->modalias, "dummy", sizeof(ancillary->modalias));
 
+       /*
+        * Zero(0) is a valid physical CS value and can be located at any
+        * logical CS in the spi->chip_select[]. If all the physical CS
+        * are initialized to 0 then It would be difficult to differentiate
+        * between a valid physical CS 0 & an unused logical CS whose physical
+        * CS can be 0. As a solution to this issue initialize all the CS to 0xFF.
+        * Now all the unused logical CS will have 0xFF physical CS value & can be
+        * ignore while performing physical CS validity checks.
+        */
+       for (idx = 0; idx < SPI_CS_CNT_MAX; idx++)
+               spi_set_chipselect(ancillary, idx, 0xFF);
+
        /* Use provided chip-select for ancillary device */
        spi_set_chipselect(ancillary, 0, chip_select);
 
        /* Take over SPI mode/speed from SPI main device */
        ancillary->max_speed_hz = spi->max_speed_hz;
        ancillary->mode = spi->mode;
+       /*
+        * spi->chip_select[i] gives the corresponding physical CS for logical CS i
+        * logical CS number is represented by setting the ith bit in spi->cs_index_mask
+        * So, for example, if spi->cs_index_mask = 0x01 then logical CS number is 0 and
+        * spi->chip_select[0] will give the physical CS.
+        * By default spi->chip_select[0] will hold the physical CS number so, set
+        * spi->cs_index_mask as 0x01.
+        */
+       ancillary->cs_index_mask = 0x01;
 
        WARN_ON(!mutex_is_locked(&ctlr->add_lock));
 
        struct acpi_spi_lookup lookup = {};
        struct spi_device *spi;
        int ret;
+       u8 idx;
 
        if (!ctlr && index == -1)
                return ERR_PTR(-EINVAL);
                return ERR_PTR(-ENOMEM);
        }
 
+       /*
+        * Zero(0) is a valid physical CS value and can be located at any
+        * logical CS in the spi->chip_select[]. If all the physical CS
+        * are initialized to 0 then It would be difficult to differentiate
+        * between a valid physical CS 0 & an unused logical CS whose physical
+        * CS can be 0. As a solution to this issue initialize all the CS to 0xFF.
+        * Now all the unused logical CS will have 0xFF physical CS value & can be
+        * ignore while performing physical CS validity checks.
+        */
+       for (idx = 0; idx < SPI_CS_CNT_MAX; idx++)
+               spi_set_chipselect(spi, idx, 0xFF);
+
        ACPI_COMPANION_SET(&spi->dev, adev);
        spi->max_speed_hz       = lookup.max_speed_hz;
        spi->mode               |= lookup.mode;
        spi->irq                = lookup.irq;
        spi->bits_per_word      = lookup.bits_per_word;
        spi_set_chipselect(spi, 0, lookup.chip_select);
+       /*
+        * spi->chip_select[i] gives the corresponding physical CS for logical CS i
+        * logical CS number is represented by setting the ith bit in spi->cs_index_mask
+        * So, for example, if spi->cs_index_mask = 0x01 then logical CS number is 0 and
+        * spi->chip_select[0] will give the physical CS.
+        * By default spi->chip_select[0] will hold the physical CS number so, set
+        * spi->cs_index_mask as 0x01.
+        */
+       spi->cs_index_mask      = 0x01;
 
        return spi;
 }
        struct boardinfo        *bi;
        int                     first_dynamic;
        int                     status;
+       int                     idx;
 
        if (!dev)
                return -ENODEV;
        }
 
        /* Setting last_cs to -1 means no chip selected */
-       ctlr->last_cs = -1;
+       for (idx = 0; idx < SPI_CS_CNT_MAX; idx++)
+               ctlr->last_cs[idx] = -1;
 
        status = device_add(&ctlr->dev);
        if (status < 0)
         * cs_change is set for each transfer.
         */
        if ((spi->mode & SPI_CS_WORD) && (!(ctlr->mode_bits & SPI_CS_WORD) ||
-                                         spi_get_csgpiod(spi, 0))) {
+                                         spi_is_csgpiod(spi))) {
                size_t maxsize = BITS_TO_BYTES(spi->bits_per_word);
                int ret;
 
 
 
 #include <uapi/linux/spi/spi.h>
 
+/* Max no. of CS supported per spi device */
+#define SPI_CS_CNT_MAX 4
+
 struct dma_chan;
 struct software_node;
 struct ptp_system_timestamp;
  * @max_speed_hz: Maximum clock rate to be used with this chip
  *     (on this board); may be changed by the device's driver.
  *     The spi_transfer.speed_hz can override this for each transfer.
- * @chip_select: Chipselect, distinguishing chips handled by @controller.
+ * @chip_select: Array of physical chipselect, spi->chipselect[i] gives
+ *     the corresponding physical CS for logical CS i.
  * @mode: The spi mode defines how data is clocked out and in.
  *     This may be changed by the device's driver.
  *     The "active low" default for chipselect mode can be overridden
  *     the device will bind to the named driver and only the named driver.
  *     Do not set directly, because core frees it; use driver_set_override() to
  *     set or clear it.
- * @cs_gpiod: GPIO descriptor of the chipselect line (optional, NULL when
- *     not using a GPIO line)
+ * @cs_gpiod: Array of GPIO descriptors of the corresponding chipselect lines
+ *     (optional, NULL when not using a GPIO line)
  * @word_delay: delay to be inserted between consecutive
  *     words of a transfer
  * @cs_setup: delay to be introduced by the controller after CS is asserted
  *     deasserted. If @cs_change_delay is used from @spi_transfer, then the
  *     two delays will be added up.
  * @pcpu_statistics: statistics for the spi_device
+ * @cs_index_mask: Bit mask of the active chipselect(s) in the chipselect array
  *
  * A @spi_device is used to interchange data between an SPI slave
  * (usually a discrete chip) and CPU memory.
        struct spi_controller   *controller;
        struct spi_controller   *master;        /* Compatibility layer */
        u32                     max_speed_hz;
-       u8                      chip_select;
+       u8                      chip_select[SPI_CS_CNT_MAX];
        u8                      bits_per_word;
        bool                    rt;
 #define SPI_NO_TX              BIT(31)         /* No transmit wire */
        void                    *controller_data;
        char                    modalias[SPI_NAME_SIZE];
        const char              *driver_override;
-       struct gpio_desc        *cs_gpiod;      /* Chip select GPIO descriptor */
+       struct gpio_desc        *cs_gpiod[SPI_CS_CNT_MAX];      /* Chip select gpio desc */
        struct spi_delay        word_delay; /* Inter-word delay */
        /* CS delays */
        struct spi_delay        cs_setup;
        /* The statistics */
        struct spi_statistics __percpu  *pcpu_statistics;
 
+       /* Bit mask of the chipselect(s) that the driver need to use from
+        * the chipselect array.When the controller is capable to handle
+        * multiple chip selects & memories are connected in parallel
+        * then more than one bit need to be set in cs_index_mask.
+        */
+       u32                     cs_index_mask : SPI_CS_CNT_MAX;
+
        /*
         * Likely need more hooks for more protocol options affecting how
         * the controller talks to each chip, like:
 
 static inline u8 spi_get_chipselect(const struct spi_device *spi, u8 idx)
 {
-       return spi->chip_select;
+       return spi->chip_select[idx];
 }
 
 static inline void spi_set_chipselect(struct spi_device *spi, u8 idx, u8 chipselect)
 {
-       spi->chip_select = chipselect;
+       spi->chip_select[idx] = chipselect;
 }
 
 static inline struct gpio_desc *spi_get_csgpiod(const struct spi_device *spi, u8 idx)
 {
-       return spi->cs_gpiod;
+       return spi->cs_gpiod[idx];
 }
 
 static inline void spi_set_csgpiod(struct spi_device *spi, u8 idx, struct gpio_desc *csgpiod)
 {
-       spi->cs_gpiod = csgpiod;
+       spi->cs_gpiod[idx] = csgpiod;
+}
+
+static inline bool spi_is_csgpiod(struct spi_device *spi)
+{
+       u8 idx;
+
+       for (idx = 0; idx < SPI_CS_CNT_MAX; idx++) {
+               if (spi_get_csgpiod(spi, idx))
+                       return true;
+       }
+       return false;
 }
 
 /**
  * @bus_lock_spinlock: spinlock for SPI bus locking
  * @bus_lock_mutex: mutex for exclusion of multiple callers
  * @bus_lock_flag: indicates that the SPI bus is locked for exclusive use
+ * @multi_cs_cap: indicates that the SPI Controller can assert/de-assert
+ *     more than one chip select at once.
  * @setup: updates the device mode and clocking records used by a
  *     device's SPI controller; protocol code may call this.  This
  *     must fail if an unrecognized or unsupported mode is requested.
 #define SPI_CONTROLLER_MUST_TX         BIT(4)  /* Requires tx */
 #define SPI_CONTROLLER_GPIO_SS         BIT(5)  /* GPIO CS must select slave */
 #define SPI_CONTROLLER_SUSPENDED       BIT(6)  /* Currently suspended */
+       /*
+        * The spi-controller has multi chip select capability and can
+        * assert/de-assert more than one chip select at once.
+        */
+#define SPI_CONTROLLER_MULTI_CS                BIT(7)
 
        /* Flag indicating if the allocation of this struct is devres-managed */
        bool                    devm_allocated;
        bool                            rt;
        bool                            auto_runtime_pm;
        bool                            cur_msg_mapped;
-       char                            last_cs;
+       char                            last_cs[SPI_CS_CNT_MAX];
+       char                            last_cs_index_mask;
        bool                            last_cs_mode_high;
        bool                            fallback;
        struct completion               xfer_completion;