|
@@ -773,14 +773,6 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
|
|
return ERR_PTR(-ENOMEM);
|
|
return ERR_PTR(-ENOMEM);
|
|
}
|
|
}
|
|
|
|
|
|
- cs->line = of_get_named_gpio(data_np, "cs-gpio", 0);
|
|
|
|
- if (!gpio_is_valid(cs->line)) {
|
|
|
|
- dev_err(&spi->dev, "chip select gpio is not specified or invalid\n");
|
|
|
|
- kfree(cs);
|
|
|
|
- of_node_put(data_np);
|
|
|
|
- return ERR_PTR(-EINVAL);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
of_property_read_u32(data_np, "samsung,spi-feedback-delay", &fb_delay);
|
|
of_property_read_u32(data_np, "samsung,spi-feedback-delay", &fb_delay);
|
|
cs->fb_delay = fb_delay;
|
|
cs->fb_delay = fb_delay;
|
|
of_node_put(data_np);
|
|
of_node_put(data_np);
|
|
@@ -801,9 +793,16 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
|
|
int err;
|
|
int err;
|
|
|
|
|
|
sdd = spi_master_get_devdata(spi->master);
|
|
sdd = spi_master_get_devdata(spi->master);
|
|
- if (!cs && spi->dev.of_node) {
|
|
|
|
|
|
+ if (spi->dev.of_node) {
|
|
cs = s3c64xx_get_slave_ctrldata(spi);
|
|
cs = s3c64xx_get_slave_ctrldata(spi);
|
|
spi->controller_data = cs;
|
|
spi->controller_data = cs;
|
|
|
|
+ } else if (cs) {
|
|
|
|
+ /* On non-DT platforms the SPI core will set spi->cs_gpio
|
|
|
|
+ * to -ENOENT. The GPIO pin used to drive the chip select
|
|
|
|
+ * is defined by using platform data so spi->cs_gpio value
|
|
|
|
+ * has to be override to have the proper GPIO pin number.
|
|
|
|
+ */
|
|
|
|
+ spi->cs_gpio = cs->line;
|
|
}
|
|
}
|
|
|
|
|
|
if (IS_ERR_OR_NULL(cs)) {
|
|
if (IS_ERR_OR_NULL(cs)) {
|
|
@@ -812,17 +811,17 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
|
|
}
|
|
}
|
|
|
|
|
|
if (!spi_get_ctldata(spi)) {
|
|
if (!spi_get_ctldata(spi)) {
|
|
- err = gpio_request_one(cs->line, GPIOF_OUT_INIT_HIGH,
|
|
|
|
- dev_name(&spi->dev));
|
|
|
|
- if (err) {
|
|
|
|
- dev_err(&spi->dev,
|
|
|
|
- "Failed to get /CS gpio [%d]: %d\n",
|
|
|
|
- cs->line, err);
|
|
|
|
- goto err_gpio_req;
|
|
|
|
|
|
+ if (gpio_is_valid(spi->cs_gpio)) {
|
|
|
|
+ err = gpio_request_one(spi->cs_gpio, GPIOF_OUT_INIT_HIGH,
|
|
|
|
+ dev_name(&spi->dev));
|
|
|
|
+ if (err) {
|
|
|
|
+ dev_err(&spi->dev,
|
|
|
|
+ "Failed to get /CS gpio [%d]: %d\n",
|
|
|
|
+ spi->cs_gpio, err);
|
|
|
|
+ goto err_gpio_req;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- spi->cs_gpio = cs->line;
|
|
|
|
-
|
|
|
|
spi_set_ctldata(spi, cs);
|
|
spi_set_ctldata(spi, cs);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -875,7 +874,8 @@ setup_exit:
|
|
/* setup() returns with device de-selected */
|
|
/* setup() returns with device de-selected */
|
|
writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
|
|
writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
|
|
|
|
|
|
- gpio_free(cs->line);
|
|
|
|
|
|
+ if (gpio_is_valid(spi->cs_gpio))
|
|
|
|
+ gpio_free(spi->cs_gpio);
|
|
spi_set_ctldata(spi, NULL);
|
|
spi_set_ctldata(spi, NULL);
|
|
|
|
|
|
err_gpio_req:
|
|
err_gpio_req:
|
|
@@ -889,11 +889,20 @@ static void s3c64xx_spi_cleanup(struct spi_device *spi)
|
|
{
|
|
{
|
|
struct s3c64xx_spi_csinfo *cs = spi_get_ctldata(spi);
|
|
struct s3c64xx_spi_csinfo *cs = spi_get_ctldata(spi);
|
|
|
|
|
|
- if (cs) {
|
|
|
|
|
|
+ if (gpio_is_valid(spi->cs_gpio)) {
|
|
gpio_free(spi->cs_gpio);
|
|
gpio_free(spi->cs_gpio);
|
|
if (spi->dev.of_node)
|
|
if (spi->dev.of_node)
|
|
kfree(cs);
|
|
kfree(cs);
|
|
|
|
+ else {
|
|
|
|
+ /* On non-DT platforms, the SPI core sets
|
|
|
|
+ * spi->cs_gpio to -ENOENT and .setup()
|
|
|
|
+ * overrides it with the GPIO pin value
|
|
|
|
+ * passed using platform data.
|
|
|
|
+ */
|
|
|
|
+ spi->cs_gpio = -ENOENT;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+
|
|
spi_set_ctldata(spi, NULL);
|
|
spi_set_ctldata(spi, NULL);
|
|
}
|
|
}
|
|
|
|
|