diff options
author | 2016-04-11 10:41:07 +0300 | |
---|---|---|
committer | 2016-04-13 08:17:18 +0300 | |
commit | e09b41010ba33a20a87472ee821fa407a5b8da36 (patch) | |
tree | d10dc367189862e7ca5c592f033dc3726e1df4e3 /kernel/arch/arm/mach-ep93xx/simone.c | |
parent | f93b97fd65072de626c074dbe099a1fff05ce060 (diff) |
These changes are the raw update to linux-4.4.6-rt14. Kernel sources
are taken from kernel.org, and rt patch from the rt wiki download page.
During the rebasing, the following patch collided:
Force tick interrupt and get rid of softirq magic(I70131fb85).
Collisions have been removed because its logic was found on the
source already.
Change-Id: I7f57a4081d9deaa0d9ccfc41a6c8daccdee3b769
Signed-off-by: José Pekkarinen <jose.pekkarinen@nokia.com>
Diffstat (limited to 'kernel/arch/arm/mach-ep93xx/simone.c')
-rw-r--r-- | kernel/arch/arm/mach-ep93xx/simone.c | 138 |
1 files changed, 135 insertions, 3 deletions
diff --git a/kernel/arch/arm/mach-ep93xx/simone.c b/kernel/arch/arm/mach-ep93xx/simone.c index 36f22c1a3..7bb540c42 100644 --- a/kernel/arch/arm/mach-ep93xx/simone.c +++ b/kernel/arch/arm/mach-ep93xx/simone.c @@ -20,9 +20,14 @@ #include <linux/platform_device.h> #include <linux/i2c.h> #include <linux/i2c-gpio.h> +#include <linux/mmc/host.h> +#include <linux/spi/spi.h> +#include <linux/spi/mmc_spi.h> +#include <linux/platform_data/video-ep93xx.h> +#include <linux/platform_data/spi-ep93xx.h> +#include <linux/gpio.h> #include <mach/hardware.h> -#include <linux/platform_data/video-ep93xx.h> #include <mach/gpio-ep93xx.h> #include <asm/mach-types.h> @@ -35,11 +40,136 @@ static struct ep93xx_eth_data __initdata simone_eth_data = { }; static struct ep93xxfb_mach_info __initdata simone_fb_info = { - .num_modes = EP93XXFB_USE_MODEDB, - .bpp = 16, .flags = EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING, }; +/* + * GPIO lines used for MMC card detection. + */ +#define MMC_CARD_DETECT_GPIO EP93XX_GPIO_LINE_EGPIO0 + +/* + * Up to v1.3, the Sim.One used SFRMOUT as SD card chip select, but this goes + * low between multi-message command blocks. From v1.4, it uses a GPIO instead. + * v1.3 parts will still work, since the signal on SFRMOUT is automatic. + */ +#define MMC_CHIP_SELECT_GPIO EP93XX_GPIO_LINE_EGPIO1 + +/* + * MMC SPI chip select GPIO handling. If you are using SFRMOUT (SFRM1) signal, + * you can leave these empty and pass NULL as .controller_data. + */ + +static int simone_mmc_spi_setup(struct spi_device *spi) +{ + unsigned int gpio = MMC_CHIP_SELECT_GPIO; + int err; + + err = gpio_request(gpio, spi->modalias); + if (err) + return err; + + err = gpio_direction_output(gpio, 1); + if (err) { + gpio_free(gpio); + return err; + } + + return 0; +} + +static void simone_mmc_spi_cleanup(struct spi_device *spi) +{ + unsigned int gpio = MMC_CHIP_SELECT_GPIO; + + gpio_set_value(gpio, 1); + gpio_direction_input(gpio); + gpio_free(gpio); +} + +static void simone_mmc_spi_cs_control(struct spi_device *spi, int value) +{ + gpio_set_value(MMC_CHIP_SELECT_GPIO, value); +} + +static struct ep93xx_spi_chip_ops simone_mmc_spi_ops = { + .setup = simone_mmc_spi_setup, + .cleanup = simone_mmc_spi_cleanup, + .cs_control = simone_mmc_spi_cs_control, +}; + +/* + * MMC card detection GPIO setup. + */ + +static int simone_mmc_spi_init(struct device *dev, + irqreturn_t (*irq_handler)(int, void *), void *mmc) +{ + unsigned int gpio = MMC_CARD_DETECT_GPIO; + int irq, err; + + err = gpio_request(gpio, dev_name(dev)); + if (err) + return err; + + err = gpio_direction_input(gpio); + if (err) + goto fail; + + irq = gpio_to_irq(gpio); + if (irq < 0) + goto fail; + + err = request_irq(irq, irq_handler, IRQF_TRIGGER_FALLING, + "MMC card detect", mmc); + if (err) + goto fail; + + printk(KERN_INFO "%s: using irq %d for MMC card detection\n", + dev_name(dev), irq); + + return 0; +fail: + gpio_free(gpio); + return err; +} + +static void simone_mmc_spi_exit(struct device *dev, void *mmc) +{ + unsigned int gpio = MMC_CARD_DETECT_GPIO; + + free_irq(gpio_to_irq(gpio), mmc); + gpio_free(gpio); +} + +static struct mmc_spi_platform_data simone_mmc_spi_data = { + .init = simone_mmc_spi_init, + .exit = simone_mmc_spi_exit, + .detect_delay = 500, + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, +}; + +static struct spi_board_info simone_spi_devices[] __initdata = { + { + .modalias = "mmc_spi", + .controller_data = &simone_mmc_spi_ops, + .platform_data = &simone_mmc_spi_data, + /* + * We use 10 MHz even though the maximum is 3.7 MHz. The driver + * will limit it automatically to max. frequency. + */ + .max_speed_hz = 10 * 1000 * 1000, + .bus_num = 0, + .chip_select = 0, + .mode = SPI_MODE_3, + }, +}; + +static struct ep93xx_spi_info simone_spi_info __initdata = { + .num_chipselect = ARRAY_SIZE(simone_spi_devices), + .use_dma = 1, +}; + static struct i2c_gpio_platform_data __initdata simone_i2c_gpio_data = { .sda_pin = EP93XX_GPIO_LINE_EEDAT, .sda_is_open_drain = 0, @@ -74,6 +204,8 @@ static void __init simone_init_machine(void) ep93xx_register_fb(&simone_fb_info); ep93xx_register_i2c(&simone_i2c_gpio_data, simone_i2c_board_info, ARRAY_SIZE(simone_i2c_board_info)); + ep93xx_register_spi(&simone_spi_info, simone_spi_devices, + ARRAY_SIZE(simone_spi_devices)); simone_register_audio(); } |