Commit 75dcc7ef authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'spi-v4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi

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
  ...
parents b51c4354 0930437e
...@@ -18,6 +18,7 @@ Aleksey Gorelov <aleksey_gorelov@phoenix.com> ...@@ -18,6 +18,7 @@ Aleksey Gorelov <aleksey_gorelov@phoenix.com>
Aleksandar Markovic <aleksandar.markovic@mips.com> <aleksandar.markovic@imgtec.com> Aleksandar Markovic <aleksandar.markovic@mips.com> <aleksandar.markovic@imgtec.com>
Al Viro <viro@ftp.linux.org.uk> Al Viro <viro@ftp.linux.org.uk>
Al Viro <viro@zenIV.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> Andreas Herrmann <aherrman@de.ibm.com>
Andrey Ryabinin <ryabinin.a.a@gmail.com> <a.ryabinin@samsung.com> Andrey Ryabinin <ryabinin.a.a@gmail.com> <a.ryabinin@samsung.com>
Andrew Morton <akpm@linux-foundation.org> Andrew Morton <akpm@linux-foundation.org>
......
...@@ -10,6 +10,7 @@ Required properties: ...@@ -10,6 +10,7 @@ Required properties:
"renesas,msiof-r8a7794" (R-Car E2) "renesas,msiof-r8a7794" (R-Car E2)
"renesas,msiof-r8a7795" (R-Car H3) "renesas,msiof-r8a7795" (R-Car H3)
"renesas,msiof-r8a7796" (R-Car M3-W) "renesas,msiof-r8a7796" (R-Car M3-W)
"renesas,msiof-r8a77965" (R-Car M3-N)
"renesas,msiof-sh73a0" (SH-Mobile AG5) "renesas,msiof-sh73a0" (SH-Mobile AG5)
"renesas,sh-mobile-msiof" (generic SH-Mobile compatibile device) "renesas,sh-mobile-msiof" (generic SH-Mobile compatibile device)
"renesas,rcar-gen2-msiof" (generic R-Car Gen2 and RZ/G1 compatible device) "renesas,rcar-gen2-msiof" (generic R-Car Gen2 and RZ/G1 compatible device)
......
SPI-GPIO devicetree bindings SPI-GPIO devicetree bindings
This represents a group of 3-n GPIO lines used for bit-banged SPI on dedicated
GPIO lines.
Required properties: Required properties:
- compatible: should be set to "spi-gpio" - compatible: should be set to "spi-gpio"
- #address-cells: should be set to <0x1> - #address-cells: should be set to <0x1>
- ranges - ranges
- gpio-sck: GPIO spec for the SCK line to use - sck-gpios: GPIO spec for the SCK line to use
- gpio-miso: GPIO spec for the MISO line to use - miso-gpios: GPIO spec for the MISO line to use
- gpio-mosi: GPIO spec for the MOSI line to use - mosi-gpios: GPIO spec for the MOSI line to use
- cs-gpios: GPIOs to use for chipselect lines. - cs-gpios: GPIOs to use for chipselect lines.
Not needed if num-chipselects = <0>. Not needed if num-chipselects = <0>.
- num-chipselects: Number of chipselect lines. Should be <0> if a single device - num-chipselects: Number of chipselect lines. Should be <0> if a single device
with no chip select is connected. 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: Example:
spi { spi {
...@@ -20,9 +32,9 @@ Example: ...@@ -20,9 +32,9 @@ Example:
#address-cells = <0x1>; #address-cells = <0x1>;
ranges; ranges;
gpio-sck = <&gpio 95 0>; sck-gpios = <&gpio 95 0>;
gpio-miso = <&gpio 98 0>; miso-gpios = <&gpio 98 0>;
gpio-mosi = <&gpio 97 0>; mosi-gpios = <&gpio 97 0>;
cs-gpios = <&gpio 125 0>; cs-gpios = <&gpio 125 0>;
num-chipselects = <1>; num-chipselects = <1>;
......
...@@ -12181,7 +12181,7 @@ F: Documentation/devicetree/bindings/clock/exynos*.txt ...@@ -12181,7 +12181,7 @@ F: Documentation/devicetree/bindings/clock/exynos*.txt
SAMSUNG SPI DRIVERS SAMSUNG SPI DRIVERS
M: Kukjin Kim <kgene@kernel.org> M: Kukjin Kim <kgene@kernel.org>
M: Krzysztof Kozlowski <krzk@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-spi@vger.kernel.org
L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
S: Maintained S: Maintained
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/dm9000.h> #include <linux/dm9000.h>
#include <linux/leds.h> #include <linux/leds.h>
#include <linux/platform_data/rtc-v3020.h> #include <linux/platform_data/rtc-v3020.h>
...@@ -343,9 +344,6 @@ static inline void cm_x300_init_bl(void) {} ...@@ -343,9 +344,6 @@ static inline void cm_x300_init_bl(void) {}
#define LCD_SPI_BUS_NUM (1) #define LCD_SPI_BUS_NUM (1)
static struct spi_gpio_platform_data cm_x300_spi_gpio_pdata = { 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, .num_chipselect = 1,
}; };
...@@ -357,6 +355,21 @@ static struct platform_device cm_x300_spi_gpio = { ...@@ -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 = { static struct tdo24m_platform_data cm_x300_tdo24m_pdata = {
.model = TDO35S, .model = TDO35S,
}; };
...@@ -367,7 +380,6 @@ static struct spi_board_info cm_x300_spi_devices[] __initdata = { ...@@ -367,7 +380,6 @@ static struct spi_board_info cm_x300_spi_devices[] __initdata = {
.max_speed_hz = 1000000, .max_speed_hz = 1000000,
.bus_num = LCD_SPI_BUS_NUM, .bus_num = LCD_SPI_BUS_NUM,
.chip_select = 0, .chip_select = 0,
.controller_data = (void *) GPIO_LCD_CS,
.platform_data = &cm_x300_tdo24m_pdata, .platform_data = &cm_x300_tdo24m_pdata,
}, },
}; };
...@@ -376,6 +388,7 @@ static void __init cm_x300_init_spi(void) ...@@ -376,6 +388,7 @@ static void __init cm_x300_init_spi(void)
{ {
spi_register_board_info(cm_x300_spi_devices, spi_register_board_info(cm_x300_spi_devices,
ARRAY_SIZE(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); platform_device_register(&cm_x300_spi_gpio);
} }
#else #else
......
...@@ -646,9 +646,6 @@ static void __init raumfeld_lcd_init(void) ...@@ -646,9 +646,6 @@ static void __init raumfeld_lcd_init(void)
*/ */
static struct spi_gpio_platform_data raumfeld_spi_platform_data = { 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, .num_chipselect = 3,
}; };
...@@ -660,6 +657,25 @@ static struct platform_device raumfeld_spi_device = { ...@@ -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 = { static struct lis3lv02d_platform_data lis3_pdata = {
.click_flags = LIS3_CLICK_SINGLE_X | .click_flags = LIS3_CLICK_SINGLE_X |
LIS3_CLICK_SINGLE_Y | LIS3_CLICK_SINGLE_Y |
...@@ -680,7 +696,6 @@ static struct lis3lv02d_platform_data lis3_pdata = { ...@@ -680,7 +696,6 @@ static struct lis3lv02d_platform_data lis3_pdata = {
.max_speed_hz = 10000, \ .max_speed_hz = 10000, \
.bus_num = 0, \ .bus_num = 0, \
.chip_select = 0, \ .chip_select = 0, \
.controller_data = (void *) GPIO_SPDIF_CS, \
} }
#define SPI_LIS3 \ #define SPI_LIS3 \
...@@ -689,7 +704,6 @@ static struct lis3lv02d_platform_data lis3_pdata = { ...@@ -689,7 +704,6 @@ static struct lis3lv02d_platform_data lis3_pdata = {
.max_speed_hz = 1000000, \ .max_speed_hz = 1000000, \
.bus_num = 0, \ .bus_num = 0, \
.chip_select = 1, \ .chip_select = 1, \
.controller_data = (void *) GPIO_ACCEL_CS, \
.platform_data = &lis3_pdata, \ .platform_data = &lis3_pdata, \
.irq = PXA_GPIO_TO_IRQ(GPIO_ACCEL_IRQ), \ .irq = PXA_GPIO_TO_IRQ(GPIO_ACCEL_IRQ), \
} }
...@@ -700,7 +714,6 @@ static struct lis3lv02d_platform_data lis3_pdata = { ...@@ -700,7 +714,6 @@ static struct lis3lv02d_platform_data lis3_pdata = {
.max_speed_hz = 1000000, \ .max_speed_hz = 1000000, \
.bus_num = 0, \ .bus_num = 0, \
.chip_select = 2, \ .chip_select = 2, \
.controller_data = (void *) GPIO_MCLK_DAC_CS, \
} }
static struct spi_board_info connector_spi_devices[] __initdata = { static struct spi_board_info connector_spi_devices[] __initdata = {
...@@ -1066,6 +1079,7 @@ static void __init raumfeld_common_init(void) ...@@ -1066,6 +1079,7 @@ static void __init raumfeld_common_init(void)
else else
gpio_direction_output(GPIO_SHUTDOWN_SUPPLY, 0); gpio_direction_output(GPIO_SHUTDOWN_SUPPLY, 0);
gpiod_add_lookup_table(&raumfeld_spi_gpiod_table);
platform_add_devices(ARRAY_AND_SIZE(raumfeld_common_devices)); platform_add_devices(ARRAY_AND_SIZE(raumfeld_common_devices));
i2c_register_board_info(1, &raumfeld_pwri2c_board_info, 1); i2c_register_board_info(1, &raumfeld_pwri2c_board_info, 1);
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/syscore_ops.h> #include <linux/syscore_ops.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <linux/serial_s3c.h> #include <linux/serial_s3c.h>
...@@ -388,32 +389,53 @@ static struct ili9320_platdata jive_lcm_config = { ...@@ -388,32 +389,53 @@ static struct ili9320_platdata jive_lcm_config = {
/* LCD SPI support */ /* LCD SPI support */
static struct spi_gpio_platform_data jive_lcd_spi = { static struct spi_gpio_platform_data jive_lcd_spi = {
.sck = S3C2410_GPG(8), .num_chipselect = 1,
.mosi = S3C2410_GPB(8),
.miso = SPI_GPIO_NO_MISO,
}; };
static struct platform_device jive_device_lcdspi = { static struct platform_device jive_device_lcdspi = {
.name = "spi-gpio", .name = "spi_gpio",
.id = 1, .id = 1,
.dev.platform_data = &jive_lcd_spi, .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 */ /* WM8750 audio code SPI definition */
static struct spi_gpio_platform_data jive_wm8750_spi = { static struct spi_gpio_platform_data jive_wm8750_spi = {
.sck = S3C2410_GPB(4), .num_chipselect = 1,
.mosi = S3C2410_GPB(9),
.miso = SPI_GPIO_NO_MISO,
}; };
static struct platform_device jive_device_wm8750 = { static struct platform_device jive_device_wm8750 = {
.name = "spi-gpio", .name = "spi_gpio",
.id = 2, .id = 2,
.dev.platform_data = &jive_wm8750_spi, .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. */ /* JIVE SPI devices. */
static struct spi_board_info __initdata jive_spi_devs[] = { static struct spi_board_info __initdata jive_spi_devs[] = {
...@@ -424,14 +446,12 @@ 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 */ .mode = SPI_MODE_3, /* CPOL=1, CPHA=1 */
.max_speed_hz = 100000, .max_speed_hz = 100000,
.platform_data = &jive_lcm_config, .platform_data = &jive_lcm_config,
.controller_data = (void *)S3C2410_GPB(7),
}, { }, {
.modalias = "WM8750", .modalias = "WM8750",
.bus_num = 2, .bus_num = 2,
.chip_select = 0, .chip_select = 0,
.mode = SPI_MODE_0, /* CPOL=0, CPHA=0 */ .mode = SPI_MODE_0, /* CPOL=0, CPHA=0 */
.max_speed_hz = 100000, .max_speed_hz = 100000,
.controller_data = (void *)S3C2410_GPH(10),
}, },
}; };
...@@ -619,25 +639,12 @@ static void __init jive_machine_init(void) ...@@ -619,25 +639,12 @@ static void __init jive_machine_init(void)
/** TODO - check that this is after the cmdline option! */ /** TODO - check that this is after the cmdline option! */
s3c_nand_set_platdata(&jive_nand_info); s3c_nand_set_platdata(&jive_nand_info);
/* initialise the spi */
gpio_request(S3C2410_GPG(13), "lcm reset"); gpio_request(S3C2410_GPG(13), "lcm reset");
gpio_direction_output(S3C2410_GPG(13), 0); 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_request_one(S3C2410_GPB(6), GPIOF_OUT_INIT_LOW, NULL);
gpio_free(S3C2410_GPB(6)); 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 /* Turn off suspend on both USB ports, and switch the
* selectable USB port to USB device mode. */ * selectable USB port to USB device mode. */
...@@ -655,6 +662,8 @@ static void __init jive_machine_init(void) ...@@ -655,6 +662,8 @@ static void __init jive_machine_init(void)
pm_power_off = jive_power_off; 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)); platform_add_devices(jive_devices, ARRAY_SIZE(jive_devices));
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
...@@ -194,17 +195,30 @@ static struct platform_device qt2410_led = { ...@@ -194,17 +195,30 @@ static struct platform_device qt2410_led = {
/* SPI */ /* SPI */
static struct spi_gpio_platform_data spi_gpio_cfg = { static struct spi_gpio_platform_data spi_gpio_cfg = {
.sck = S3C2410_GPG(7), .num_chipselect = 1,
.mosi = S3C2410_GPG(6),
.miso = S3C2410_GPG(5),
}; };
static struct platform_device qt2410_spi = { static struct platform_device qt2410_spi = {
.name = "spi-gpio", .name = "spi_gpio",
.id = 1, .id = 1,
.dev.platform_data = &spi_gpio_cfg, .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 */ /* Board devices */
static struct platform_device *qt2410_devices[] __initdata = { static struct platform_device *qt2410_devices[] __initdata = {
...@@ -323,9 +337,7 @@ static void __init qt2410_machine_init(void) ...@@ -323,9 +337,7 @@ static void __init qt2410_machine_init(void)
s3c24xx_udc_set_platdata(&qt2410_udc_cfg); s3c24xx_udc_set_platdata(&qt2410_udc_cfg);
s3c_i2c0_set_platdata(NULL); s3c_i2c0_set_platdata(NULL);
WARN_ON(gpio_request(S3C2410_GPB(5), "spi cs")); gpiod_add_lookup_table(&qt2410_spi_gpiod_table);
gpio_direction_output(S3C2410_GPB(5), 1);
platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices)); platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices));
s3c_pm_init(); s3c_pm_init();
} }
......
...@@ -206,17 +206,30 @@ static int __init smartq_lcd_setup_gpio(void) ...@@ -206,17 +206,30 @@ static int __init smartq_lcd_setup_gpio(void)
/* GPM0 -> CS */ /* GPM0 -> CS */
static struct spi_gpio_platform_data smartq_lcd_control = { static struct spi_gpio_platform_data smartq_lcd_control = {
.sck = S3C64XX_GPM(1), .num_chipselect = 1,
.mosi = S3C64XX_GPM(2),
.miso = S3C64XX_GPM(2),
}; };
static struct platform_device smartq_lcd_control_device = { static struct platform_device smartq_lcd_control_device = {
.name = "spi-gpio", .name = "spi_gpio",
.id = 1, .id = 1,
.dev.platform_data = &smartq_lcd_control, .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) static void smartq_lcd_power_set(struct plat_lcd_data *pd, unsigned int power)
{ {
gpio_direction_output(S3C64XX_GPM(3), power); gpio_direction_output(S3C64XX_GPM(3), power);
...@@ -404,6 +417,7 @@ void __init smartq_machine_init(void) ...@@ -404,6 +417,7 @@ void __init smartq_machine_init(void)
WARN_ON(smartq_wifi_init()); WARN_ON(smartq_wifi_init());
pwm_add_table(smartq_pwm_lookup, ARRAY_SIZE(smartq_pwm_lookup)); 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)); platform_add_devices(smartq_devices, ARRAY_SIZE(smartq_devices));
gpiod_add_lookup_table(&smartq_audio_gpios); gpiod_add_lookup_table(&smartq_audio_gpios);
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/leds.h> #include <linux/leds.h>
...@@ -447,9 +448,6 @@ static struct ads7846_platform_data db1100_touch_pd = { ...@@ -447,9 +448,6 @@ static struct ads7846_platform_data db1100_touch_pd = {
}; };
static struct spi_gpio_platform_data db1100_spictl_pd = { static struct spi_gpio_platform_data db1100_spictl_pd = {
.sck = 209,
.mosi = 208,
.miso = 207,
.num_chipselect = 1, .num_chipselect = 1,
}; };
...@@ -462,7 +460,6 @@ static struct spi_board_info db1100_spi_info[] __initdata = { ...@@ -462,7 +460,6 @@ static struct spi_board_info db1100_spi_info[] __initdata = {
.mode = 0, .mode = 0,
.irq = AU1100_GPIO21_INT, .irq = AU1100_GPIO21_INT,
.platform_data = &db1100_touch_pd, .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 = { ...@@ -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[] = { static struct platform_device *db1x00_devs[] = {
&db1x00_codec_dev, &db1x00_codec_dev,
...@@ -541,6 +556,7 @@ int __init db1000_dev_setup(void) ...@@ -541,6 +556,7 @@ int __init db1000_dev_setup(void)
clk_put(p); clk_put(p);
platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs)); platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs));
gpiod_add_lookup_table(&db1100_spi_gpiod_table);
platform_device_register(&db1100_spi_dev); platform_device_register(&db1100_spi_dev);
} else if (board == BCSR_WHOAMI_DB1000) { } else if (board == BCSR_WHOAMI_DB1000) {
c0 = AU1000_GPIO2_INT; c0 = AU1000_GPIO2_INT;
......
...@@ -313,25 +313,34 @@ static struct jz4740_fb_platform_data qi_lb60_fb_pdata = { ...@@ -313,25 +313,34 @@ static struct jz4740_fb_platform_data qi_lb60_fb_pdata = {
.pixclk_falling_edge = 1, .pixclk_falling_edge = 1,
}; };
struct spi_gpio_platform_data spigpio_platform_data = { struct spi_gpio_platform_data qi_lb60_spigpio_platform_data = {
.sck = JZ_GPIO_PORTC(23),
.mosi = JZ_GPIO_PORTC(22),
.miso = -1,
.num_chipselect = 1, .num_chipselect = 1,
}; };
static struct platform_device spigpio_device = { static struct platform_device qi_lb60_spigpio_device = {
.name = "spi_gpio", .name = "spi_gpio",
.id = 1, .id = 1,
.dev = { .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[] = { static struct spi_board_info qi_lb60_spi_board_info[] = {
{ {
.modalias = "ili8960", .modalias = "ili8960",
.controller_data = (void *)JZ_GPIO_PORTC(21),
.chip_select = 0, .chip_select = 0,
.bus_num = 1, .bus_num = 1,
.max_speed_hz = 30 * 1000, .max_speed_hz = 30 * 1000,
...@@ -435,7 +444,7 @@ static struct platform_device *jz_platform_devices[] __initdata = { ...@@ -435,7 +444,7 @@ static struct platform_device *jz_platform_devices[] __initdata = {
&jz4740_mmc_device, &jz4740_mmc_device,
&jz4740_nand_device, &jz4740_nand_device,
&qi_lb60_keypad, &qi_lb60_keypad,
&spigpio_device, &qi_lb60_spigpio_device,
&jz4740_framebuffer_device, &jz4740_framebuffer_device,
&jz4740_pcm_device, &jz4740_pcm_device,
&jz4740_i2s_device, &jz4740_i2s_device,
...@@ -489,6 +498,7 @@ static int __init qi_lb60_init_platform_devices(void) ...@@ -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_audio_gpio_table);
gpiod_add_lookup_table(&qi_lb60_nand_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, spi_register_board_info(qi_lb60_spi_board_info,
ARRAY_SIZE(qi_lb60_spi_board_info)); ARRAY_SIZE(qi_lb60_spi_board_info));
......
...@@ -7,9 +7,18 @@ ...@@ -7,9 +7,18 @@
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * 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.h>
#include <linux/gpio/machine.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
...@@ -42,9 +51,6 @@ struct eeprom_93xx46_platform_data digsy_mtc_eeprom_data = { ...@@ -42,9 +51,6 @@ struct eeprom_93xx46_platform_data digsy_mtc_eeprom_data = {
}; };
static struct spi_gpio_platform_data eeprom_spi_gpio_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, .num_chipselect = 1,
}; };
...@@ -56,6 +62,21 @@ static struct platform_device digsy_mtc_eeprom = { ...@@ -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 = { static struct spi_board_info digsy_mtc_eeprom_info[] __initdata = {
{ {
.modalias = "93xx46", .modalias = "93xx46",
...@@ -63,7 +84,6 @@ static struct spi_board_info digsy_mtc_eeprom_info[] __initdata = { ...@@ -63,7 +84,6 @@ static struct spi_board_info digsy_mtc_eeprom_info[] __initdata = {
.bus_num = EE_SPI_BUS_NUM, .bus_num = EE_SPI_BUS_NUM,
.chip_select = 0, .chip_select = 0,
.mode = SPI_MODE_0, .mode = SPI_MODE_0,
.controller_data = (void *)GPIO_EEPROM_CS,
.platform_data = &digsy_mtc_eeprom_data, .platform_data = &digsy_mtc_eeprom_data,
}, },
}; };
...@@ -78,6 +98,7 @@ static int __init digsy_mtc_eeprom_devices_init(void) ...@@ -78,6 +98,7 @@ static int __init digsy_mtc_eeprom_devices_init(void)
pr_err("can't request gpio %d\n", GPIO_EEPROM_OE); pr_err("can't request gpio %d\n", GPIO_EEPROM_OE);
return ret; return ret;
} }
gpiod_add_lookup_table(&eeprom_spi_gpiod_table);
spi_register_board_info(digsy_mtc_eeprom_info, spi_register_board_info(digsy_mtc_eeprom_info,
ARRAY_SIZE(digsy_mtc_eeprom_info)); ARRAY_SIZE(digsy_mtc_eeprom_info));
return platform_device_register(&digsy_mtc_eeprom); return platform_device_register(&digsy_mtc_eeprom);
......
...@@ -768,14 +768,14 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master, ...@@ -768,14 +768,14 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master,
rxdesc = dmaengine_prep_slave_single(rxchan, rxdesc = dmaengine_prep_slave_single(rxchan,
as->dma_addr_rx_bbuf, as->dma_addr_rx_bbuf,
xfer->len, xfer->len,
DMA_FROM_DEVICE, DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT | DMA_PREP_INTERRUPT |
DMA_CTRL_ACK); DMA_CTRL_ACK);
} else { } else {
rxdesc = dmaengine_prep_slave_sg(rxchan, rxdesc = dmaengine_prep_slave_sg(rxchan,
xfer->rx_sg.sgl, xfer->rx_sg.sgl,
xfer->rx_sg.nents, xfer->rx_sg.nents,
DMA_FROM_DEVICE, DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT | DMA_PREP_INTERRUPT |
DMA_CTRL_ACK); DMA_CTRL_ACK);
} }
...@@ -787,14 +787,14 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master, ...@@ -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); memcpy(as->addr_tx_bbuf, xfer->tx_buf, xfer->len);
txdesc = dmaengine_prep_slave_single(txchan, txdesc = dmaengine_prep_slave_single(txchan,
as->dma_addr_tx_bbuf, as->dma_addr_tx_bbuf,
xfer->len, DMA_TO_DEVICE, xfer->len, DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_PREP_INTERRUPT |
DMA_CTRL_ACK); DMA_CTRL_ACK);
} else { } else {
txdesc = dmaengine_prep_slave_sg(txchan, txdesc = dmaengine_prep_slave_sg(txchan,
xfer->tx_sg.sgl, xfer->tx_sg.sgl,
xfer->tx_sg.nents, xfer->tx_sg.nents,
DMA_TO_DEVICE, DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_PREP_INTERRUPT |
DMA_CTRL_ACK); DMA_CTRL_ACK);
} }
...@@ -1512,6 +1512,11 @@ static void atmel_spi_init(struct atmel_spi *as) ...@@ -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));
spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ 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) { if (as->caps.has_wdrbt) {
spi_writel(as, MR, SPI_BIT(WDRBT) | SPI_BIT(MODFDIS) spi_writel(as, MR, SPI_BIT(WDRBT) | SPI_BIT(MODFDIS)
| SPI_BIT(MSTR)); | SPI_BIT(MSTR));
...@@ -1522,9 +1527,6 @@ static void atmel_spi_init(struct atmel_spi *as) ...@@ -1522,9 +1527,6 @@ static void atmel_spi_init(struct atmel_spi *as)
if (as->use_pdc) if (as->use_pdc)
spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS)); spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS));
spi_writel(as, CR, SPI_BIT(SPIEN)); 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) static int atmel_spi_probe(struct platform_device *pdev)
......
...@@ -1247,7 +1247,7 @@ int bcm_qspi_probe(struct platform_device *pdev, ...@@ -1247,7 +1247,7 @@ int bcm_qspi_probe(struct platform_device *pdev,
qspi->base[MSPI] = devm_ioremap_resource(dev, res); qspi->base[MSPI] = devm_ioremap_resource(dev, res);
if (IS_ERR(qspi->base[MSPI])) { if (IS_ERR(qspi->base[MSPI])) {
ret = PTR_ERR(qspi->base[MSPI]); ret = PTR_ERR(qspi->base[MSPI]);
goto qspi_probe_err; goto qspi_resource_err;
} }
} else { } else {
goto qspi_resource_err; goto qspi_resource_err;
...@@ -1258,7 +1258,7 @@ int bcm_qspi_probe(struct platform_device *pdev, ...@@ -1258,7 +1258,7 @@ int bcm_qspi_probe(struct platform_device *pdev,
qspi->base[BSPI] = devm_ioremap_resource(dev, res); qspi->base[BSPI] = devm_ioremap_resource(dev, res);
if (IS_ERR(qspi->base[BSPI])) { if (IS_ERR(qspi->base[BSPI])) {
ret = PTR_ERR(qspi->base[BSPI]); ret = PTR_ERR(qspi->base[BSPI]);
goto qspi_probe_err; goto qspi_resource_err;
} }
qspi->bspi_mode = true; qspi->bspi_mode = true;
} else { } else {
......
...@@ -321,7 +321,6 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master, ...@@ -321,7 +321,6 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master,
struct bcm2835aux_spi *bs = spi_master_get_devdata(master); struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
unsigned long spi_hz, clk_hz, speed; unsigned long spi_hz, clk_hz, speed;
unsigned long spi_used_hz; unsigned long spi_used_hz;
unsigned long long xfer_time_us;
/* calculate the registers to handle /* calculate the registers to handle
* *
...@@ -358,20 +357,21 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master, ...@@ -358,20 +357,21 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master,
bs->rx_len = tfr->len; bs->rx_len = tfr->len;
bs->pending = 0; bs->pending = 0;
/* calculate the estimated time in us the transfer runs /* Calculate the estimated time in us the transfer runs. Note that
* note that there are are 2 idle clocks after each * there are are 2 idle clocks cycles after each chunk getting
* chunk getting transferred - in our case the chunk size * transferred - in our case the chunk size is 3 bytes, so we
* is 3 bytes, so we approximate this by 9 bits/byte * 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; #define HZ_PER_BYTE ((9 * 1000000) / BCM2835_AUX_SPI_POLLING_LIMIT_US)
do_div(xfer_time_us, spi_used_hz);
/* run in polling mode for short transfers */ /* 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); return bcm2835aux_spi_transfer_one_poll(master, spi, tfr);
/* run in interrupt mode for all others */ /* run in interrupt mode for all others */
return bcm2835aux_spi_transfer_one_irq(master, spi, tfr); return bcm2835aux_spi_transfer_one_irq(master, spi, tfr);
#undef HZ_PER_BYTE
} }
static int bcm2835aux_spi_prepare_message(struct spi_master *master, static int bcm2835aux_spi_prepare_message(struct spi_master *master,
......
...@@ -112,10 +112,10 @@ static irqreturn_t dma_transfer(struct dw_spi *dws) ...@@ -112,10 +112,10 @@ static irqreturn_t dma_transfer(struct dw_spi *dws)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static bool mid_spi_can_dma(struct spi_master *master, struct spi_device *spi, static bool mid_spi_can_dma(struct spi_controller *master,
struct spi_transfer *xfer) 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) if (!dws->dma_inited)
return false; return false;
......
...@@ -135,7 +135,7 @@ static inline void dw_spi_debugfs_remove(struct dw_spi *dws) ...@@ -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) 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); struct chip_data *chip = spi_get_ctldata(spi);
/* Chip select logic is inverted from spi_set_cs() */ /* Chip select logic is inverted from spi_set_cs() */
...@@ -250,8 +250,8 @@ static irqreturn_t interrupt_transfer(struct dw_spi *dws) ...@@ -250,8 +250,8 @@ static irqreturn_t interrupt_transfer(struct dw_spi *dws)
static irqreturn_t dw_spi_irq(int irq, void *dev_id) static irqreturn_t dw_spi_irq(int irq, void *dev_id)
{ {
struct spi_master *master = dev_id; struct spi_controller *master = dev_id;
struct dw_spi *dws = spi_master_get_devdata(master); struct dw_spi *dws = spi_controller_get_devdata(master);
u16 irq_status = dw_readl(dws, DW_SPI_ISR) & 0x3f; u16 irq_status = dw_readl(dws, DW_SPI_ISR) & 0x3f;
if (!irq_status) if (!irq_status)
...@@ -277,10 +277,10 @@ static int poll_transfer(struct dw_spi *dws) ...@@ -277,10 +277,10 @@ static int poll_transfer(struct dw_spi *dws)
return 0; 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 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); struct chip_data *chip = spi_get_ctldata(spi);
u8 imask = 0; u8 imask = 0;
u16 txlevel = 0; u16 txlevel = 0;
...@@ -383,10 +383,10 @@ static int dw_spi_transfer_one(struct spi_master *master, ...@@ -383,10 +383,10 @@ static int dw_spi_transfer_one(struct spi_master *master,
return 1; 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 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) if (dws->dma_mapped)
dws->dma_ops->dma_stop(dws); dws->dma_ops->dma_stop(dws);
...@@ -471,7 +471,7 @@ static void spi_hw_init(struct device *dev, struct dw_spi *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) int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
{ {
struct spi_master *master; struct spi_controller *master;
int ret; int ret;
BUG_ON(dws == NULL); BUG_ON(dws == NULL);
...@@ -518,8 +518,8 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) ...@@ -518,8 +518,8 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
} }
} }
spi_master_set_devdata(master, dws); spi_controller_set_devdata(master, dws);
ret = devm_spi_register_master(dev, master); ret = devm_spi_register_controller(dev, master);
if (ret) { if (ret) {
dev_err(&master->dev, "problem registering spi master\n"); dev_err(&master->dev, "problem registering spi master\n");
goto err_dma_exit; goto err_dma_exit;
...@@ -534,7 +534,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) ...@@ -534,7 +534,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
spi_enable_chip(dws, 0); spi_enable_chip(dws, 0);
free_irq(dws->irq, master); free_irq(dws->irq, master);
err_free_master: err_free_master:
spi_master_put(master); spi_controller_put(master);
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(dw_spi_add_host); EXPORT_SYMBOL_GPL(dw_spi_add_host);
...@@ -556,7 +556,7 @@ int dw_spi_suspend_host(struct dw_spi *dws) ...@@ -556,7 +556,7 @@ int dw_spi_suspend_host(struct dw_spi *dws)
{ {
int ret; int ret;
ret = spi_master_suspend(dws->master); ret = spi_controller_suspend(dws->master);
if (ret) if (ret)
return ret; return ret;
...@@ -570,7 +570,7 @@ int dw_spi_resume_host(struct dw_spi *dws) ...@@ -570,7 +570,7 @@ int dw_spi_resume_host(struct dw_spi *dws)
int ret; int ret;
spi_hw_init(&dws->master->dev, dws); spi_hw_init(&dws->master->dev, dws);
ret = spi_master_resume(dws->master); ret = spi_controller_resume(dws->master);
if (ret) if (ret)
dev_err(&dws->master->dev, "fail to start queue (%d)\n", ret); dev_err(&dws->master->dev, "fail to start queue (%d)\n", ret);
return ret; return ret;
......
...@@ -93,14 +93,14 @@ struct dw_spi_dma_ops { ...@@ -93,14 +93,14 @@ struct dw_spi_dma_ops {
int (*dma_init)(struct dw_spi *dws); int (*dma_init)(struct dw_spi *dws);
void (*dma_exit)(struct dw_spi *dws); void (*dma_exit)(struct dw_spi *dws);
int (*dma_setup)(struct dw_spi *dws, struct spi_transfer *xfer); 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); struct spi_transfer *xfer);
int (*dma_transfer)(struct dw_spi *dws, struct spi_transfer *xfer); int (*dma_transfer)(struct dw_spi *dws, struct spi_transfer *xfer);
void (*dma_stop)(struct dw_spi *dws); void (*dma_stop)(struct dw_spi *dws);
}; };
struct dw_spi { struct dw_spi {
struct spi_master *master; struct spi_controller *master;
enum dw_ssi_type type; enum dw_ssi_type type;
void __iomem *regs; void __iomem *regs;
......
This diff is collapsed.
...@@ -184,10 +184,11 @@ static int jcore_spi_probe(struct platform_device *pdev) ...@@ -184,10 +184,11 @@ static int jcore_spi_probe(struct platform_device *pdev)
*/ */
clock_freq = 50000000; clock_freq = 50000000;
clk = devm_clk_get(&pdev->dev, "ref_clk"); clk = devm_clk_get(&pdev->dev, "ref_clk");
if (!IS_ERR_OR_NULL(clk)) { if (!IS_ERR(clk)) {
if (clk_enable(clk) == 0) if (clk_prepare_enable(clk) == 0) {
clock_freq = clk_get_rate(clk); clock_freq = clk_get_rate(clk);
else clk_disable_unprepare(clk);
} else
dev_warn(&pdev->dev, "could not enable ref_clk\n"); dev_warn(&pdev->dev, "could not enable ref_clk\n");
} }
hw->clock_freq = clock_freq; hw->clock_freq = clock_freq;
...@@ -198,10 +199,8 @@ static int jcore_spi_probe(struct platform_device *pdev) ...@@ -198,10 +199,8 @@ static int jcore_spi_probe(struct platform_device *pdev)
/* Register our spi controller */ /* Register our spi controller */
err = devm_spi_register_master(&pdev->dev, master); err = devm_spi_register_master(&pdev->dev, master);
if (err) { if (err)
clk_disable(clk);
goto exit; goto exit;
}
return 0; return 0;
......
...@@ -90,14 +90,19 @@ struct orion_direct_acc { ...@@ -90,14 +90,19 @@ struct orion_direct_acc {
u32 size; u32 size;
}; };
struct orion_child_options {
struct orion_direct_acc direct_access;
};
struct orion_spi { struct orion_spi {
struct spi_master *master; struct spi_master *master;
void __iomem *base; void __iomem *base;
struct clk *clk; struct clk *clk;
struct clk *axi_clk; struct clk *axi_clk;
const struct orion_spi_dev *devdata; 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) 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) ...@@ -324,13 +329,13 @@ static void orion_spi_set_cs(struct spi_device *spi, bool enable)
struct orion_spi *orion_spi; struct orion_spi *orion_spi;
int cs; int cs;
orion_spi = spi_master_get_devdata(spi->master);
if (gpio_is_valid(spi->cs_gpio)) if (gpio_is_valid(spi->cs_gpio))
cs = 0; cs = orion_spi->unused_hw_gpio;
else else
cs = spi->chip_select; 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_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, ORION_SPI_CS_MASK);
orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG, orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG,
ORION_SPI_CS(cs)); ORION_SPI_CS(cs));
...@@ -435,7 +440,7 @@ orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer) ...@@ -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 * Use SPI direct write mode if base address is available. Otherwise
* fall back to PIO mode for this transfer. * 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)) { (word_len == 8)) {
unsigned int cnt = count / 4; unsigned int cnt = count / 4;
unsigned int rem = count % 4; unsigned int rem = count % 4;
...@@ -444,12 +449,12 @@ orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer) ...@@ -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 * Send the TX-data to the SPI device via the direct
* mapped address window * mapped address window
*/ */
iowrite32_rep(orion_spi->direct_access[cs].vaddr, iowrite32_rep(orion_spi->child[cs].direct_access.vaddr,
xfer->tx_buf, cnt); xfer->tx_buf, cnt);
if (rem) { if (rem) {
u32 *buf = (u32 *)xfer->tx_buf; 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); &buf[cnt], rem);
} }
...@@ -498,6 +503,9 @@ static int orion_spi_transfer_one(struct spi_master *master, ...@@ -498,6 +503,9 @@ static int orion_spi_transfer_one(struct spi_master *master,
static int orion_spi_setup(struct spi_device *spi) 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); return orion_spi_setup_transfer(spi, NULL);
} }
...@@ -620,6 +628,7 @@ static int orion_spi_probe(struct platform_device *pdev) ...@@ -620,6 +628,7 @@ static int orion_spi_probe(struct platform_device *pdev)
spi = spi_master_get_devdata(master); spi = spi_master_get_devdata(master);
spi->master = master; spi->master = master;
spi->unused_hw_gpio = -1;
of_id = of_match_device(orion_spi_of_match_table, &pdev->dev); of_id = of_match_device(orion_spi_of_match_table, &pdev->dev);
devdata = (of_id) ? of_id->data : &orion_spi_dev_data; devdata = (of_id) ? of_id->data : &orion_spi_dev_data;
...@@ -702,14 +711,14 @@ static int orion_spi_probe(struct platform_device *pdev) ...@@ -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 * This needs to get extended for the direct SPI-NOR / SPI-NAND
* support, once this gets implemented. * 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, r->start,
PAGE_SIZE); PAGE_SIZE);
if (!spi->direct_access[cs].vaddr) { if (!spi->child[cs].direct_access.vaddr) {
status = -ENOMEM; status = -ENOMEM;
goto out_rel_axi_clk; 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); 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) ...@@ -731,8 +740,44 @@ static int orion_spi_probe(struct platform_device *pdev)
if (status < 0) if (status < 0)
goto out_rel_pm; 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; return status;
out_rel_master:
spi_unregister_master(master);
out_rel_pm: out_rel_pm:
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
out_rel_axi_clk: out_rel_axi_clk:
......
...@@ -191,7 +191,7 @@ int pxa2xx_spi_dma_setup(struct driver_data *drv_data) ...@@ -191,7 +191,7 @@ int pxa2xx_spi_dma_setup(struct driver_data *drv_data)
{ {
struct pxa2xx_spi_master *pdata = drv_data->master_info; struct pxa2xx_spi_master *pdata = drv_data->master_info;
struct device *dev = &drv_data->pdev->dev; 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_mask_t mask;
dma_cap_zero(mask); dma_cap_zero(mask);
...@@ -215,7 +215,7 @@ int pxa2xx_spi_dma_setup(struct driver_data *drv_data) ...@@ -215,7 +215,7 @@ int pxa2xx_spi_dma_setup(struct driver_data *drv_data)
void pxa2xx_spi_dma_release(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) { if (master->dma_rx) {
dmaengine_terminate_sync(master->dma_rx); dmaengine_terminate_sync(master->dma_rx);
......
...@@ -415,10 +415,17 @@ static void cs_deassert(struct driver_data *drv_data) ...@@ -415,10 +415,17 @@ static void cs_deassert(struct driver_data *drv_data)
{ {
struct chip_data *chip = struct chip_data *chip =
spi_get_ctldata(drv_data->master->cur_msg->spi); spi_get_ctldata(drv_data->master->cur_msg->spi);
unsigned long timeout;
if (drv_data->ssp_type == CE4100_SSP) if (drv_data->ssp_type == CE4100_SSP)
return; 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) { if (chip->cs_control) {
chip->cs_control(PXA2XX_CS_DEASSERT); chip->cs_control(PXA2XX_CS_DEASSERT);
return; return;
...@@ -563,7 +570,6 @@ static void giveback(struct driver_data *drv_data) ...@@ -563,7 +570,6 @@ static void giveback(struct driver_data *drv_data)
{ {
struct spi_transfer* last_transfer; struct spi_transfer* last_transfer;
struct spi_message *msg; struct spi_message *msg;
unsigned long timeout;
msg = drv_data->master->cur_msg; msg = drv_data->master->cur_msg;
drv_data->cur_transfer = NULL; drv_data->cur_transfer = NULL;
...@@ -575,12 +581,6 @@ static void giveback(struct driver_data *drv_data) ...@@ -575,12 +581,6 @@ static void giveback(struct driver_data *drv_data)
if (last_transfer->delay_usecs) if (last_transfer->delay_usecs)
udelay(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 /* Drop chip select UNLESS cs_change is true or we are returning
* a message with an error, or next message is for another chip * 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, ...@@ -962,7 +962,7 @@ static unsigned int pxa2xx_ssp_get_clk_div(struct driver_data *drv_data,
return clk_div << 8; 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_device *spi,
struct spi_transfer *xfer) struct spi_transfer *xfer)
{ {
...@@ -976,7 +976,7 @@ static bool pxa2xx_spi_can_dma(struct spi_master *master, ...@@ -976,7 +976,7 @@ static bool pxa2xx_spi_can_dma(struct spi_master *master,
static void pump_transfers(unsigned long data) static void pump_transfers(unsigned long data)
{ {
struct driver_data *drv_data = (struct driver_data *)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 spi_message *message = master->cur_msg;
struct chip_data *chip = spi_get_ctldata(message->spi); struct chip_data *chip = spi_get_ctldata(message->spi);
u32 dma_thresh = chip->dma_threshold; u32 dma_thresh = chip->dma_threshold;
...@@ -1182,10 +1182,10 @@ static void pump_transfers(unsigned long data) ...@@ -1182,10 +1182,10 @@ static void pump_transfers(unsigned long data)
pxa2xx_spi_write(drv_data, SSCR1, cr1); 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 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*/ /* Initial message state*/
msg->state = START_STATE; msg->state = START_STATE;
...@@ -1198,9 +1198,9 @@ static int pxa2xx_spi_transfer_one_message(struct spi_master *master, ...@@ -1198,9 +1198,9 @@ static int pxa2xx_spi_transfer_one_message(struct spi_master *master,
return 0; 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 */ /* Disable the SSP now */
pxa2xx_spi_write(drv_data, SSCR0, pxa2xx_spi_write(drv_data, SSCR0,
...@@ -1212,7 +1212,8 @@ static int pxa2xx_spi_unprepare_transfer(struct spi_master *master) ...@@ -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, static int setup_cs(struct spi_device *spi, struct chip_data *chip,
struct pxa2xx_spi_chip *chip_info) 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; struct gpio_desc *gpiod;
int err = 0; int err = 0;
...@@ -1270,7 +1271,8 @@ static int setup(struct spi_device *spi) ...@@ -1270,7 +1271,8 @@ static int setup(struct spi_device *spi)
struct pxa2xx_spi_chip *chip_info; struct pxa2xx_spi_chip *chip_info;
struct chip_data *chip; struct chip_data *chip;
const struct lpss_config *config; 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; uint tx_thres, tx_hi_thres, rx_thres;
switch (drv_data->ssp_type) { switch (drv_data->ssp_type) {
...@@ -1410,7 +1412,8 @@ static int setup(struct spi_device *spi) ...@@ -1410,7 +1412,8 @@ static int setup(struct spi_device *spi)
static void cleanup(struct spi_device *spi) static void cleanup(struct spi_device *spi)
{ {
struct chip_data *chip = spi_get_ctldata(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) if (!chip)
return; return;
...@@ -1575,9 +1578,10 @@ pxa2xx_spi_init_pdata(struct platform_device *pdev) ...@@ -1575,9 +1578,10 @@ pxa2xx_spi_init_pdata(struct platform_device *pdev)
} }
#endif #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)) { if (has_acpi_companion(&drv_data->pdev->dev)) {
switch (drv_data->ssp_type) { switch (drv_data->ssp_type) {
...@@ -1602,7 +1606,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) ...@@ -1602,7 +1606,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct pxa2xx_spi_master *platform_info; struct pxa2xx_spi_master *platform_info;
struct spi_master *master; struct spi_controller *master;
struct driver_data *drv_data; struct driver_data *drv_data;
struct ssp_device *ssp; struct ssp_device *ssp;
const struct lpss_config *config; const struct lpss_config *config;
...@@ -1633,7 +1637,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) ...@@ -1633,7 +1637,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
pxa_ssp_free(ssp); pxa_ssp_free(ssp);
return -ENOMEM; return -ENOMEM;
} }
drv_data = spi_master_get_devdata(master); drv_data = spi_controller_get_devdata(master);
drv_data->master = master; drv_data->master = master;
drv_data->master_info = platform_info; drv_data->master_info = platform_info;
drv_data->pdev = pdev; drv_data->pdev = pdev;
...@@ -1651,7 +1655,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) ...@@ -1651,7 +1655,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
master->unprepare_transfer_hardware = pxa2xx_spi_unprepare_transfer; master->unprepare_transfer_hardware = pxa2xx_spi_unprepare_transfer;
master->fw_translate_cs = pxa2xx_spi_fw_translate_cs; master->fw_translate_cs = pxa2xx_spi_fw_translate_cs;
master->auto_runtime_pm = true; 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; drv_data->ssp_type = ssp->type;
...@@ -1793,7 +1797,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) ...@@ -1793,7 +1797,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
/* Register with the SPI framework */ /* Register with the SPI framework */
platform_set_drvdata(pdev, drv_data); 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) { if (status != 0) {
dev_err(&pdev->dev, "problem registering spi master\n"); dev_err(&pdev->dev, "problem registering spi master\n");
goto out_error_clock_enabled; goto out_error_clock_enabled;
...@@ -1802,12 +1806,14 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) ...@@ -1802,12 +1806,14 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
return status; return status;
out_error_clock_enabled: out_error_clock_enabled:
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
clk_disable_unprepare(ssp->clk); clk_disable_unprepare(ssp->clk);
pxa2xx_spi_dma_release(drv_data); pxa2xx_spi_dma_release(drv_data);
free_irq(ssp->irq, drv_data); free_irq(ssp->irq, drv_data);
out_error_master_alloc: out_error_master_alloc:
spi_master_put(master); spi_controller_put(master);
pxa_ssp_free(ssp); pxa_ssp_free(ssp);
return status; return status;
} }
...@@ -1858,7 +1864,7 @@ static int pxa2xx_spi_suspend(struct device *dev) ...@@ -1858,7 +1864,7 @@ static int pxa2xx_spi_suspend(struct device *dev)
struct ssp_device *ssp = drv_data->ssp; struct ssp_device *ssp = drv_data->ssp;
int status; int status;
status = spi_master_suspend(drv_data->master); status = spi_controller_suspend(drv_data->master);
if (status != 0) if (status != 0)
return status; return status;
pxa2xx_spi_write(drv_data, SSCR0, 0); pxa2xx_spi_write(drv_data, SSCR0, 0);
...@@ -1884,7 +1890,7 @@ static int pxa2xx_spi_resume(struct device *dev) ...@@ -1884,7 +1890,7 @@ static int pxa2xx_spi_resume(struct device *dev)
lpss_ssp_setup(drv_data); lpss_ssp_setup(drv_data);
/* Start the queue running */ /* Start the queue running */
status = spi_master_resume(drv_data->master); status = spi_controller_resume(drv_data->master);
if (status != 0) { if (status != 0) {
dev_err(dev, "problem starting queue (%d)\n", status); dev_err(dev, "problem starting queue (%d)\n", status);
return status; return status;
......
...@@ -31,7 +31,7 @@ struct driver_data { ...@@ -31,7 +31,7 @@ struct driver_data {
/* SPI framework hookup */ /* SPI framework hookup */
enum pxa_ssp_type ssp_type; enum pxa_ssp_type ssp_type;
struct spi_master *master; struct spi_controller *master;
/* PXA hookup */ /* PXA hookup */
struct pxa2xx_spi_master *master_info; struct pxa2xx_spi_master *master_info;
......
...@@ -535,7 +535,7 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, ...@@ -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 */ /* First prepare and submit the DMA request(s), as this may fail */
if (rx) { if (rx) {
desc_rx = dmaengine_prep_slave_sg(rspi->master->dma_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); DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc_rx) { if (!desc_rx) {
ret = -EAGAIN; ret = -EAGAIN;
...@@ -555,7 +555,7 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, ...@@ -555,7 +555,7 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
if (tx) { if (tx) {
desc_tx = dmaengine_prep_slave_sg(rspi->master->dma_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); DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc_tx) { if (!desc_tx) {
ret = -EAGAIN; ret = -EAGAIN;
......
...@@ -752,7 +752,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, ...@@ -752,7 +752,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
if (rx) { if (rx) {
ier_bits |= IER_RDREQE | IER_RDMAE; ier_bits |= IER_RDREQE | IER_RDMAE;
desc_rx = dmaengine_prep_slave_single(p->master->dma_rx, 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); DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc_rx) if (!desc_rx)
return -EAGAIN; return -EAGAIN;
...@@ -769,7 +769,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, ...@@ -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, dma_sync_single_for_device(p->master->dma_tx->device->dev,
p->tx_dma_addr, len, DMA_TO_DEVICE); p->tx_dma_addr, len, DMA_TO_DEVICE);
desc_tx = dmaengine_prep_slave_single(p->master->dma_tx, 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); DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc_tx) { if (!desc_tx) {
ret = -EAGAIN; ret = -EAGAIN;
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
*/ */
#include <linux/delay.h>
#include <linux/hwspinlock.h> #include <linux/hwspinlock.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h> #include <linux/io.h>
...@@ -12,6 +13,7 @@ ...@@ -12,6 +13,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/reboot.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/sizes.h> #include <linux/sizes.h>
...@@ -67,6 +69,40 @@ ...@@ -67,6 +69,40 @@
#define ADI_READ_TIMEOUT 2000 #define ADI_READ_TIMEOUT 2000
#define REG_ADDR_LOW_MASK GENMASK(11, 0) #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 sprd_adi {
struct spi_controller *ctlr; struct spi_controller *ctlr;
struct device *dev; struct device *dev;
...@@ -74,6 +110,7 @@ struct sprd_adi { ...@@ -74,6 +110,7 @@ struct sprd_adi {
struct hwspinlock *hwlock; struct hwspinlock *hwlock;
unsigned long slave_vbase; unsigned long slave_vbase;
unsigned long slave_pbase; unsigned long slave_pbase;
struct notifier_block restart_handler;
}; };
static int sprd_adi_check_paddr(struct sprd_adi *sadi, u32 paddr) 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) ...@@ -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) static int sprd_adi_read(struct sprd_adi *sadi, u32 reg_paddr, u32 *read_val)
{ {
int read_timeout = ADI_READ_TIMEOUT; int read_timeout = ADI_READ_TIMEOUT;
unsigned long flags;
u32 val, rd_addr; 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, * 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) ...@@ -147,7 +194,8 @@ static int sprd_adi_read(struct sprd_adi *sadi, u32 reg_paddr, u32 *read_val)
if (read_timeout == 0) { if (read_timeout == 0) {
dev_err(sadi->dev, "ADI read timeout\n"); 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) ...@@ -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)) { if (rd_addr != (reg_paddr & REG_ADDR_LOW_MASK)) {
dev_err(sadi->dev, "read error, reg addr = 0x%x, val = 0x%x\n", dev_err(sadi->dev, "read error, reg addr = 0x%x, val = 0x%x\n",
reg_paddr, val); reg_paddr, val);
return -EIO; ret = -EIO;
goto out;
} }
*read_val = val & RD_VALUE_MASK; *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; u32 timeout = ADI_FIFO_DRAIN_TIMEOUT;
unsigned long flags;
int ret; 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); ret = sprd_adi_drain_fifo(sadi);
if (ret < 0) if (ret < 0)
return ret; goto out;
/* /*
* we should wait for write fifo is empty before writing data to PMIC * 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) ...@@ -192,10 +254,12 @@ static int sprd_adi_write(struct sprd_adi *sadi, unsigned long reg, u32 val)
if (timeout == 0) { if (timeout == 0) {
dev_err(sadi->dev, "write fifo is full\n"); 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, static int sprd_adi_transfer_one(struct spi_controller *ctlr,
...@@ -203,7 +267,6 @@ 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 spi_transfer *t)
{ {
struct sprd_adi *sadi = spi_controller_get_devdata(ctlr); struct sprd_adi *sadi = spi_controller_get_devdata(ctlr);
unsigned long flags, virt_reg;
u32 phy_reg, val; u32 phy_reg, val;
int ret; int ret;
...@@ -214,16 +277,7 @@ static int sprd_adi_transfer_one(struct spi_controller *ctlr, ...@@ -214,16 +277,7 @@ static int sprd_adi_transfer_one(struct spi_controller *ctlr,
if (ret) if (ret)
return 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); ret = sprd_adi_read(sadi, phy_reg, &val);
hwspin_unlock_irqrestore(sadi->hwlock, &flags);
if (ret) if (ret)
return ret; return ret;
...@@ -241,19 +295,8 @@ static int sprd_adi_transfer_one(struct spi_controller *ctlr, ...@@ -241,19 +295,8 @@ static int sprd_adi_transfer_one(struct spi_controller *ctlr,
if (ret) if (ret)
return ret; return ret;
virt_reg = sprd_adi_to_vaddr(sadi, phy_reg);
val = *p; val = *p;
ret = sprd_adi_write(sadi, phy_reg, val);
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);
if (ret) if (ret)
return ret; return ret;
} else { } else {
...@@ -264,6 +307,72 @@ static int sprd_adi_transfer_one(struct spi_controller *ctlr, ...@@ -264,6 +307,72 @@ static int sprd_adi_transfer_one(struct spi_controller *ctlr,
return 0; 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) static void sprd_adi_hw_init(struct sprd_adi *sadi)
{ {
struct device_node *np = sadi->dev->of_node; struct device_node *np = sadi->dev->of_node;
...@@ -377,6 +486,14 @@ static int sprd_adi_probe(struct platform_device *pdev) ...@@ -377,6 +486,14 @@ static int sprd_adi_probe(struct platform_device *pdev)
goto free_hwlock; 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; return 0;
free_hwlock: free_hwlock:
...@@ -391,6 +508,7 @@ static int sprd_adi_remove(struct platform_device *pdev) ...@@ -391,6 +508,7 @@ static int sprd_adi_remove(struct platform_device *pdev)
struct spi_controller *ctlr = dev_get_drvdata(&pdev->dev); struct spi_controller *ctlr = dev_get_drvdata(&pdev->dev);
struct sprd_adi *sadi = spi_controller_get_devdata(ctlr); struct sprd_adi *sadi = spi_controller_get_devdata(ctlr);
unregister_restart_handler(&sadi->restart_handler);
hwspin_lock_free(sadi->hwlock); hwspin_lock_free(sadi->hwlock);
return 0; return 0;
} }
......
...@@ -276,10 +276,10 @@ static unsigned tegra_slink_calculate_curr_xfer_param( ...@@ -276,10 +276,10 @@ static unsigned tegra_slink_calculate_curr_xfer_param(
tspi->bytes_per_word = DIV_ROUND_UP(bits_per_word, 8); tspi->bytes_per_word = DIV_ROUND_UP(bits_per_word, 8);
if (bits_per_word == 8 || bits_per_word == 16) { 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; tspi->words_per_32bit = 32/bits_per_word;
} else { } else {
tspi->is_packed = 0; tspi->is_packed = false;
tspi->words_per_32bit = 1; tspi->words_per_32bit = 1;
} }
tspi->packed_size = tegra_slink_get_packed_size(tspi, t); tspi->packed_size = tegra_slink_get_packed_size(tspi, t);
......
...@@ -779,8 +779,14 @@ static int spi_map_buf(struct spi_controller *ctlr, struct device *dev, ...@@ -779,8 +779,14 @@ static int spi_map_buf(struct spi_controller *ctlr, struct device *dev,
for (i = 0; i < sgs; i++) { for (i = 0; i < sgs; i++) {
if (vmalloced_buf || kmap_buf) { 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) if (vmalloced_buf)
vm_page = vmalloc_to_page(buf); vm_page = vmalloc_to_page(buf);
else else
...@@ -2254,12 +2260,6 @@ void spi_unregister_controller(struct spi_controller *ctlr) ...@@ -2254,12 +2260,6 @@ void spi_unregister_controller(struct spi_controller *ctlr)
mutex_lock(&board_lock); mutex_lock(&board_lock);
found = idr_find(&spi_master_idr, id); found = idr_find(&spi_master_idr, id);
mutex_unlock(&board_lock); 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 (ctlr->queued) {
if (spi_destroy_queue(ctlr)) if (spi_destroy_queue(ctlr))
dev_err(&ctlr->dev, "queue remove failed\n"); dev_err(&ctlr->dev, "queue remove failed\n");
...@@ -2272,7 +2272,8 @@ void spi_unregister_controller(struct spi_controller *ctlr) ...@@ -2272,7 +2272,8 @@ void spi_unregister_controller(struct spi_controller *ctlr)
device_unregister(&ctlr->dev); device_unregister(&ctlr->dev);
/* free bus id */ /* free bus id */
mutex_lock(&board_lock); mutex_lock(&board_lock);
idr_remove(&spi_master_idr, id); if (found == ctlr)
idr_remove(&spi_master_idr, id);
mutex_unlock(&board_lock); mutex_unlock(&board_lock);
} }
EXPORT_SYMBOL_GPL(spi_unregister_controller); EXPORT_SYMBOL_GPL(spi_unregister_controller);
......
...@@ -8,64 +8,17 @@ ...@@ -8,64 +8,17 @@
* - id the same as the SPI bus number it implements * - id the same as the SPI bus number it implements
* - dev.platform data pointing to a struct spi_gpio_platform_data * - dev.platform data pointing to a struct spi_gpio_platform_data
* *
* Or, see the driver code for information about speedups that are * Use spi_board_info with these busses in the usual way.
* 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.
* *
* If the bitbanged bus is later switched to a "native" controller, * If the bitbanged bus is later switched to a "native" controller,
* that platform_device and controller_data should be removed. * 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 * 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 * @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 { struct spi_gpio_platform_data {
unsigned sck;
unsigned long mosi;
unsigned long miso;
u16 num_chipselect; u16 num_chipselect;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment