]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge tag 'spi-v4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 3 Apr 2018 19:06:21 +0000 (12:06 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 3 Apr 2018 19:06:21 +0000 (12:06 -0700)
Pull SPI updates from Mark Brown:
 "A quiet release for SPI, some fixes and small updates for individual
  drivers with one bigger change from Linus Walleij which coverts the
  bitbanging SPI driver to use the GPIO descriptor API from Linus
  Walleij.

  Since GPIO descriptors were used by platform data this means there's a
  few changes in arch/ making relevant updates for a few platforms and
  one misc driver that are affected"

* tag 'spi-v4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (24 commits)
  MAINTAINERS: update Andi's e-mail
  spi: spi-atmel: Use correct enum for DMA transfer direction
  spi: sh-msiof: Document R-Car M3-N support
  spi: sh-msiof: Use correct enum for DMA transfer direction
  spi: sprd: Add the support of restarting the system
  spi: sprd: Simplify the transfer function
  spi: Fix unregistration of controller with fixed SPI bus number
  spi: rspi: use correct enum for DMA transfer direction
  spi: jcore: disable ref_clk after getting its rate
  spi: bcm-qspi: fIX some error handling paths
  spi: pxa2xx: Disable runtime PM if controller registration fails
  spi: tegra20-slink: use true and false for boolean values
  spi: Fix scatterlist elements size in spi_map_buf
  spi: atmel: init FIFOs before spi enable
  spi: orion: Prepare space for per-child options
  spi: orion: Make the error message greppable
  spi: orion: Rework GPIO CS handling
  spi: bcm2835aux: Avoid 64-bit arithmetic in xfer len calc
  spi: spi-gpio: Augment device tree bindings
  spi: spi-gpio: Rewrite to use GPIO descriptors
  ...

30 files changed:
.mailmap
Documentation/devicetree/bindings/spi/sh-msiof.txt
Documentation/devicetree/bindings/spi/spi-gpio.txt
MAINTAINERS
arch/arm/mach-pxa/cm-x300.c
arch/arm/mach-pxa/raumfeld.c
arch/arm/mach-s3c24xx/mach-jive.c
arch/arm/mach-s3c24xx/mach-qt2410.c
arch/arm/mach-s3c64xx/mach-smartq.c
arch/mips/alchemy/devboards/db1000.c
arch/mips/jz4740/board-qi_lb60.c
drivers/misc/eeprom/digsy_mtc_eeprom.c
drivers/spi/spi-atmel.c
drivers/spi/spi-bcm-qspi.c
drivers/spi/spi-bcm2835aux.c
drivers/spi/spi-dw-mid.c
drivers/spi/spi-dw.c
drivers/spi/spi-dw.h
drivers/spi/spi-gpio.c
drivers/spi/spi-jcore.c
drivers/spi/spi-orion.c
drivers/spi/spi-pxa2xx-dma.c
drivers/spi/spi-pxa2xx.c
drivers/spi/spi-pxa2xx.h
drivers/spi/spi-rspi.c
drivers/spi/spi-sh-msiof.c
drivers/spi/spi-sprd-adi.c
drivers/spi/spi-tegra20-slink.c
drivers/spi/spi.c
include/linux/spi/spi_gpio.h

index a2ce89a456c225610d38ca38499dbbe5dfd1a703..dc42cfb4130463782bad7da2e57d22162062dfdc 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -18,6 +18,7 @@ Aleksey Gorelov <aleksey_gorelov@phoenix.com>
 Aleksandar Markovic <aleksandar.markovic@mips.com> <aleksandar.markovic@imgtec.com>
 Al Viro <viro@ftp.linux.org.uk>
 Al Viro <viro@zenIV.linux.org.uk>
+Andi Shyti <andi@etezian.org> <andi.shyti@samsung.com>
 Andreas Herrmann <aherrman@de.ibm.com>
 Andrey Ryabinin <ryabinin.a.a@gmail.com> <a.ryabinin@samsung.com>
 Andrew Morton <akpm@linux-foundation.org>
index 80710f0f044891748a506374c68dfef635cf2853..39806329c19396f6ce903a6171dc20fd252ac21e 100644 (file)
@@ -10,6 +10,7 @@ Required properties:
                         "renesas,msiof-r8a7794" (R-Car E2)
                         "renesas,msiof-r8a7795" (R-Car H3)
                         "renesas,msiof-r8a7796" (R-Car M3-W)
+                        "renesas,msiof-r8a77965" (R-Car M3-N)
                         "renesas,msiof-sh73a0" (SH-Mobile AG5)
                         "renesas,sh-mobile-msiof" (generic SH-Mobile compatibile device)
                         "renesas,rcar-gen2-msiof" (generic R-Car Gen2 and RZ/G1 compatible device)
index a95603bcf6ffd9bbf99eff8ac2e5e367660e84a7..52db562f17a422df5d7db5cc5a3ece060009a657 100644 (file)
@@ -1,18 +1,30 @@
 SPI-GPIO devicetree bindings
 
+This represents a group of 3-n GPIO lines used for bit-banged SPI on dedicated
+GPIO lines.
+
 Required properties:
 
  - compatible: should be set to "spi-gpio"
  - #address-cells: should be set to <0x1>
  - ranges
- - gpio-sck: GPIO spec for the SCK line to use
- - gpio-miso: GPIO spec for the MISO line to use
- - gpio-mosi: GPIO spec for the MOSI line to use
+ - sck-gpios: GPIO spec for the SCK line to use
+ - miso-gpios: GPIO spec for the MISO line to use
+ - mosi-gpios: GPIO spec for the MOSI line to use
  - cs-gpios: GPIOs to use for chipselect lines.
              Not needed if num-chipselects = <0>.
  - num-chipselects: Number of chipselect lines. Should be <0> if a single device
                     with no chip select is connected.
 
+Deprecated bindings:
+
+These legacy GPIO line bindings can alternatively be used to define the
+GPIO lines used, they should not be used in new device trees.
+
+ - gpio-sck: GPIO spec for the SCK line to use
+ - gpio-miso: GPIO spec for the MISO line to use
+ - gpio-mosi: GPIO spec for the MOSI line to use
+
 Example:
 
        spi {
@@ -20,9 +32,9 @@ Example:
                #address-cells = <0x1>;
                ranges;
 
-               gpio-sck = <&gpio 95 0>;
-               gpio-miso = <&gpio 98 0>;
-               gpio-mosi = <&gpio 97 0>;
+               sck-gpios = <&gpio 95 0>;
+               miso-gpios = <&gpio 98 0>;
+               mosi-gpios = <&gpio 97 0>;
                cs-gpios = <&gpio 125 0>;
                num-chipselects = <1>;
 
index 6acc800aa28cd6d340399460241d4b991bb4fd29..5a9634a0eeb43004e53e50ca4d91f6103ac0d1d3 100644 (file)
@@ -12181,7 +12181,7 @@ F:      Documentation/devicetree/bindings/clock/exynos*.txt
 SAMSUNG SPI DRIVERS
 M:     Kukjin Kim <kgene@kernel.org>
 M:     Krzysztof Kozlowski <krzk@kernel.org>
-M:     Andi Shyti <andi.shyti@samsung.com>
+M:     Andi Shyti <andi@etezian.org>
 L:     linux-spi@vger.kernel.org
 L:     linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
 S:     Maintained
index c487401b6fdb5dbeffa0752ad90a8065921a6762..69d7f48a4183c07cbc102ebc83d8598773264143 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/clk.h>
 
 #include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 #include <linux/dm9000.h>
 #include <linux/leds.h>
 #include <linux/platform_data/rtc-v3020.h>
@@ -343,9 +344,6 @@ static inline void cm_x300_init_bl(void) {}
 #define LCD_SPI_BUS_NUM        (1)
 
 static struct spi_gpio_platform_data cm_x300_spi_gpio_pdata = {
-       .sck            = GPIO_LCD_SCL,
-       .mosi           = GPIO_LCD_DIN,
-       .miso           = GPIO_LCD_DOUT,
        .num_chipselect = 1,
 };
 
@@ -357,6 +355,21 @@ static struct platform_device cm_x300_spi_gpio = {
        },
 };
 
+static struct gpiod_lookup_table cm_x300_spi_gpiod_table = {
+       .dev_id         = "spi_gpio",
+       .table          = {
+               GPIO_LOOKUP("gpio-pxa", GPIO_LCD_SCL,
+                           "sck", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("gpio-pxa", GPIO_LCD_DIN,
+                           "mosi", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("gpio-pxa", GPIO_LCD_DOUT,
+                           "miso", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("gpio-pxa", GPIO_LCD_CS,
+                           "cs", GPIO_ACTIVE_HIGH),
+               { },
+       },
+};
+
 static struct tdo24m_platform_data cm_x300_tdo24m_pdata = {
        .model = TDO35S,
 };
@@ -367,7 +380,6 @@ static struct spi_board_info cm_x300_spi_devices[] __initdata = {
                .max_speed_hz           = 1000000,
                .bus_num                = LCD_SPI_BUS_NUM,
                .chip_select            = 0,
-               .controller_data        = (void *) GPIO_LCD_CS,
                .platform_data          = &cm_x300_tdo24m_pdata,
        },
 };
@@ -376,6 +388,7 @@ static void __init cm_x300_init_spi(void)
 {
        spi_register_board_info(cm_x300_spi_devices,
                                ARRAY_SIZE(cm_x300_spi_devices));
+       gpiod_add_lookup_table(&cm_x300_spi_gpiod_table);
        platform_device_register(&cm_x300_spi_gpio);
 }
 #else
index 4d5d05cf87d69b513b337632ed6c3127a5ead6cf..e7ac7dcb95e933ae9d1fb6da85ad515522e23ebd 100644 (file)
@@ -646,9 +646,6 @@ static void __init raumfeld_lcd_init(void)
  */
 
 static struct spi_gpio_platform_data raumfeld_spi_platform_data = {
-       .sck            = GPIO_SPI_CLK,
-       .mosi           = GPIO_SPI_MOSI,
-       .miso           = GPIO_SPI_MISO,
        .num_chipselect = 3,
 };
 
@@ -660,6 +657,25 @@ static struct platform_device raumfeld_spi_device = {
        }
 };
 
+static struct gpiod_lookup_table raumfeld_spi_gpiod_table = {
+       .dev_id         = "spi_gpio",
+       .table          = {
+               GPIO_LOOKUP("gpio-0", GPIO_SPI_CLK,
+                           "sck", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("gpio-0", GPIO_SPI_MOSI,
+                           "mosi", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("gpio-0", GPIO_SPI_MISO,
+                           "miso", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP_IDX("gpio-0", GPIO_SPDIF_CS,
+                               "cs", 0, GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP_IDX("gpio-0", GPIO_ACCEL_CS,
+                               "cs", 1, GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP_IDX("gpio-0", GPIO_MCLK_DAC_CS,
+                               "cs", 2, GPIO_ACTIVE_HIGH),
+               { },
+       },
+};
+
 static struct lis3lv02d_platform_data lis3_pdata = {
        .click_flags    = LIS3_CLICK_SINGLE_X |
                          LIS3_CLICK_SINGLE_Y |
@@ -680,7 +696,6 @@ static struct lis3lv02d_platform_data lis3_pdata = {
        .max_speed_hz   = 10000,                \
        .bus_num        = 0,                    \
        .chip_select    = 0,                    \
-       .controller_data = (void *) GPIO_SPDIF_CS,      \
 }
 
 #define SPI_LIS3       \
@@ -689,7 +704,6 @@ static struct lis3lv02d_platform_data lis3_pdata = {
        .max_speed_hz   = 1000000,              \
        .bus_num        = 0,                    \
        .chip_select    = 1,                    \
-       .controller_data = (void *) GPIO_ACCEL_CS,      \
        .platform_data  = &lis3_pdata,          \
        .irq            = PXA_GPIO_TO_IRQ(GPIO_ACCEL_IRQ),      \
 }
@@ -700,7 +714,6 @@ static struct lis3lv02d_platform_data lis3_pdata = {
        .max_speed_hz   = 1000000,              \
        .bus_num        = 0,                    \
        .chip_select    = 2,                    \
-       .controller_data = (void *) GPIO_MCLK_DAC_CS,   \
 }
 
 static struct spi_board_info connector_spi_devices[] __initdata = {
@@ -1066,6 +1079,7 @@ static void __init raumfeld_common_init(void)
        else
                gpio_direction_output(GPIO_SHUTDOWN_SUPPLY, 0);
 
+       gpiod_add_lookup_table(&raumfeld_spi_gpiod_table);
        platform_add_devices(ARRAY_AND_SIZE(raumfeld_common_devices));
        i2c_register_board_info(1, &raumfeld_pwri2c_board_info, 1);
 }
index a3ddbbbd6d927a0785a7fcf75fef763d3ea40253..59589a4a0d4b2023b628e9485aec98849c0f4c76 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 #include <linux/syscore_ops.h>
 #include <linux/serial_core.h>
 #include <linux/serial_s3c.h>
@@ -388,32 +389,53 @@ static struct ili9320_platdata jive_lcm_config = {
 /* LCD SPI support */
 
 static struct spi_gpio_platform_data jive_lcd_spi = {
-       .sck            = S3C2410_GPG(8),
-       .mosi           = S3C2410_GPB(8),
-       .miso           = SPI_GPIO_NO_MISO,
+       .num_chipselect = 1,
 };
 
 static struct platform_device jive_device_lcdspi = {
-       .name           = "spi-gpio",
+       .name           = "spi_gpio",
        .id             = 1,
        .dev.platform_data = &jive_lcd_spi,
 };
 
+static struct gpiod_lookup_table jive_lcdspi_gpiod_table = {
+       .dev_id         = "spi_gpio",
+       .table          = {
+               GPIO_LOOKUP("GPIOG", 8,
+                           "sck", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("GPIOB", 8,
+                           "mosi", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("GPIOB", 7,
+                           "cs", GPIO_ACTIVE_HIGH),
+               { },
+       },
+};
 
 /* WM8750 audio code SPI definition */
 
 static struct spi_gpio_platform_data jive_wm8750_spi = {
-       .sck            = S3C2410_GPB(4),
-       .mosi           = S3C2410_GPB(9),
-       .miso           = SPI_GPIO_NO_MISO,
+       .num_chipselect = 1,
 };
 
 static struct platform_device jive_device_wm8750 = {
-       .name           = "spi-gpio",
+       .name           = "spi_gpio",
        .id             = 2,
        .dev.platform_data = &jive_wm8750_spi,
 };
 
+static struct gpiod_lookup_table jive_wm8750_gpiod_table = {
+       .dev_id         = "spi_gpio",
+       .table          = {
+               GPIO_LOOKUP("GPIOB", 4,
+                           "gpio-sck", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("GPIOB", 9,
+                           "gpio-mosi", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("GPIOH", 10,
+                           "cs", GPIO_ACTIVE_HIGH),
+               { },
+       },
+};
+
 /* JIVE SPI devices. */
 
 static struct spi_board_info __initdata jive_spi_devs[] = {
@@ -424,14 +446,12 @@ static struct spi_board_info __initdata jive_spi_devs[] = {
                .mode           = SPI_MODE_3,   /* CPOL=1, CPHA=1 */
                .max_speed_hz   = 100000,
                .platform_data  = &jive_lcm_config,
-               .controller_data = (void *)S3C2410_GPB(7),
        }, {
                .modalias       = "WM8750",
                .bus_num        = 2,
                .chip_select    = 0,
                .mode           = SPI_MODE_0,   /* CPOL=0, CPHA=0 */
                .max_speed_hz   = 100000,
-               .controller_data = (void *)S3C2410_GPH(10),
        },
 };
 
@@ -619,25 +639,12 @@ static void __init jive_machine_init(void)
        /** TODO - check that this is after the cmdline option! */
        s3c_nand_set_platdata(&jive_nand_info);
 
-       /* initialise the spi */
-
        gpio_request(S3C2410_GPG(13), "lcm reset");
        gpio_direction_output(S3C2410_GPG(13), 0);
 
-       gpio_request(S3C2410_GPB(7), "jive spi");
-       gpio_direction_output(S3C2410_GPB(7), 1);
-
        gpio_request_one(S3C2410_GPB(6), GPIOF_OUT_INIT_LOW, NULL);
        gpio_free(S3C2410_GPB(6));
 
-       gpio_request_one(S3C2410_GPG(8), GPIOF_OUT_INIT_HIGH, NULL);
-       gpio_free(S3C2410_GPG(8));
-
-       /* initialise the WM8750 spi */
-
-       gpio_request(S3C2410_GPH(10), "jive wm8750 spi");
-       gpio_direction_output(S3C2410_GPH(10), 1);
-
        /* Turn off suspend on both USB ports, and switch the
         * selectable USB port to USB device mode. */
 
@@ -655,6 +662,8 @@ static void __init jive_machine_init(void)
 
        pm_power_off = jive_power_off;
 
+       gpiod_add_lookup_table(&jive_lcdspi_gpiod_table);
+       gpiod_add_lookup_table(&jive_wm8750_gpiod_table);
        platform_add_devices(jive_devices, ARRAY_SIZE(jive_devices));
 }
 
index 9c8373b8d9c35c01141791e24cf0425006182ea6..5d48e5b6e738726133d69ae66da316ba77c3bfca 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
@@ -194,17 +195,30 @@ static struct platform_device qt2410_led = {
 /* SPI */
 
 static struct spi_gpio_platform_data spi_gpio_cfg = {
-       .sck            = S3C2410_GPG(7),
-       .mosi           = S3C2410_GPG(6),
-       .miso           = S3C2410_GPG(5),
+       .num_chipselect = 1,
 };
 
 static struct platform_device qt2410_spi = {
-       .name           = "spi-gpio",
+       .name           = "spi_gpio",
        .id             = 1,
        .dev.platform_data = &spi_gpio_cfg,
 };
 
+static struct gpiod_lookup_table qt2410_spi_gpiod_table = {
+       .dev_id         = "spi_gpio",
+       .table          = {
+               GPIO_LOOKUP("GPIOG", 7,
+                           "sck", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("GPIOG", 6,
+                           "mosi", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("GPIOG", 5,
+                           "miso", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("GPIOB", 5,
+                           "cs", GPIO_ACTIVE_HIGH),
+               { },
+       },
+};
+
 /* Board devices */
 
 static struct platform_device *qt2410_devices[] __initdata = {
@@ -323,9 +337,7 @@ static void __init qt2410_machine_init(void)
        s3c24xx_udc_set_platdata(&qt2410_udc_cfg);
        s3c_i2c0_set_platdata(NULL);
 
-       WARN_ON(gpio_request(S3C2410_GPB(5), "spi cs"));
-       gpio_direction_output(S3C2410_GPB(5), 1);
-
+       gpiod_add_lookup_table(&qt2410_spi_gpiod_table);
        platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices));
        s3c_pm_init();
 }
index 5655fe968b1f03ebc1dd9723e3d1657c170fc339..951208f168e7105063de0f03cc4fe8190018b250 100644 (file)
@@ -206,17 +206,30 @@ static int __init smartq_lcd_setup_gpio(void)
 
 /* GPM0 -> CS */
 static struct spi_gpio_platform_data smartq_lcd_control = {
-       .sck                    = S3C64XX_GPM(1),
-       .mosi                   = S3C64XX_GPM(2),
-       .miso                   = S3C64XX_GPM(2),
+       .num_chipselect = 1,
 };
 
 static struct platform_device smartq_lcd_control_device = {
-       .name                   = "spi-gpio",
+       .name                   = "spi_gpio",
        .id                     = 1,
        .dev.platform_data      = &smartq_lcd_control,
 };
 
+static struct gpiod_lookup_table smartq_lcd_control_gpiod_table = {
+       .dev_id         = "spi_gpio",
+       .table          = {
+               GPIO_LOOKUP("GPIOM", 1,
+                           "sck", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("GPIOM", 2,
+                           "mosi", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("GPIOM", 3,
+                           "miso", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("GPIOM", 0,
+                           "cs", GPIO_ACTIVE_HIGH),
+               { },
+       },
+};
+
 static void smartq_lcd_power_set(struct plat_lcd_data *pd, unsigned int power)
 {
        gpio_direction_output(S3C64XX_GPM(3), power);
@@ -404,6 +417,7 @@ void __init smartq_machine_init(void)
        WARN_ON(smartq_wifi_init());
 
        pwm_add_table(smartq_pwm_lookup, ARRAY_SIZE(smartq_pwm_lookup));
+       gpiod_add_lookup_table(&smartq_lcd_control_gpiod_table);
        platform_add_devices(smartq_devices, ARRAY_SIZE(smartq_devices));
 
        gpiod_add_lookup_table(&smartq_audio_gpios);
index 433c4b9a9f0a92af20e31f1f16f9be5cde955b12..13e3c84859fe760c0a4c109211be06f52135c58f 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/clk.h>
 #include <linux/dma-mapping.h>
 #include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/leds.h>
@@ -447,9 +448,6 @@ static struct ads7846_platform_data db1100_touch_pd = {
 };
 
 static struct spi_gpio_platform_data db1100_spictl_pd = {
-       .sck            = 209,
-       .mosi           = 208,
-       .miso           = 207,
        .num_chipselect = 1,
 };
 
@@ -462,7 +460,6 @@ static struct spi_board_info db1100_spi_info[] __initdata = {
                .mode            = 0,
                .irq             = AU1100_GPIO21_INT,
                .platform_data   = &db1100_touch_pd,
-               .controller_data = (void *)210, /* for spi_gpio: CS# GPIO210 */
        },
 };
 
@@ -474,6 +471,24 @@ static struct platform_device db1100_spi_dev = {
        },
 };
 
+/*
+ * Alchemy GPIO 2 has its base at 200 so the GPIO lines
+ * 207 thru 210 are GPIOs at offset 7 thru 10 at this chip.
+ */
+static struct gpiod_lookup_table db1100_spi_gpiod_table = {
+       .dev_id         = "spi_gpio",
+       .table          = {
+               GPIO_LOOKUP("alchemy-gpio2", 9,
+                           "sck", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("alchemy-gpio2", 8,
+                           "mosi", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("alchemy-gpio2", 7,
+                           "miso", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("alchemy-gpio2", 10,
+                           "cs", GPIO_ACTIVE_HIGH),
+               { },
+       },
+};
 
 static struct platform_device *db1x00_devs[] = {
        &db1x00_codec_dev,
@@ -541,6 +556,7 @@ int __init db1000_dev_setup(void)
                        clk_put(p);
 
                platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs));
+               gpiod_add_lookup_table(&db1100_spi_gpiod_table);
                platform_device_register(&db1100_spi_dev);
        } else if (board == BCSR_WHOAMI_DB1000) {
                c0 = AU1000_GPIO2_INT;
index 6d7f97552200853259e6f2ba3ad06a2341423f4e..60f0767507c62c70c98cc469aff43150435b6189 100644 (file)
@@ -313,25 +313,34 @@ static struct jz4740_fb_platform_data qi_lb60_fb_pdata = {
        .pixclk_falling_edge = 1,
 };
 
-struct spi_gpio_platform_data spigpio_platform_data = {
-       .sck = JZ_GPIO_PORTC(23),
-       .mosi = JZ_GPIO_PORTC(22),
-       .miso = -1,
+struct spi_gpio_platform_data qi_lb60_spigpio_platform_data = {
        .num_chipselect = 1,
 };
 
-static struct platform_device spigpio_device = {
+static struct platform_device qi_lb60_spigpio_device = {
        .name = "spi_gpio",
        .id   = 1,
        .dev = {
-               .platform_data = &spigpio_platform_data,
+               .platform_data = &qi_lb60_spigpio_platform_data,
+       },
+};
+
+static struct gpiod_lookup_table qi_lb60_spigpio_gpio_table = {
+       .dev_id         = "spi_gpio",
+       .table          = {
+               GPIO_LOOKUP("GPIOC", 23,
+                           "sck", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("GPIOC", 22,
+                           "mosi", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("GPIOC", 21,
+                           "cs", GPIO_ACTIVE_HIGH),
+               { },
        },
 };
 
 static struct spi_board_info qi_lb60_spi_board_info[] = {
        {
                .modalias = "ili8960",
-               .controller_data = (void *)JZ_GPIO_PORTC(21),
                .chip_select = 0,
                .bus_num = 1,
                .max_speed_hz = 30 * 1000,
@@ -435,7 +444,7 @@ static struct platform_device *jz_platform_devices[] __initdata = {
        &jz4740_mmc_device,
        &jz4740_nand_device,
        &qi_lb60_keypad,
-       &spigpio_device,
+       &qi_lb60_spigpio_device,
        &jz4740_framebuffer_device,
        &jz4740_pcm_device,
        &jz4740_i2s_device,
@@ -489,6 +498,7 @@ static int __init qi_lb60_init_platform_devices(void)
 
        gpiod_add_lookup_table(&qi_lb60_audio_gpio_table);
        gpiod_add_lookup_table(&qi_lb60_nand_gpio_table);
+       gpiod_add_lookup_table(&qi_lb60_spigpio_gpio_table);
 
        spi_register_board_info(qi_lb60_spi_board_info,
                                ARRAY_SIZE(qi_lb60_spi_board_info));
index 66d9e1baeae50c86210cfdf3ed99841cf703f3a4..fbde2516c04ff70af35c003e3b7469d6f2c32b80 100644 (file)
@@ -7,9 +7,18 @@
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
+ *
+ * FIXME: this driver is used on a device-tree probed platform: it
+ * should be defined as a bit-banged SPI device and probed from the device
+ * tree and not like this with static grabbing of a few numbered GPIO
+ * lines at random.
+ *
+ * Add proper SPI and EEPROM in arch/powerpc/boot/dts/digsy_mtc.dts
+ * and delete this driver.
  */
 
 #include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
@@ -42,9 +51,6 @@ struct eeprom_93xx46_platform_data digsy_mtc_eeprom_data = {
 };
 
 static struct spi_gpio_platform_data eeprom_spi_gpio_data = {
-       .sck            = GPIO_EEPROM_CLK,
-       .mosi           = GPIO_EEPROM_DI,
-       .miso           = GPIO_EEPROM_DO,
        .num_chipselect = 1,
 };
 
@@ -56,6 +62,21 @@ static struct platform_device digsy_mtc_eeprom = {
        },
 };
 
+static struct gpiod_lookup_table eeprom_spi_gpiod_table = {
+       .dev_id         = "spi_gpio",
+       .table          = {
+               GPIO_LOOKUP("gpio@b00", GPIO_EEPROM_CLK,
+                           "sck", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("gpio@b00", GPIO_EEPROM_DI,
+                           "mosi", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("gpio@b00", GPIO_EEPROM_DO,
+                           "miso", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("gpio@b00", GPIO_EEPROM_CS,
+                           "cs", GPIO_ACTIVE_HIGH),
+               { },
+       },
+};
+
 static struct spi_board_info digsy_mtc_eeprom_info[] __initdata = {
        {
                .modalias               = "93xx46",
@@ -63,7 +84,6 @@ static struct spi_board_info digsy_mtc_eeprom_info[] __initdata = {
                .bus_num                = EE_SPI_BUS_NUM,
                .chip_select            = 0,
                .mode                   = SPI_MODE_0,
-               .controller_data        = (void *)GPIO_EEPROM_CS,
                .platform_data          = &digsy_mtc_eeprom_data,
        },
 };
@@ -78,6 +98,7 @@ static int __init digsy_mtc_eeprom_devices_init(void)
                pr_err("can't request gpio %d\n", GPIO_EEPROM_OE);
                return ret;
        }
+       gpiod_add_lookup_table(&eeprom_spi_gpiod_table);
        spi_register_board_info(digsy_mtc_eeprom_info,
                                ARRAY_SIZE(digsy_mtc_eeprom_info));
        return platform_device_register(&digsy_mtc_eeprom);
index 4a11fc0d41367c2dd92a0559f041cd24795ae5fb..3f890d16293411ba86618d54d4f8f70887aec31d 100644 (file)
@@ -768,14 +768,14 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master,
                rxdesc = dmaengine_prep_slave_single(rxchan,
                                                     as->dma_addr_rx_bbuf,
                                                     xfer->len,
-                                                    DMA_FROM_DEVICE,
+                                                    DMA_DEV_TO_MEM,
                                                     DMA_PREP_INTERRUPT |
                                                     DMA_CTRL_ACK);
        } else {
                rxdesc = dmaengine_prep_slave_sg(rxchan,
                                                 xfer->rx_sg.sgl,
                                                 xfer->rx_sg.nents,
-                                                DMA_FROM_DEVICE,
+                                                DMA_DEV_TO_MEM,
                                                 DMA_PREP_INTERRUPT |
                                                 DMA_CTRL_ACK);
        }
@@ -787,14 +787,14 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master,
                memcpy(as->addr_tx_bbuf, xfer->tx_buf, xfer->len);
                txdesc = dmaengine_prep_slave_single(txchan,
                                                     as->dma_addr_tx_bbuf,
-                                                    xfer->len, DMA_TO_DEVICE,
+                                                    xfer->len, DMA_MEM_TO_DEV,
                                                     DMA_PREP_INTERRUPT |
                                                     DMA_CTRL_ACK);
        } else {
                txdesc = dmaengine_prep_slave_sg(txchan,
                                                 xfer->tx_sg.sgl,
                                                 xfer->tx_sg.nents,
-                                                DMA_TO_DEVICE,
+                                                DMA_MEM_TO_DEV,
                                                 DMA_PREP_INTERRUPT |
                                                 DMA_CTRL_ACK);
        }
@@ -1512,6 +1512,11 @@ static void atmel_spi_init(struct atmel_spi *as)
 {
        spi_writel(as, CR, SPI_BIT(SWRST));
        spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
+
+       /* It is recommended to enable FIFOs first thing after reset */
+       if (as->fifo_size)
+               spi_writel(as, CR, SPI_BIT(FIFOEN));
+
        if (as->caps.has_wdrbt) {
                spi_writel(as, MR, SPI_BIT(WDRBT) | SPI_BIT(MODFDIS)
                                | SPI_BIT(MSTR));
@@ -1522,9 +1527,6 @@ static void atmel_spi_init(struct atmel_spi *as)
        if (as->use_pdc)
                spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS));
        spi_writel(as, CR, SPI_BIT(SPIEN));
-
-       if (as->fifo_size)
-               spi_writel(as, CR, SPI_BIT(FIFOEN));
 }
 
 static int atmel_spi_probe(struct platform_device *pdev)
index a172ab299e80316ee904a1c9277a36755699e4d4..1596d35498c5a5567bc844c11c2fd1463867dde5 100644 (file)
@@ -1247,7 +1247,7 @@ int bcm_qspi_probe(struct platform_device *pdev,
                qspi->base[MSPI]  = devm_ioremap_resource(dev, res);
                if (IS_ERR(qspi->base[MSPI])) {
                        ret = PTR_ERR(qspi->base[MSPI]);
-                       goto qspi_probe_err;
+                       goto qspi_resource_err;
                }
        } else {
                goto qspi_resource_err;
@@ -1258,7 +1258,7 @@ int bcm_qspi_probe(struct platform_device *pdev,
                qspi->base[BSPI]  = devm_ioremap_resource(dev, res);
                if (IS_ERR(qspi->base[BSPI])) {
                        ret = PTR_ERR(qspi->base[BSPI]);
-                       goto qspi_probe_err;
+                       goto qspi_resource_err;
                }
                qspi->bspi_mode = true;
        } else {
index 7428091d3f5b8ffa77ed2a3be65a114720cb4bfa..1431cb98fe403a4b7039195bf172bf47bceb6702 100644 (file)
@@ -321,7 +321,6 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master,
        struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
        unsigned long spi_hz, clk_hz, speed;
        unsigned long spi_used_hz;
-       unsigned long long xfer_time_us;
 
        /* calculate the registers to handle
         *
@@ -358,20 +357,21 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master,
        bs->rx_len = tfr->len;
        bs->pending = 0;
 
-       /* calculate the estimated time in us the transfer runs
-        * note that there are are 2 idle clocks after each
-        * chunk getting transferred - in our case the chunk size
-        * is 3 bytes, so we approximate this by 9 bits/byte
+       /* Calculate the estimated time in us the transfer runs.  Note that
+        * there are are 2 idle clocks cycles after each chunk getting
+        * transferred - in our case the chunk size is 3 bytes, so we
+        * approximate this by 9 cycles/byte.  This is used to find the number
+        * of Hz per byte per polling limit.  E.g., we can transfer 1 byte in
+        * 30 Âµs per 300,000 Hz of bus clock.
         */
-       xfer_time_us = tfr->len * 9 * 1000000;
-       do_div(xfer_time_us, spi_used_hz);
-
+#define HZ_PER_BYTE ((9 * 1000000) / BCM2835_AUX_SPI_POLLING_LIMIT_US)
        /* run in polling mode for short transfers */
-       if (xfer_time_us < BCM2835_AUX_SPI_POLLING_LIMIT_US)
+       if (tfr->len < spi_used_hz / HZ_PER_BYTE)
                return bcm2835aux_spi_transfer_one_poll(master, spi, tfr);
 
        /* run in interrupt mode for all others */
        return bcm2835aux_spi_transfer_one_irq(master, spi, tfr);
+#undef HZ_PER_BYTE
 }
 
 static int bcm2835aux_spi_prepare_message(struct spi_master *master,
index 837cb8d0bac6c9a1bd9f866192cd96950b13a68b..3db905f5f345c689ce4ffd965a9055a47f396c76 100644 (file)
@@ -112,10 +112,10 @@ static irqreturn_t dma_transfer(struct dw_spi *dws)
        return IRQ_HANDLED;
 }
 
-static bool mid_spi_can_dma(struct spi_master *master, struct spi_device *spi,
-               struct spi_transfer *xfer)
+static bool mid_spi_can_dma(struct spi_controller *master,
+               struct spi_device *spi, struct spi_transfer *xfer)
 {
-       struct dw_spi *dws = spi_master_get_devdata(master);
+       struct dw_spi *dws = spi_controller_get_devdata(master);
 
        if (!dws->dma_inited)
                return false;
index 211cc7d75bf83d37b1bcb5841a1e715ea3645d1d..f693bfe95ab9a1133e93a30b148f2b89a9499413 100644 (file)
@@ -135,7 +135,7 @@ static inline void dw_spi_debugfs_remove(struct dw_spi *dws)
 
 static void dw_spi_set_cs(struct spi_device *spi, bool enable)
 {
-       struct dw_spi *dws = spi_master_get_devdata(spi->master);
+       struct dw_spi *dws = spi_controller_get_devdata(spi->controller);
        struct chip_data *chip = spi_get_ctldata(spi);
 
        /* Chip select logic is inverted from spi_set_cs() */
@@ -250,8 +250,8 @@ static irqreturn_t interrupt_transfer(struct dw_spi *dws)
 
 static irqreturn_t dw_spi_irq(int irq, void *dev_id)
 {
-       struct spi_master *master = dev_id;
-       struct dw_spi *dws = spi_master_get_devdata(master);
+       struct spi_controller *master = dev_id;
+       struct dw_spi *dws = spi_controller_get_devdata(master);
        u16 irq_status = dw_readl(dws, DW_SPI_ISR) & 0x3f;
 
        if (!irq_status)
@@ -277,10 +277,10 @@ static int poll_transfer(struct dw_spi *dws)
        return 0;
 }
 
-static int dw_spi_transfer_one(struct spi_master *master,
+static int dw_spi_transfer_one(struct spi_controller *master,
                struct spi_device *spi, struct spi_transfer *transfer)
 {
-       struct dw_spi *dws = spi_master_get_devdata(master);
+       struct dw_spi *dws = spi_controller_get_devdata(master);
        struct chip_data *chip = spi_get_ctldata(spi);
        u8 imask = 0;
        u16 txlevel = 0;
@@ -383,10 +383,10 @@ static int dw_spi_transfer_one(struct spi_master *master,
        return 1;
 }
 
-static void dw_spi_handle_err(struct spi_master *master,
+static void dw_spi_handle_err(struct spi_controller *master,
                struct spi_message *msg)
 {
-       struct dw_spi *dws = spi_master_get_devdata(master);
+       struct dw_spi *dws = spi_controller_get_devdata(master);
 
        if (dws->dma_mapped)
                dws->dma_ops->dma_stop(dws);
@@ -471,7 +471,7 @@ static void spi_hw_init(struct device *dev, struct dw_spi *dws)
 
 int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
 {
-       struct spi_master *master;
+       struct spi_controller *master;
        int ret;
 
        BUG_ON(dws == NULL);
@@ -518,8 +518,8 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
                }
        }
 
-       spi_master_set_devdata(master, dws);
-       ret = devm_spi_register_master(dev, master);
+       spi_controller_set_devdata(master, dws);
+       ret = devm_spi_register_controller(dev, master);
        if (ret) {
                dev_err(&master->dev, "problem registering spi master\n");
                goto err_dma_exit;
@@ -534,7 +534,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
        spi_enable_chip(dws, 0);
        free_irq(dws->irq, master);
 err_free_master:
-       spi_master_put(master);
+       spi_controller_put(master);
        return ret;
 }
 EXPORT_SYMBOL_GPL(dw_spi_add_host);
@@ -556,7 +556,7 @@ int dw_spi_suspend_host(struct dw_spi *dws)
 {
        int ret;
 
-       ret = spi_master_suspend(dws->master);
+       ret = spi_controller_suspend(dws->master);
        if (ret)
                return ret;
 
@@ -570,7 +570,7 @@ int dw_spi_resume_host(struct dw_spi *dws)
        int ret;
 
        spi_hw_init(&dws->master->dev, dws);
-       ret = spi_master_resume(dws->master);
+       ret = spi_controller_resume(dws->master);
        if (ret)
                dev_err(&dws->master->dev, "fail to start queue (%d)\n", ret);
        return ret;
index 5c07cf8f19e00607c0f4d17f94c4a8d419658df1..2cde2473b3e94ba4e13c327bd4a063f9ce868cb8 100644 (file)
@@ -93,14 +93,14 @@ struct dw_spi_dma_ops {
        int (*dma_init)(struct dw_spi *dws);
        void (*dma_exit)(struct dw_spi *dws);
        int (*dma_setup)(struct dw_spi *dws, struct spi_transfer *xfer);
-       bool (*can_dma)(struct spi_master *master, struct spi_device *spi,
+       bool (*can_dma)(struct spi_controller *master, struct spi_device *spi,
                        struct spi_transfer *xfer);
        int (*dma_transfer)(struct dw_spi *dws, struct spi_transfer *xfer);
        void (*dma_stop)(struct dw_spi *dws);
 };
 
 struct dw_spi {
-       struct spi_master       *master;
+       struct spi_controller   *master;
        enum dw_ssi_type        type;
 
        void __iomem            *regs;
index 1c34c9314c8a1fab3c5bae9948775467f66017a9..b85a93cad44a1ecb117a4c9bcae161bc109a23c6 100644 (file)
@@ -2,6 +2,7 @@
  * SPI master driver using generic bitbanged GPIO
  *
  * Copyright (C) 2006,2008 David Brownell
+ * Copyright (C) 2017 Linus Walleij
  *
  * 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
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
-#include <linux/of_gpio.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
@@ -44,7 +44,11 @@ struct spi_gpio {
        struct spi_bitbang              bitbang;
        struct spi_gpio_platform_data   pdata;
        struct platform_device          *pdev;
-       unsigned long                   cs_gpios[0];
+       struct gpio_desc                *sck;
+       struct gpio_desc                *miso;
+       struct gpio_desc                *mosi;
+       struct gpio_desc                **cs_gpios;
+       bool                            has_cs;
 };
 
 /*----------------------------------------------------------------------*/
@@ -77,13 +81,6 @@ struct spi_gpio {
 
 #define GENERIC_BITBANG        /* vs tight inlines */
 
-/* all functions referencing these symbols must define pdata */
-#define SPI_MISO_GPIO  ((pdata)->miso)
-#define SPI_MOSI_GPIO  ((pdata)->mosi)
-#define SPI_SCK_GPIO   ((pdata)->sck)
-
-#define SPI_N_CHIPSEL  ((pdata)->num_chipselect)
-
 #endif
 
 /*----------------------------------------------------------------------*/
@@ -105,25 +102,27 @@ spi_to_pdata(const struct spi_device *spi)
        return &spi_to_spi_gpio(spi)->pdata;
 }
 
-/* this is #defined to avoid unused-variable warnings when inlining */
-#define pdata          spi_to_pdata(spi)
-
+/* These helpers are in turn called by the bitbang inlines */
 static inline void setsck(const struct spi_device *spi, int is_on)
 {
-       gpio_set_value_cansleep(SPI_SCK_GPIO, is_on);
+       struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
+
+       gpiod_set_value_cansleep(spi_gpio->sck, is_on);
 }
 
 static inline void setmosi(const struct spi_device *spi, int is_on)
 {
-       gpio_set_value_cansleep(SPI_MOSI_GPIO, is_on);
+       struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
+
+       gpiod_set_value_cansleep(spi_gpio->mosi, is_on);
 }
 
 static inline int getmiso(const struct spi_device *spi)
 {
-       return !!gpio_get_value_cansleep(SPI_MISO_GPIO);
-}
+       struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
 
-#undef pdata
+       return !!gpiod_get_value_cansleep(spi_gpio->miso);
+}
 
 /*
  * NOTE:  this clocks "as fast as we can".  It "should" be a function of the
@@ -216,123 +215,89 @@ static u32 spi_gpio_spec_txrx_word_mode3(struct spi_device *spi,
 static void spi_gpio_chipselect(struct spi_device *spi, int is_active)
 {
        struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
-       unsigned long cs = spi_gpio->cs_gpios[spi->chip_select];
 
-       /* set initial clock polarity */
+       /* set initial clock line level */
        if (is_active)
-               setsck(spi, spi->mode & SPI_CPOL);
+               gpiod_set_value_cansleep(spi_gpio->sck, spi->mode & SPI_CPOL);
+
+       /* Drive chip select line, if we have one */
+       if (spi_gpio->has_cs) {
+               struct gpio_desc *cs = spi_gpio->cs_gpios[spi->chip_select];
 
-       if (cs != SPI_GPIO_NO_CHIPSELECT) {
-               /* SPI is normally active-low */
-               gpio_set_value_cansleep(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active);
+               /* SPI chip selects are normally active-low */
+               gpiod_set_value_cansleep(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active);
        }
 }
 
 static int spi_gpio_setup(struct spi_device *spi)
 {
-       unsigned long           cs;
+       struct gpio_desc        *cs;
        int                     status = 0;
        struct spi_gpio         *spi_gpio = spi_to_spi_gpio(spi);
-       struct device_node      *np = spi->master->dev.of_node;
-
-       if (np) {
-               /*
-                * In DT environments, the CS GPIOs have already been
-                * initialized from the "cs-gpios" property of the node.
-                */
-               cs = spi_gpio->cs_gpios[spi->chip_select];
-       } else {
-               /*
-                * ... otherwise, take it from spi->controller_data
-                */
-               cs = (uintptr_t) spi->controller_data;
-       }
 
-       if (!spi->controller_state) {
-               if (cs != SPI_GPIO_NO_CHIPSELECT) {
-                       status = gpio_request(cs, dev_name(&spi->dev));
-                       if (status)
-                               return status;
-                       status = gpio_direction_output(cs,
-                                       !(spi->mode & SPI_CS_HIGH));
-               }
-       }
-       if (!status) {
-               /* in case it was initialized from static board data */
-               spi_gpio->cs_gpios[spi->chip_select] = cs;
+       /*
+        * The CS GPIOs have already been
+        * initialized from the descriptor lookup.
+        */
+       cs = spi_gpio->cs_gpios[spi->chip_select];
+       if (!spi->controller_state && cs)
+               status = gpiod_direction_output(cs,
+                                               !(spi->mode & SPI_CS_HIGH));
+
+       if (!status)
                status = spi_bitbang_setup(spi);
-       }
 
-       if (status) {
-               if (!spi->controller_state && cs != SPI_GPIO_NO_CHIPSELECT)
-                       gpio_free(cs);
-       }
        return status;
 }
 
 static void spi_gpio_cleanup(struct spi_device *spi)
 {
-       struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
-       unsigned long cs = spi_gpio->cs_gpios[spi->chip_select];
-
-       if (cs != SPI_GPIO_NO_CHIPSELECT)
-               gpio_free(cs);
        spi_bitbang_cleanup(spi);
 }
 
-static int spi_gpio_alloc(unsigned pin, const char *label, bool is_in)
-{
-       int value;
-
-       value = gpio_request(pin, label);
-       if (value == 0) {
-               if (is_in)
-                       value = gpio_direction_input(pin);
-               else
-                       value = gpio_direction_output(pin, 0);
-       }
-       return value;
-}
-
-static int spi_gpio_request(struct spi_gpio_platform_data *pdata,
-                           const char *label, u16 *res_flags)
+/*
+ * It can be convenient to use this driver with pins that have alternate
+ * functions associated with a "native" SPI controller if a driver for that
+ * controller is not available, or is missing important functionality.
+ *
+ * On platforms which can do so, configure MISO with a weak pullup unless
+ * there's an external pullup on that signal.  That saves power by avoiding
+ * floating signals.  (A weak pulldown would save power too, but many
+ * drivers expect to see all-ones data as the no slave "response".)
+ */
+static int spi_gpio_request(struct device *dev,
+                           struct spi_gpio *spi_gpio,
+                           unsigned int num_chipselects,
+                           u16 *mflags)
 {
-       int value;
-
-       /* NOTE:  SPI_*_GPIO symbols may reference "pdata" */
+       int i;
 
-       if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI) {
-               value = spi_gpio_alloc(SPI_MOSI_GPIO, label, false);
-               if (value)
-                       goto done;
-       } else {
+       spi_gpio->mosi = devm_gpiod_get_optional(dev, "mosi", GPIOD_OUT_LOW);
+       if (IS_ERR(spi_gpio->mosi))
+               return PTR_ERR(spi_gpio->mosi);
+       if (!spi_gpio->mosi)
                /* HW configuration without MOSI pin */
-               *res_flags |= SPI_MASTER_NO_TX;
-       }
+               *mflags |= SPI_MASTER_NO_TX;
 
-       if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO) {
-               value = spi_gpio_alloc(SPI_MISO_GPIO, label, true);
-               if (value)
-                       goto free_mosi;
-       } else {
+       spi_gpio->miso = devm_gpiod_get_optional(dev, "miso", GPIOD_IN);
+       if (IS_ERR(spi_gpio->miso))
+               return PTR_ERR(spi_gpio->miso);
+       if (!spi_gpio->miso)
                /* HW configuration without MISO pin */
-               *res_flags |= SPI_MASTER_NO_RX;
-       }
+               *mflags |= SPI_MASTER_NO_RX;
 
-       value = spi_gpio_alloc(SPI_SCK_GPIO, label, false);
-       if (value)
-               goto free_miso;
+       spi_gpio->sck = devm_gpiod_get(dev, "sck", GPIOD_OUT_LOW);
+       if (IS_ERR(spi_gpio->mosi))
+               return PTR_ERR(spi_gpio->mosi);
 
-       goto done;
+       for (i = 0; i < num_chipselects; i++) {
+               spi_gpio->cs_gpios[i] = devm_gpiod_get_index(dev, "cs",
+                                                            i, GPIOD_OUT_HIGH);
+               if (IS_ERR(spi_gpio->cs_gpios[i]))
+                       return PTR_ERR(spi_gpio->cs_gpios[i]);
+       }
 
-free_miso:
-       if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)
-               gpio_free(SPI_MISO_GPIO);
-free_mosi:
-       if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI)
-               gpio_free(SPI_MOSI_GPIO);
-done:
-       return value;
+       return 0;
 }
 
 #ifdef CONFIG_OF
@@ -358,26 +323,6 @@ static int spi_gpio_probe_dt(struct platform_device *pdev)
        if (!pdata)
                return -ENOMEM;
 
-       ret = of_get_named_gpio(np, "gpio-sck", 0);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "gpio-sck property not found\n");
-               goto error_free;
-       }
-       pdata->sck = ret;
-
-       ret = of_get_named_gpio(np, "gpio-miso", 0);
-       if (ret < 0) {
-               dev_info(&pdev->dev, "gpio-miso property not found, switching to no-rx mode\n");
-               pdata->miso = SPI_GPIO_NO_MISO;
-       } else
-               pdata->miso = ret;
-
-       ret = of_get_named_gpio(np, "gpio-mosi", 0);
-       if (ret < 0) {
-               dev_info(&pdev->dev, "gpio-mosi property not found, switching to no-tx mode\n");
-               pdata->mosi = SPI_GPIO_NO_MOSI;
-       } else
-               pdata->mosi = ret;
 
        ret = of_property_read_u32(np, "num-chipselects", &tmp);
        if (ret < 0) {
@@ -409,7 +354,6 @@ static int spi_gpio_probe(struct platform_device *pdev)
        struct spi_gpio_platform_data   *pdata;
        u16 master_flags = 0;
        bool use_of = 0;
-       int num_devices;
 
        status = spi_gpio_probe_dt(pdev);
        if (status < 0)
@@ -423,59 +367,41 @@ static int spi_gpio_probe(struct platform_device *pdev)
                return -ENODEV;
 #endif
 
-       if (use_of && !SPI_N_CHIPSEL)
-               num_devices = 1;
-       else
-               num_devices = SPI_N_CHIPSEL;
-
-       status = spi_gpio_request(pdata, dev_name(&pdev->dev), &master_flags);
-       if (status < 0)
-               return status;
+       master = spi_alloc_master(&pdev->dev, sizeof(*spi_gpio));
+       if (!master)
+               return -ENOMEM;
 
-       master = spi_alloc_master(&pdev->dev, sizeof(*spi_gpio) +
-                                       (sizeof(unsigned long) * num_devices));
-       if (!master) {
-               status = -ENOMEM;
-               goto gpio_free;
-       }
        spi_gpio = spi_master_get_devdata(master);
+
+       spi_gpio->cs_gpios = devm_kzalloc(&pdev->dev,
+                               pdata->num_chipselect * sizeof(*spi_gpio->cs_gpios),
+                               GFP_KERNEL);
+       if (!spi_gpio->cs_gpios)
+               return -ENOMEM;
+
        platform_set_drvdata(pdev, spi_gpio);
 
+       /* Determine if we have chip selects connected */
+       spi_gpio->has_cs = !!pdata->num_chipselect;
+
        spi_gpio->pdev = pdev;
        if (pdata)
                spi_gpio->pdata = *pdata;
 
+       status = spi_gpio_request(&pdev->dev, spi_gpio,
+                                 pdata->num_chipselect, &master_flags);
+       if (status)
+               return status;
+
        master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
        master->flags = master_flags;
        master->bus_num = pdev->id;
-       master->num_chipselect = num_devices;
+       /* The master needs to think there is a chipselect even if not connected */
+       master->num_chipselect = spi_gpio->has_cs ? pdata->num_chipselect : 1;
        master->setup = spi_gpio_setup;
        master->cleanup = spi_gpio_cleanup;
 #ifdef CONFIG_OF
        master->dev.of_node = pdev->dev.of_node;
-
-       if (use_of) {
-               int i;
-               struct device_node *np = pdev->dev.of_node;
-
-               /*
-                * In DT environments, take the CS GPIO from the "cs-gpios"
-                * property of the node.
-                */
-
-               if (!SPI_N_CHIPSEL)
-                       spi_gpio->cs_gpios[0] = SPI_GPIO_NO_CHIPSELECT;
-               else
-                       for (i = 0; i < SPI_N_CHIPSEL; i++) {
-                               status = of_get_named_gpio(np, "cs-gpios", i);
-                               if (status < 0) {
-                                       dev_err(&pdev->dev,
-                                               "invalid cs-gpios property\n");
-                                       goto gpio_free;
-                               }
-                               spi_gpio->cs_gpios[i] = status;
-                       }
-       }
 #endif
 
        spi_gpio->bitbang.master = master;
@@ -496,15 +422,8 @@ static int spi_gpio_probe(struct platform_device *pdev)
        spi_gpio->bitbang.flags = SPI_CS_HIGH;
 
        status = spi_bitbang_start(&spi_gpio->bitbang);
-       if (status < 0) {
-gpio_free:
-               if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)
-                       gpio_free(SPI_MISO_GPIO);
-               if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI)
-                       gpio_free(SPI_MOSI_GPIO);
-               gpio_free(SPI_SCK_GPIO);
+       if (status)
                spi_master_put(master);
-       }
 
        return status;
 }
@@ -520,11 +439,6 @@ static int spi_gpio_remove(struct platform_device *pdev)
        /* stop() unregisters child devices too */
        spi_bitbang_stop(&spi_gpio->bitbang);
 
-       if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)
-               gpio_free(SPI_MISO_GPIO);
-       if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI)
-               gpio_free(SPI_MOSI_GPIO);
-       gpio_free(SPI_SCK_GPIO);
        spi_master_put(spi_gpio->bitbang.master);
 
        return 0;
index dafed6280df3285055306df409070a73ba8283cb..702fe573a47b882b384bf340b02004b7c0486bc4 100644 (file)
@@ -184,10 +184,11 @@ static int jcore_spi_probe(struct platform_device *pdev)
         */
        clock_freq = 50000000;
        clk = devm_clk_get(&pdev->dev, "ref_clk");
-       if (!IS_ERR_OR_NULL(clk)) {
-               if (clk_enable(clk) == 0)
+       if (!IS_ERR(clk)) {
+               if (clk_prepare_enable(clk) == 0) {
                        clock_freq = clk_get_rate(clk);
-               else
+                       clk_disable_unprepare(clk);
+               } else
                        dev_warn(&pdev->dev, "could not enable ref_clk\n");
        }
        hw->clock_freq = clock_freq;
@@ -198,10 +199,8 @@ static int jcore_spi_probe(struct platform_device *pdev)
 
        /* Register our spi controller */
        err = devm_spi_register_master(&pdev->dev, master);
-       if (err) {
-               clk_disable(clk);
+       if (err)
                goto exit;
-       }
 
        return 0;
 
index deca63e82ff6884a52b405fabc208379ea107009..d01a6adc726e4b3dab7da0db259c78d518734867 100644 (file)
@@ -90,14 +90,19 @@ struct orion_direct_acc {
        u32                     size;
 };
 
+struct orion_child_options {
+       struct orion_direct_acc direct_access;
+};
+
 struct orion_spi {
        struct spi_master       *master;
        void __iomem            *base;
        struct clk              *clk;
        struct clk              *axi_clk;
        const struct orion_spi_dev *devdata;
+       int                     unused_hw_gpio;
 
-       struct orion_direct_acc direct_access[ORION_NUM_CHIPSELECTS];
+       struct orion_child_options      child[ORION_NUM_CHIPSELECTS];
 };
 
 static inline void __iomem *spi_reg(struct orion_spi *orion_spi, u32 reg)
@@ -324,13 +329,13 @@ static void orion_spi_set_cs(struct spi_device *spi, bool enable)
        struct orion_spi *orion_spi;
        int cs;
 
+       orion_spi = spi_master_get_devdata(spi->master);
+
        if (gpio_is_valid(spi->cs_gpio))
-               cs = 0;
+               cs = orion_spi->unused_hw_gpio;
        else
                cs = spi->chip_select;
 
-       orion_spi = spi_master_get_devdata(spi->master);
-
        orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, ORION_SPI_CS_MASK);
        orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG,
                                ORION_SPI_CS(cs));
@@ -435,7 +440,7 @@ orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
         * Use SPI direct write mode if base address is available. Otherwise
         * fall back to PIO mode for this transfer.
         */
-       if ((orion_spi->direct_access[cs].vaddr) && (xfer->tx_buf) &&
+       if ((orion_spi->child[cs].direct_access.vaddr) && (xfer->tx_buf) &&
            (word_len == 8)) {
                unsigned int cnt = count / 4;
                unsigned int rem = count % 4;
@@ -444,12 +449,12 @@ orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
                 * Send the TX-data to the SPI device via the direct
                 * mapped address window
                 */
-               iowrite32_rep(orion_spi->direct_access[cs].vaddr,
+               iowrite32_rep(orion_spi->child[cs].direct_access.vaddr,
                              xfer->tx_buf, cnt);
                if (rem) {
                        u32 *buf = (u32 *)xfer->tx_buf;
 
-                       iowrite8_rep(orion_spi->direct_access[cs].vaddr,
+                       iowrite8_rep(orion_spi->child[cs].direct_access.vaddr,
                                     &buf[cnt], rem);
                }
 
@@ -498,6 +503,9 @@ static int orion_spi_transfer_one(struct spi_master *master,
 
 static int orion_spi_setup(struct spi_device *spi)
 {
+       if (gpio_is_valid(spi->cs_gpio)) {
+               gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH));
+       }
        return orion_spi_setup_transfer(spi, NULL);
 }
 
@@ -620,6 +628,7 @@ static int orion_spi_probe(struct platform_device *pdev)
 
        spi = spi_master_get_devdata(master);
        spi->master = master;
+       spi->unused_hw_gpio = -1;
 
        of_id = of_match_device(orion_spi_of_match_table, &pdev->dev);
        devdata = (of_id) ? of_id->data : &orion_spi_dev_data;
@@ -702,14 +711,14 @@ static int orion_spi_probe(struct platform_device *pdev)
                 * This needs to get extended for the direct SPI-NOR / SPI-NAND
                 * support, once this gets implemented.
                 */
-               spi->direct_access[cs].vaddr = devm_ioremap(&pdev->dev,
+               spi->child[cs].direct_access.vaddr = devm_ioremap(&pdev->dev,
                                                            r->start,
                                                            PAGE_SIZE);
-               if (!spi->direct_access[cs].vaddr) {
+               if (!spi->child[cs].direct_access.vaddr) {
                        status = -ENOMEM;
                        goto out_rel_axi_clk;
                }
-               spi->direct_access[cs].size = PAGE_SIZE;
+               spi->child[cs].direct_access.size = PAGE_SIZE;
 
                dev_info(&pdev->dev, "CS%d configured for direct access\n", cs);
        }
@@ -731,8 +740,44 @@ static int orion_spi_probe(struct platform_device *pdev)
        if (status < 0)
                goto out_rel_pm;
 
+       if (master->cs_gpios) {
+               int i;
+               for (i = 0; i < master->num_chipselect; ++i) {
+                       char *gpio_name;
+
+                       if (!gpio_is_valid(master->cs_gpios[i])) {
+                               continue;
+                       }
+
+                       gpio_name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+                                       "%s-CS%d", dev_name(&pdev->dev), i);
+                       if (!gpio_name) {
+                               status = -ENOMEM;
+                               goto out_rel_master;
+                       }
+
+                       status = devm_gpio_request(&pdev->dev,
+                                       master->cs_gpios[i], gpio_name);
+                       if (status) {
+                               dev_err(&pdev->dev,
+                                       "Can't request GPIO for CS %d\n",
+                                       master->cs_gpios[i]);
+                               goto out_rel_master;
+                       }
+                       if (spi->unused_hw_gpio == -1) {
+                               dev_info(&pdev->dev,
+                                       "Selected unused HW CS#%d for any GPIO CSes\n",
+                                       i);
+                               spi->unused_hw_gpio = i;
+                       }
+               }
+       }
+
+
        return status;
 
+out_rel_master:
+       spi_unregister_master(master);
 out_rel_pm:
        pm_runtime_disable(&pdev->dev);
 out_rel_axi_clk:
index 04f3eecf5cf3a83af999e0237a95add1a919d983..3d7f66080c57a10e477d52c484a78391db6f8ea1 100644 (file)
@@ -191,7 +191,7 @@ int pxa2xx_spi_dma_setup(struct driver_data *drv_data)
 {
        struct pxa2xx_spi_master *pdata = drv_data->master_info;
        struct device *dev = &drv_data->pdev->dev;
-       struct spi_master *master = drv_data->master;
+       struct spi_controller *master = drv_data->master;
        dma_cap_mask_t mask;
 
        dma_cap_zero(mask);
@@ -215,7 +215,7 @@ int pxa2xx_spi_dma_setup(struct driver_data *drv_data)
 
 void pxa2xx_spi_dma_release(struct driver_data *drv_data)
 {
-       struct spi_master *master = drv_data->master;
+       struct spi_controller *master = drv_data->master;
 
        if (master->dma_rx) {
                dmaengine_terminate_sync(master->dma_rx);
index b0822d1dba298fced70045495f48f33d49db8ca3..82dcb88fcfba48cc24d58b5b110f99123752f8b3 100644 (file)
@@ -415,10 +415,17 @@ static void cs_deassert(struct driver_data *drv_data)
 {
        struct chip_data *chip =
                spi_get_ctldata(drv_data->master->cur_msg->spi);
+       unsigned long timeout;
 
        if (drv_data->ssp_type == CE4100_SSP)
                return;
 
+       /* Wait until SSP becomes idle before deasserting the CS */
+       timeout = jiffies + msecs_to_jiffies(10);
+       while (pxa2xx_spi_read(drv_data, SSSR) & SSSR_BSY &&
+              !time_after(jiffies, timeout))
+               cpu_relax();
+
        if (chip->cs_control) {
                chip->cs_control(PXA2XX_CS_DEASSERT);
                return;
@@ -563,7 +570,6 @@ static void giveback(struct driver_data *drv_data)
 {
        struct spi_transfer* last_transfer;
        struct spi_message *msg;
-       unsigned long timeout;
 
        msg = drv_data->master->cur_msg;
        drv_data->cur_transfer = NULL;
@@ -575,12 +581,6 @@ static void giveback(struct driver_data *drv_data)
        if (last_transfer->delay_usecs)
                udelay(last_transfer->delay_usecs);
 
-       /* Wait until SSP becomes idle before deasserting the CS */
-       timeout = jiffies + msecs_to_jiffies(10);
-       while (pxa2xx_spi_read(drv_data, SSSR) & SSSR_BSY &&
-              !time_after(jiffies, timeout))
-               cpu_relax();
-
        /* Drop chip select UNLESS cs_change is true or we are returning
         * a message with an error, or next message is for another chip
         */
@@ -962,7 +962,7 @@ static unsigned int pxa2xx_ssp_get_clk_div(struct driver_data *drv_data,
        return clk_div << 8;
 }
 
-static bool pxa2xx_spi_can_dma(struct spi_master *master,
+static bool pxa2xx_spi_can_dma(struct spi_controller *master,
                               struct spi_device *spi,
                               struct spi_transfer *xfer)
 {
@@ -976,7 +976,7 @@ static bool pxa2xx_spi_can_dma(struct spi_master *master,
 static void pump_transfers(unsigned long data)
 {
        struct driver_data *drv_data = (struct driver_data *)data;
-       struct spi_master *master = drv_data->master;
+       struct spi_controller *master = drv_data->master;
        struct spi_message *message = master->cur_msg;
        struct chip_data *chip = spi_get_ctldata(message->spi);
        u32 dma_thresh = chip->dma_threshold;
@@ -1182,10 +1182,10 @@ static void pump_transfers(unsigned long data)
        pxa2xx_spi_write(drv_data, SSCR1, cr1);
 }
 
-static int pxa2xx_spi_transfer_one_message(struct spi_master *master,
+static int pxa2xx_spi_transfer_one_message(struct spi_controller *master,
                                           struct spi_message *msg)
 {
-       struct driver_data *drv_data = spi_master_get_devdata(master);
+       struct driver_data *drv_data = spi_controller_get_devdata(master);
 
        /* Initial message state*/
        msg->state = START_STATE;
@@ -1198,9 +1198,9 @@ static int pxa2xx_spi_transfer_one_message(struct spi_master *master,
        return 0;
 }
 
-static int pxa2xx_spi_unprepare_transfer(struct spi_master *master)
+static int pxa2xx_spi_unprepare_transfer(struct spi_controller *master)
 {
-       struct driver_data *drv_data = spi_master_get_devdata(master);
+       struct driver_data *drv_data = spi_controller_get_devdata(master);
 
        /* Disable the SSP now */
        pxa2xx_spi_write(drv_data, SSCR0,
@@ -1212,7 +1212,8 @@ static int pxa2xx_spi_unprepare_transfer(struct spi_master *master)
 static int setup_cs(struct spi_device *spi, struct chip_data *chip,
                    struct pxa2xx_spi_chip *chip_info)
 {
-       struct driver_data *drv_data = spi_master_get_devdata(spi->master);
+       struct driver_data *drv_data =
+               spi_controller_get_devdata(spi->controller);
        struct gpio_desc *gpiod;
        int err = 0;
 
@@ -1270,7 +1271,8 @@ static int setup(struct spi_device *spi)
        struct pxa2xx_spi_chip *chip_info;
        struct chip_data *chip;
        const struct lpss_config *config;
-       struct driver_data *drv_data = spi_master_get_devdata(spi->master);
+       struct driver_data *drv_data =
+               spi_controller_get_devdata(spi->controller);
        uint tx_thres, tx_hi_thres, rx_thres;
 
        switch (drv_data->ssp_type) {
@@ -1410,7 +1412,8 @@ static int setup(struct spi_device *spi)
 static void cleanup(struct spi_device *spi)
 {
        struct chip_data *chip = spi_get_ctldata(spi);
-       struct driver_data *drv_data = spi_master_get_devdata(spi->master);
+       struct driver_data *drv_data =
+               spi_controller_get_devdata(spi->controller);
 
        if (!chip)
                return;
@@ -1575,9 +1578,10 @@ pxa2xx_spi_init_pdata(struct platform_device *pdev)
 }
 #endif
 
-static int pxa2xx_spi_fw_translate_cs(struct spi_master *master, unsigned cs)
+static int pxa2xx_spi_fw_translate_cs(struct spi_controller *master,
+                                     unsigned int cs)
 {
-       struct driver_data *drv_data = spi_master_get_devdata(master);
+       struct driver_data *drv_data = spi_controller_get_devdata(master);
 
        if (has_acpi_companion(&drv_data->pdev->dev)) {
                switch (drv_data->ssp_type) {
@@ -1602,7 +1606,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct pxa2xx_spi_master *platform_info;
-       struct spi_master *master;
+       struct spi_controller *master;
        struct driver_data *drv_data;
        struct ssp_device *ssp;
        const struct lpss_config *config;
@@ -1633,7 +1637,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
                pxa_ssp_free(ssp);
                return -ENOMEM;
        }
-       drv_data = spi_master_get_devdata(master);
+       drv_data = spi_controller_get_devdata(master);
        drv_data->master = master;
        drv_data->master_info = platform_info;
        drv_data->pdev = pdev;
@@ -1651,7 +1655,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
        master->unprepare_transfer_hardware = pxa2xx_spi_unprepare_transfer;
        master->fw_translate_cs = pxa2xx_spi_fw_translate_cs;
        master->auto_runtime_pm = true;
-       master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX;
+       master->flags = SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX;
 
        drv_data->ssp_type = ssp->type;
 
@@ -1793,7 +1797,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
 
        /* Register with the SPI framework */
        platform_set_drvdata(pdev, drv_data);
-       status = devm_spi_register_master(&pdev->dev, master);
+       status = devm_spi_register_controller(&pdev->dev, master);
        if (status != 0) {
                dev_err(&pdev->dev, "problem registering spi master\n");
                goto out_error_clock_enabled;
@@ -1802,12 +1806,14 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
        return status;
 
 out_error_clock_enabled:
+       pm_runtime_put_noidle(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
        clk_disable_unprepare(ssp->clk);
        pxa2xx_spi_dma_release(drv_data);
        free_irq(ssp->irq, drv_data);
 
 out_error_master_alloc:
-       spi_master_put(master);
+       spi_controller_put(master);
        pxa_ssp_free(ssp);
        return status;
 }
@@ -1858,7 +1864,7 @@ static int pxa2xx_spi_suspend(struct device *dev)
        struct ssp_device *ssp = drv_data->ssp;
        int status;
 
-       status = spi_master_suspend(drv_data->master);
+       status = spi_controller_suspend(drv_data->master);
        if (status != 0)
                return status;
        pxa2xx_spi_write(drv_data, SSCR0, 0);
@@ -1884,7 +1890,7 @@ static int pxa2xx_spi_resume(struct device *dev)
                lpss_ssp_setup(drv_data);
 
        /* Start the queue running */
-       status = spi_master_resume(drv_data->master);
+       status = spi_controller_resume(drv_data->master);
        if (status != 0) {
                dev_err(dev, "problem starting queue (%d)\n", status);
                return status;
index 94f7b0713281929c5706555af3a9ed8418045670..513ec6c6e25b310b62d0024cd6c71a23c4890b5e 100644 (file)
@@ -31,7 +31,7 @@ struct driver_data {
 
        /* SPI framework hookup */
        enum pxa_ssp_type ssp_type;
-       struct spi_master *master;
+       struct spi_controller *master;
 
        /* PXA hookup */
        struct pxa2xx_spi_master *master_info;
index 0835a8d88fb8f85ab5ae44a4aa74d94121d19d87..95dc4d78618df29c2b15d92fa6d11e3b84bb7ed1 100644 (file)
@@ -535,7 +535,7 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
        /* First prepare and submit the DMA request(s), as this may fail */
        if (rx) {
                desc_rx = dmaengine_prep_slave_sg(rspi->master->dma_rx,
-                                       rx->sgl, rx->nents, DMA_FROM_DEVICE,
+                                       rx->sgl, rx->nents, DMA_DEV_TO_MEM,
                                        DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
                if (!desc_rx) {
                        ret = -EAGAIN;
@@ -555,7 +555,7 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
 
        if (tx) {
                desc_tx = dmaengine_prep_slave_sg(rspi->master->dma_tx,
-                                       tx->sgl, tx->nents, DMA_TO_DEVICE,
+                                       tx->sgl, tx->nents, DMA_MEM_TO_DEV,
                                        DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
                if (!desc_tx) {
                        ret = -EAGAIN;
index c5dcfb434a498b2742b8496b1ac122ee1414da8a..ae086aab57d51edc2c8014160f4abeab365ea9cc 100644 (file)
@@ -752,7 +752,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
        if (rx) {
                ier_bits |= IER_RDREQE | IER_RDMAE;
                desc_rx = dmaengine_prep_slave_single(p->master->dma_rx,
-                                       p->rx_dma_addr, len, DMA_FROM_DEVICE,
+                                       p->rx_dma_addr, len, DMA_DEV_TO_MEM,
                                        DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
                if (!desc_rx)
                        return -EAGAIN;
@@ -769,7 +769,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
                dma_sync_single_for_device(p->master->dma_tx->device->dev,
                                           p->tx_dma_addr, len, DMA_TO_DEVICE);
                desc_tx = dmaengine_prep_slave_single(p->master->dma_tx,
-                                       p->tx_dma_addr, len, DMA_TO_DEVICE,
+                                       p->tx_dma_addr, len, DMA_MEM_TO_DEV,
                                        DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
                if (!desc_tx) {
                        ret = -EAGAIN;
index 5993bdbf79e46e9aa2b4bde4ab29729cf623f90a..197d4b0d81afac0bd8945f53a9b78393b344698e 100644 (file)
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: GPL-2.0
  */
 
+#include <linux/delay.h>
 #include <linux/hwspinlock.h>
 #include <linux/init.h>
 #include <linux/io.h>
@@ -12,6 +13,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/reboot.h>
 #include <linux/spi/spi.h>
 #include <linux/sizes.h>
 
 #define ADI_READ_TIMEOUT               2000
 #define REG_ADDR_LOW_MASK              GENMASK(11, 0)
 
+/* Registers definitions for PMIC watchdog controller */
+#define REG_WDG_LOAD_LOW               0x80
+#define REG_WDG_LOAD_HIGH              0x84
+#define REG_WDG_CTRL                   0x88
+#define REG_WDG_LOCK                   0xa0
+
+/* Bits definitions for register REG_WDG_CTRL */
+#define BIT_WDG_RUN                    BIT(1)
+#define BIT_WDG_RST                    BIT(3)
+
+/* Registers definitions for PMIC */
+#define PMIC_RST_STATUS                        0xee8
+#define PMIC_MODULE_EN                 0xc08
+#define PMIC_CLK_EN                    0xc18
+#define BIT_WDG_EN                     BIT(2)
+
+/* Definition of PMIC reset status register */
+#define HWRST_STATUS_RECOVERY          0x20
+#define HWRST_STATUS_NORMAL            0x40
+#define HWRST_STATUS_ALARM             0x50
+#define HWRST_STATUS_SLEEP             0x60
+#define HWRST_STATUS_FASTBOOT          0x30
+#define HWRST_STATUS_SPECIAL           0x70
+#define HWRST_STATUS_PANIC             0x80
+#define HWRST_STATUS_CFTREBOOT         0x90
+#define HWRST_STATUS_AUTODLOADER       0xa0
+#define HWRST_STATUS_IQMODE            0xb0
+#define HWRST_STATUS_SPRDISK           0xc0
+
+/* Use default timeout 50 ms that converts to watchdog values */
+#define WDG_LOAD_VAL                   ((50 * 1000) / 32768)
+#define WDG_LOAD_MASK                  GENMASK(15, 0)
+#define WDG_UNLOCK_KEY                 0xe551
+
 struct sprd_adi {
        struct spi_controller   *ctlr;
        struct device           *dev;
@@ -74,6 +110,7 @@ struct sprd_adi {
        struct hwspinlock       *hwlock;
        unsigned long           slave_vbase;
        unsigned long           slave_pbase;
+       struct notifier_block   restart_handler;
 };
 
 static int sprd_adi_check_paddr(struct sprd_adi *sadi, u32 paddr)
@@ -123,7 +160,17 @@ static int sprd_adi_fifo_is_full(struct sprd_adi *sadi)
 static int sprd_adi_read(struct sprd_adi *sadi, u32 reg_paddr, u32 *read_val)
 {
        int read_timeout = ADI_READ_TIMEOUT;
+       unsigned long flags;
        u32 val, rd_addr;
+       int ret;
+
+       ret = hwspin_lock_timeout_irqsave(sadi->hwlock,
+                                         ADI_HWSPINLOCK_TIMEOUT,
+                                         &flags);
+       if (ret) {
+               dev_err(sadi->dev, "get the hw lock failed\n");
+               return ret;
+       }
 
        /*
         * Set the physical register address need to read into RD_CMD register,
@@ -147,7 +194,8 @@ static int sprd_adi_read(struct sprd_adi *sadi, u32 reg_paddr, u32 *read_val)
 
        if (read_timeout == 0) {
                dev_err(sadi->dev, "ADI read timeout\n");
-               return -EBUSY;
+               ret = -EBUSY;
+               goto out;
        }
 
        /*
@@ -161,21 +209,35 @@ static int sprd_adi_read(struct sprd_adi *sadi, u32 reg_paddr, u32 *read_val)
        if (rd_addr != (reg_paddr & REG_ADDR_LOW_MASK)) {
                dev_err(sadi->dev, "read error, reg addr = 0x%x, val = 0x%x\n",
                        reg_paddr, val);
-               return -EIO;
+               ret = -EIO;
+               goto out;
        }
 
        *read_val = val & RD_VALUE_MASK;
-       return 0;
+
+out:
+       hwspin_unlock_irqrestore(sadi->hwlock, &flags);
+       return ret;
 }
 
-static int sprd_adi_write(struct sprd_adi *sadi, unsigned long reg, u32 val)
+static int sprd_adi_write(struct sprd_adi *sadi, u32 reg_paddr, u32 val)
 {
+       unsigned long reg = sprd_adi_to_vaddr(sadi, reg_paddr);
        u32 timeout = ADI_FIFO_DRAIN_TIMEOUT;
+       unsigned long flags;
        int ret;
 
+       ret = hwspin_lock_timeout_irqsave(sadi->hwlock,
+                                         ADI_HWSPINLOCK_TIMEOUT,
+                                         &flags);
+       if (ret) {
+               dev_err(sadi->dev, "get the hw lock failed\n");
+               return ret;
+       }
+
        ret = sprd_adi_drain_fifo(sadi);
        if (ret < 0)
-               return ret;
+               goto out;
 
        /*
         * we should wait for write fifo is empty before writing data to PMIC
@@ -192,10 +254,12 @@ static int sprd_adi_write(struct sprd_adi *sadi, unsigned long reg, u32 val)
 
        if (timeout == 0) {
                dev_err(sadi->dev, "write fifo is full\n");
-               return -EBUSY;
+               ret = -EBUSY;
        }
 
-       return 0;
+out:
+       hwspin_unlock_irqrestore(sadi->hwlock, &flags);
+       return ret;
 }
 
 static int sprd_adi_transfer_one(struct spi_controller *ctlr,
@@ -203,7 +267,6 @@ static int sprd_adi_transfer_one(struct spi_controller *ctlr,
                                 struct spi_transfer *t)
 {
        struct sprd_adi *sadi = spi_controller_get_devdata(ctlr);
-       unsigned long flags, virt_reg;
        u32 phy_reg, val;
        int ret;
 
@@ -214,16 +277,7 @@ static int sprd_adi_transfer_one(struct spi_controller *ctlr,
                if (ret)
                        return ret;
 
-               ret = hwspin_lock_timeout_irqsave(sadi->hwlock,
-                                                 ADI_HWSPINLOCK_TIMEOUT,
-                                                 &flags);
-               if (ret) {
-                       dev_err(sadi->dev, "get the hw lock failed\n");
-                       return ret;
-               }
-
                ret = sprd_adi_read(sadi, phy_reg, &val);
-               hwspin_unlock_irqrestore(sadi->hwlock, &flags);
                if (ret)
                        return ret;
 
@@ -241,19 +295,8 @@ static int sprd_adi_transfer_one(struct spi_controller *ctlr,
                if (ret)
                        return ret;
 
-               virt_reg = sprd_adi_to_vaddr(sadi, phy_reg);
                val = *p;
-
-               ret = hwspin_lock_timeout_irqsave(sadi->hwlock,
-                                                 ADI_HWSPINLOCK_TIMEOUT,
-                                                 &flags);
-               if (ret) {
-                       dev_err(sadi->dev, "get the hw lock failed\n");
-                       return ret;
-               }
-
-               ret = sprd_adi_write(sadi, virt_reg, val);
-               hwspin_unlock_irqrestore(sadi->hwlock, &flags);
+               ret = sprd_adi_write(sadi, phy_reg, val);
                if (ret)
                        return ret;
        } else {
@@ -264,6 +307,72 @@ static int sprd_adi_transfer_one(struct spi_controller *ctlr,
        return 0;
 }
 
+static int sprd_adi_restart_handler(struct notifier_block *this,
+                                   unsigned long mode, void *cmd)
+{
+       struct sprd_adi *sadi = container_of(this, struct sprd_adi,
+                                            restart_handler);
+       u32 val, reboot_mode = 0;
+
+       if (!cmd)
+               reboot_mode = HWRST_STATUS_NORMAL;
+       else if (!strncmp(cmd, "recovery", 8))
+               reboot_mode = HWRST_STATUS_RECOVERY;
+       else if (!strncmp(cmd, "alarm", 5))
+               reboot_mode = HWRST_STATUS_ALARM;
+       else if (!strncmp(cmd, "fastsleep", 9))
+               reboot_mode = HWRST_STATUS_SLEEP;
+       else if (!strncmp(cmd, "bootloader", 10))
+               reboot_mode = HWRST_STATUS_FASTBOOT;
+       else if (!strncmp(cmd, "panic", 5))
+               reboot_mode = HWRST_STATUS_PANIC;
+       else if (!strncmp(cmd, "special", 7))
+               reboot_mode = HWRST_STATUS_SPECIAL;
+       else if (!strncmp(cmd, "cftreboot", 9))
+               reboot_mode = HWRST_STATUS_CFTREBOOT;
+       else if (!strncmp(cmd, "autodloader", 11))
+               reboot_mode = HWRST_STATUS_AUTODLOADER;
+       else if (!strncmp(cmd, "iqmode", 6))
+               reboot_mode = HWRST_STATUS_IQMODE;
+       else if (!strncmp(cmd, "sprdisk", 7))
+               reboot_mode = HWRST_STATUS_SPRDISK;
+       else
+               reboot_mode = HWRST_STATUS_NORMAL;
+
+       /* Record the reboot mode */
+       sprd_adi_read(sadi, sadi->slave_pbase + PMIC_RST_STATUS, &val);
+       val |= reboot_mode;
+       sprd_adi_write(sadi, sadi->slave_pbase + PMIC_RST_STATUS, val);
+
+       /* Enable the interface clock of the watchdog */
+       sprd_adi_read(sadi, sadi->slave_pbase + PMIC_MODULE_EN, &val);
+       val |= BIT_WDG_EN;
+       sprd_adi_write(sadi, sadi->slave_pbase + PMIC_MODULE_EN, val);
+
+       /* Enable the work clock of the watchdog */
+       sprd_adi_read(sadi, sadi->slave_pbase + PMIC_CLK_EN, &val);
+       val |= BIT_WDG_EN;
+       sprd_adi_write(sadi, sadi->slave_pbase + PMIC_CLK_EN, val);
+
+       /* Unlock the watchdog */
+       sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_LOCK, WDG_UNLOCK_KEY);
+
+       /* Load the watchdog timeout value, 50ms is always enough. */
+       sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_LOAD_LOW,
+                      WDG_LOAD_VAL & WDG_LOAD_MASK);
+       sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_LOAD_HIGH, 0);
+
+       /* Start the watchdog to reset system */
+       sprd_adi_read(sadi, sadi->slave_pbase + REG_WDG_CTRL, &val);
+       val |= BIT_WDG_RUN | BIT_WDG_RST;
+       sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_CTRL, val);
+
+       mdelay(1000);
+
+       dev_emerg(sadi->dev, "Unable to restart system\n");
+       return NOTIFY_DONE;
+}
+
 static void sprd_adi_hw_init(struct sprd_adi *sadi)
 {
        struct device_node *np = sadi->dev->of_node;
@@ -377,6 +486,14 @@ static int sprd_adi_probe(struct platform_device *pdev)
                goto free_hwlock;
        }
 
+       sadi->restart_handler.notifier_call = sprd_adi_restart_handler;
+       sadi->restart_handler.priority = 128;
+       ret = register_restart_handler(&sadi->restart_handler);
+       if (ret) {
+               dev_err(&pdev->dev, "can not register restart handler\n");
+               goto free_hwlock;
+       }
+
        return 0;
 
 free_hwlock:
@@ -391,6 +508,7 @@ static int sprd_adi_remove(struct platform_device *pdev)
        struct spi_controller *ctlr = dev_get_drvdata(&pdev->dev);
        struct sprd_adi *sadi = spi_controller_get_devdata(ctlr);
 
+       unregister_restart_handler(&sadi->restart_handler);
        hwspin_lock_free(sadi->hwlock);
        return 0;
 }
index 3e12d5f87ee4412b086649c8f2312fb3cc9e30a8..6f7b946b5cedf103cbed9886d7ec3079bbdcf6de 100644 (file)
@@ -276,10 +276,10 @@ static unsigned tegra_slink_calculate_curr_xfer_param(
        tspi->bytes_per_word = DIV_ROUND_UP(bits_per_word, 8);
 
        if (bits_per_word == 8 || bits_per_word == 16) {
-               tspi->is_packed = 1;
+               tspi->is_packed = true;
                tspi->words_per_32bit = 32/bits_per_word;
        } else {
-               tspi->is_packed = 0;
+               tspi->is_packed = false;
                tspi->words_per_32bit = 1;
        }
        tspi->packed_size = tegra_slink_get_packed_size(tspi, t);
index b33a727a0158b19ebae1364a21fd8c9dff22e4e5..7b213faa0a2b7247837372a4bc4a537e1c9a2ad1 100644 (file)
@@ -779,8 +779,14 @@ static int spi_map_buf(struct spi_controller *ctlr, struct device *dev,
        for (i = 0; i < sgs; i++) {
 
                if (vmalloced_buf || kmap_buf) {
-                       min = min_t(size_t,
-                                   len, desc_len - offset_in_page(buf));
+                       /*
+                        * Next scatterlist entry size is the minimum between
+                        * the desc_len and the remaining buffer length that
+                        * fits in a page.
+                        */
+                       min = min_t(size_t, desc_len,
+                                   min_t(size_t, len,
+                                         PAGE_SIZE - offset_in_page(buf)));
                        if (vmalloced_buf)
                                vm_page = vmalloc_to_page(buf);
                        else
@@ -2254,12 +2260,6 @@ void spi_unregister_controller(struct spi_controller *ctlr)
        mutex_lock(&board_lock);
        found = idr_find(&spi_master_idr, id);
        mutex_unlock(&board_lock);
-       if (found != ctlr) {
-               dev_dbg(&ctlr->dev,
-                       "attempting to delete unregistered controller [%s]\n",
-                       dev_name(&ctlr->dev));
-               return;
-       }
        if (ctlr->queued) {
                if (spi_destroy_queue(ctlr))
                        dev_err(&ctlr->dev, "queue remove failed\n");
@@ -2272,7 +2272,8 @@ void spi_unregister_controller(struct spi_controller *ctlr)
        device_unregister(&ctlr->dev);
        /* free bus id */
        mutex_lock(&board_lock);
-       idr_remove(&spi_master_idr, id);
+       if (found == ctlr)
+               idr_remove(&spi_master_idr, id);
        mutex_unlock(&board_lock);
 }
 EXPORT_SYMBOL_GPL(spi_unregister_controller);
index e7bd89a59cd10d77b41fda118205b12078d616c1..9e7e83d8645b667be1437c3bc705ac8f98144d6e 100644 (file)
@@ -8,64 +8,17 @@
  *   - id the same as the SPI bus number it implements
  *   - dev.platform data pointing to a struct spi_gpio_platform_data
  *
- * Or, see the driver code for information about speedups that are
- * possible on platforms that support inlined access for GPIOs (no
- * spi_gpio_platform_data is used).
- *
- * Use spi_board_info with these busses in the usual way, being sure
- * that the controller_data being the GPIO used for each device's
- * chipselect:
- *
- *     static struct spi_board_info ... [] = {
- *     ...
- *             // this slave uses GPIO 42 for its chipselect
- *             .controller_data = (void *) 42,
- *     ...
- *             // this one uses GPIO 86 for its chipselect
- *             .controller_data = (void *) 86,
- *     ...
- *     };
- *
- * If chipselect is not used (there's only one device on the bus), assign
- * SPI_GPIO_NO_CHIPSELECT to the controller_data:
- *             .controller_data = (void *) SPI_GPIO_NO_CHIPSELECT;
- *
- * If the MISO or MOSI pin is not available then it should be set to
- * SPI_GPIO_NO_MISO or SPI_GPIO_NO_MOSI.
+ * Use spi_board_info with these busses in the usual way.
  *
  * If the bitbanged bus is later switched to a "native" controller,
  * that platform_device and controller_data should be removed.
  */
 
-#define SPI_GPIO_NO_CHIPSELECT         ((unsigned long)-1l)
-#define SPI_GPIO_NO_MISO               ((unsigned long)-1l)
-#define SPI_GPIO_NO_MOSI               ((unsigned long)-1l)
-
 /**
  * struct spi_gpio_platform_data - parameter for bitbanged SPI master
- * @sck: number of the GPIO used for clock output
- * @mosi: number of the GPIO used for Master Output, Slave In (MOSI) data
- * @miso: number of the GPIO used for Master Input, Slave Output (MISO) data
  * @num_chipselect: how many slaves to allow
- *
- * All GPIO signals used with the SPI bus managed through this driver
- * (chipselects, MOSI, MISO, SCK) must be configured as GPIOs, instead
- * of some alternate function.
- *
- * It can be convenient to use this driver with pins that have alternate
- * functions associated with a "native" SPI controller if a driver for that
- * controller is not available, or is missing important functionality.
- *
- * On platforms which can do so, configure MISO with a weak pullup unless
- * there's an external pullup on that signal.  That saves power by avoiding
- * floating signals.  (A weak pulldown would save power too, but many
- * drivers expect to see all-ones data as the no slave "response".)
  */
 struct spi_gpio_platform_data {
-       unsigned        sck;
-       unsigned long   mosi;
-       unsigned long   miso;
-
        u16             num_chipselect;
 };