diff options
Diffstat (limited to 'target/linux/brcm2708/patches-3.18/0063-bcm2708-Allow-option-card-devices-to-be-configured-v.patch')
-rwxr-xr-x | target/linux/brcm2708/patches-3.18/0063-bcm2708-Allow-option-card-devices-to-be-configured-v.patch | 461 |
1 files changed, 461 insertions, 0 deletions
diff --git a/target/linux/brcm2708/patches-3.18/0063-bcm2708-Allow-option-card-devices-to-be-configured-v.patch b/target/linux/brcm2708/patches-3.18/0063-bcm2708-Allow-option-card-devices-to-be-configured-v.patch new file mode 100755 index 0000000000..803e6743e6 --- /dev/null +++ b/target/linux/brcm2708/patches-3.18/0063-bcm2708-Allow-option-card-devices-to-be-configured-v.patch @@ -0,0 +1,461 @@ +From 37fd085e3449fabd2d976d671ebf2a6c631c9afd Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.org> +Date: Mon, 1 Sep 2014 16:35:56 +0100 +Subject: [PATCH 063/114] bcm2708: Allow option card devices to be configured + via DT + +If the kernel is built with Device Tree support, and if a DT blob +is provided for the kernel at boot time, then the platform devices +for option cards are not created. This avoids both the need to +blacklist unwanted devices, and the need to update the board +support code with each new device. +--- + arch/arm/mach-bcm2708/bcm2708.c | 70 ++++++++++++++++++++--------------------- + drivers/dma/bcm2708-dmaengine.c | 14 ++++----- + drivers/mmc/host/bcm2835-mmc.c | 24 +++++++------- + drivers/of/fdt.c | 6 +++- + sound/soc/bcm/bcm2708-i2s.c | 29 +++++++++++------ + sound/soc/bcm/bcm2835-i2s.c | 1 + + 6 files changed, 80 insertions(+), 64 deletions(-) + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index 5f6a1fa..2c6a29d 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -35,6 +35,7 @@ + #include <linux/module.h> + #include <linux/of_platform.h> + #include <linux/spi/spi.h> ++#include <linux/gpio/machine.h> + #include <linux/w1-gpio.h> + + #include <linux/version.h> +@@ -93,6 +94,8 @@ static unsigned reboot_part = 0; + static unsigned w1_gpio_pin = W1_GPIO; + static unsigned w1_gpio_pullup = W1_PULLUP; + ++static unsigned use_dt = 0; ++ + static void __init bcm2708_init_led(void); + + void __init bcm2708_init_irq(void) +@@ -514,7 +517,6 @@ static struct platform_device bcm2708_alsa_devices[] = { + }, + }; + +-#ifndef CONFIG_OF + static struct resource bcm2708_spi_resources[] = { + { + .start = SPI0_BASE, +@@ -538,7 +540,6 @@ static struct platform_device bcm2708_spi_device = { + .dma_mask = &bcm2708_spi_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON)}, + }; +-#endif + + #ifdef CONFIG_BCM2708_SPIDEV + static struct spi_board_info bcm2708_spi_devices[] = { +@@ -560,7 +561,6 @@ static struct spi_board_info bcm2708_spi_devices[] = { + }; + #endif + +-#ifndef CONFIG_OF + static struct resource bcm2708_bsc0_resources[] = { + { + .start = BSC0_BASE, +@@ -599,7 +599,6 @@ static struct platform_device bcm2708_bsc1_device = { + .num_resources = ARRAY_SIZE(bcm2708_bsc1_resources), + .resource = bcm2708_bsc1_resources, + }; +-#endif + + static struct platform_device bcm2835_hwmon_device = { + .name = "bcm2835_hwmon", +@@ -609,7 +608,7 @@ static struct platform_device bcm2835_thermal_device = { + .name = "bcm2835_thermal", + }; + +-#ifdef CONFIG_SND_BCM2708_SOC_I2S_MODULE ++#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) + static struct resource bcm2708_i2s_resources[] = { + { + .start = I2S_BASE, +@@ -731,14 +730,14 @@ int __init bcm_register_device(struct platform_device *pdev) + } + + /* +- * Use this macro for platform devices that are present in the Device Tree. +- * This way the device is only added on non-DT builds. ++ * Use these macros for platform and i2c devices that are present in the ++ * Device Tree. This way the devices are only added on non-DT systems. + */ +-#ifdef CONFIG_OF +-#define bcm_register_device_dt(pdev) +-#else +-#define bcm_register_device_dt(pdev) bcm_register_device(pdev) +-#endif ++#define bcm_register_device_dt(pdev) \ ++ if (!use_dt) bcm_register_device(pdev) ++ ++#define i2c_register_board_info_dt(busnum, info, n) \ ++ if (!use_dt) i2c_register_board_info(busnum, info, n) + + int calc_rsts(int partition) + { +@@ -814,7 +813,9 @@ static void __init bcm2708_dt_init(void) + ret = of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + if (ret) { + pr_err("of_platform_populate failed: %d\n", ret); +- BUG(); ++ /* Proceed as if CONFIG_OF was not defined */ ++ } else { ++ use_dt = 1; + } + } + #else +@@ -842,7 +843,7 @@ void __init bcm2708_init(void) + #if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) + w1_gpio_pdata.pin = w1_gpio_pin; + w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; +- platform_device_register(&w1_device); ++ bcm_register_device_dt(&w1_device); + #endif + bcm_register_device(&bcm2708_systemtimer_device); + bcm_register_device(&bcm2708_fb_device); +@@ -857,46 +858,45 @@ void __init bcm2708_init(void) + for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) + bcm_register_device(&bcm2708_alsa_devices[i]); + ++ bcm_register_device(&bcm2835_hwmon_device); ++ bcm_register_device(&bcm2835_thermal_device); ++ + bcm_register_device_dt(&bcm2708_spi_device); + bcm_register_device_dt(&bcm2708_bsc0_device); + bcm_register_device_dt(&bcm2708_bsc1_device); + +- bcm_register_device(&bcm2835_hwmon_device); +- bcm_register_device(&bcm2835_thermal_device); +- +-#ifdef CONFIG_SND_BCM2708_SOC_I2S_MODULE +- bcm_register_device(&bcm2708_i2s_device); ++#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) ++ bcm_register_device_dt(&bcm2708_i2s_device); + #endif + + #if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE) +- bcm_register_device(&snd_hifiberry_dac_device); +- bcm_register_device(&snd_pcm5102a_codec_device); ++ bcm_register_device_dt(&snd_hifiberry_dac_device); ++ bcm_register_device_dt(&snd_pcm5102a_codec_device); + #endif + + #if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS_MODULE) +- bcm_register_device(&snd_rpi_hifiberry_dacplus_device); +- i2c_register_board_info(1, snd_pcm512x_hbdacplus_i2c_devices, ARRAY_SIZE(snd_pcm512x_hbdacplus_i2c_devices)); ++ bcm_register_device_dt(&snd_rpi_hifiberry_dacplus_device); ++ i2c_register_board_info_dt(1, snd_pcm512x_hbdacplus_i2c_devices, ARRAY_SIZE(snd_pcm512x_hbdacplus_i2c_devices)); + #endif + + #if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) +- bcm_register_device(&snd_hifiberry_digi_device); +- i2c_register_board_info(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices)); ++ bcm_register_device_dt(&snd_hifiberry_digi_device); ++ i2c_register_board_info_dt(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices)); + #endif + + #if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP_MODULE) +- bcm_register_device(&snd_hifiberry_amp_device); +- i2c_register_board_info(1, snd_tas5713_i2c_devices, ARRAY_SIZE(snd_tas5713_i2c_devices)); ++ bcm_register_device_dt(&snd_hifiberry_amp_device); ++ i2c_register_board_info_dt(1, snd_tas5713_i2c_devices, ARRAY_SIZE(snd_tas5713_i2c_devices)); + #endif + +- + #if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) +- bcm_register_device(&snd_rpi_dac_device); +- bcm_register_device(&snd_pcm1794a_codec_device); ++ bcm_register_device_dt(&snd_rpi_dac_device); ++ bcm_register_device_dt(&snd_pcm1794a_codec_device); + #endif + + #if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE) +- bcm_register_device(&snd_rpi_iqaudio_dac_device); +- i2c_register_board_info(1, snd_pcm512x_i2c_devices, ARRAY_SIZE(snd_pcm512x_i2c_devices)); ++ bcm_register_device_dt(&snd_rpi_iqaudio_dac_device); ++ i2c_register_board_info_dt(1, snd_pcm512x_i2c_devices, ARRAY_SIZE(snd_pcm512x_i2c_devices)); + #endif + + +@@ -1041,9 +1041,9 @@ static struct platform_device bcm2708_led_device = { + + static void __init bcm2708_init_led(void) + { +- bcm2708_leds[0].gpio = disk_led_gpio; +- bcm2708_leds[0].active_low = disk_led_active_low; +- platform_device_register(&bcm2708_led_device); ++ bcm2708_leds[0].gpio = disk_led_gpio; ++ bcm2708_leds[0].active_low = disk_led_active_low; ++ bcm_register_device_dt(&bcm2708_led_device); + } + #else + static inline void bcm2708_init_led(void) +diff --git a/drivers/dma/bcm2708-dmaengine.c b/drivers/dma/bcm2708-dmaengine.c +index 10463db..3f9be02 100644 +--- a/drivers/dma/bcm2708-dmaengine.c ++++ b/drivers/dma/bcm2708-dmaengine.c +@@ -42,7 +42,7 @@ + #include <linux/io.h> + #include <linux/spinlock.h> + +-#ifndef CONFIG_OF ++#ifndef CONFIG_ARCH_BCM2835 + + /* dma manager */ + #include <mach/dma.h> +@@ -721,7 +721,7 @@ static int bcm2835_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + } + } + +-#ifdef CONFIG_OF ++#ifdef CONFIG_ARCH_BCM2835 + static int bcm2835_dma_chan_init(struct bcm2835_dmadev *d, int chan_id, int irq) + { + struct bcm2835_chan *c; +@@ -784,7 +784,7 @@ static const struct of_device_id bcm2835_dma_of_match[] = { + }; + MODULE_DEVICE_TABLE(of, bcm2835_dma_of_match); + +-#ifdef CONFIG_OF ++#ifdef CONFIG_ARCH_BCM2835 + static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec, + struct of_dma *ofdma) + { +@@ -817,7 +817,7 @@ static int bcm2835_dma_device_slave_caps(struct dma_chan *dchan, + static int bcm2835_dma_probe(struct platform_device *pdev) + { + struct bcm2835_dmadev *od; +-#ifdef CONFIG_OF ++#ifdef CONFIG_ARCH_BCM2835 + struct resource *res; + void __iomem *base; + uint32_t chans_available; +@@ -830,10 +830,10 @@ static int bcm2835_dma_probe(struct platform_device *pdev) + if (!pdev->dev.dma_mask) + pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; + +- /* If CONFIG_OF is selected, device tree is used */ ++ /* If CONFIG_ARCH_BCM2835 is selected, device tree is used */ + /* hence the difference between probing */ + +-#ifndef CONFIG_OF ++#ifndef CONFIG_ARCH_BCM2835 + + rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); + if (rc) +@@ -987,7 +987,7 @@ static int bcm2835_dma_remove(struct platform_device *pdev) + return 0; + } + +-#ifndef CONFIG_OF ++#ifndef CONFIG_ARCH_BCM2835 + + + static struct platform_driver bcm2835_dma_driver = { +diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c +index cefba7c..34d6167 100644 +--- a/drivers/mmc/host/bcm2835-mmc.c ++++ b/drivers/mmc/host/bcm2835-mmc.c +@@ -42,7 +42,7 @@ + #include "sdhci.h" + + +-#ifndef CONFIG_OF ++#ifndef CONFIG_ARCH_BCM2835 + #define BCM2835_CLOCK_FREQ 250000000 + #endif + +@@ -662,7 +662,7 @@ void bcm2835_mmc_send_command(struct bcm2835_host *host, struct mmc_command *cmd + } + + timeout = jiffies; +-#ifdef CONFIG_OF ++#ifdef CONFIG_ARCH_BCM2835 + if (!cmd->data && cmd->busy_timeout > 9000) + timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ; + else +@@ -962,7 +962,7 @@ static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id) + struct bcm2835_host *host = dev_id; + u32 intmask, mask, unexpected = 0; + int max_loops = 16; +-#ifndef CONFIG_OF ++#ifndef CONFIG_ARCH_BCM2835 + int cardint = 0; + #endif + +@@ -993,7 +993,7 @@ static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id) + mmc_hostname(host->mmc)); + + if (intmask & SDHCI_INT_CARD_INT) { +-#ifndef CONFIG_OF ++#ifndef CONFIG_ARCH_BCM2835 + cardint = 1; + #else + bcm2835_mmc_enable_sdio_irq_nolock(host, false); +@@ -1026,7 +1026,7 @@ out: + bcm2835_mmc_dumpregs(host); + } + +-#ifndef CONFIG_OF ++#ifndef CONFIG_ARCH_BCM2835 + if (cardint) + mmc_signal_sdio_irq(host->mmc); + #endif +@@ -1034,7 +1034,7 @@ out: + return result; + } + +-#ifdef CONFIG_OF ++#ifdef CONFIG_ARCH_BCM2835 + static irqreturn_t bcm2835_mmc_thread_irq(int irq, void *dev_id) + { + struct bcm2835_host *host = dev_id; +@@ -1288,7 +1288,7 @@ int bcm2835_mmc_add_host(struct bcm2835_host *host) + + /* SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK */ + host->timeout_clk = mmc->f_max / 1000; +-#ifdef CONFIG_OF ++#ifdef CONFIG_ARCH_BCM2835 + mmc->max_busy_timeout = (1 << 27) / host->timeout_clk; + #endif + /* host controller capabilities */ +@@ -1345,7 +1345,7 @@ int bcm2835_mmc_add_host(struct bcm2835_host *host) + init_waitqueue_head(&host->buf_ready_int); + + bcm2835_mmc_init(host, 0); +-#ifndef CONFIG_OF ++#ifndef CONFIG_ARCH_BCM2835 + ret = request_irq(host->irq, bcm2835_mmc_irq, 0 /*IRQF_SHARED*/, + mmc_hostname(mmc), host); + #else +@@ -1374,7 +1374,7 @@ untasklet: + static int bcm2835_mmc_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +-#ifdef CONFIG_OF ++#ifdef CONFIG_ARCH_BCM2835 + struct device_node *node = dev->of_node; + struct clk *clk; + #endif +@@ -1383,7 +1383,7 @@ static int bcm2835_mmc_probe(struct platform_device *pdev) + + int ret; + struct mmc_host *mmc; +-#if !defined(CONFIG_OF) && !defined(FORCE_PIO) ++#if !defined(CONFIG_ARCH_BCM2835) && !defined(FORCE_PIO) + dma_cap_mask_t mask; + #endif + +@@ -1408,7 +1408,7 @@ static int bcm2835_mmc_probe(struct platform_device *pdev) + + host->phys_addr = iomem->start + BCM2835_VCMMU_SHIFT; + +-#ifndef CONFIG_OF ++#ifndef CONFIG_ARCH_BCM2835 + #ifndef FORCE_PIO + dma_cap_zero(mask); + /* we don't care about the channel, any would work */ +@@ -1458,7 +1458,7 @@ static int bcm2835_mmc_probe(struct platform_device *pdev) + } + + +-#ifndef CONFIG_OF ++#ifndef CONFIG_ARCH_BCM2835 + mmc->caps |= MMC_CAP_4_BIT_DATA; + #else + mmc_of_parse(mmc); +diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c +index d134710..2e2b6d0 100644 +--- a/drivers/of/fdt.c ++++ b/drivers/of/fdt.c +@@ -1083,8 +1083,12 @@ static struct debugfs_blob_wrapper flat_dt_blob; + + static int __init of_flat_dt_debugfs_export_fdt(void) + { +- struct dentry *d = debugfs_create_dir("device-tree", NULL); ++ struct dentry *d; + ++ if (!initial_boot_params) ++ return -ENOENT; ++ ++ d = debugfs_create_dir("device-tree", NULL); + if (!d) + return -ENOENT; + +diff --git a/sound/soc/bcm/bcm2708-i2s.c b/sound/soc/bcm/bcm2708-i2s.c +index 0b5322a..a3b65dc 100644 +--- a/sound/soc/bcm/bcm2708-i2s.c ++++ b/sound/soc/bcm/bcm2708-i2s.c +@@ -493,15 +493,19 @@ static int bcm2708_i2s_hw_params(struct snd_pcm_substream *substream, + divf = dividend & BCM2708_CLK_DIVF_MASK; + } + +- /* Set clock divider */ +- regmap_write(dev->clk_regmap, BCM2708_CLK_PCMDIV_REG, BCM2708_CLK_PASSWD +- | BCM2708_CLK_DIVI(divi) +- | BCM2708_CLK_DIVF(divf)); +- +- /* Setup clock, but don't start it yet */ +- regmap_write(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, BCM2708_CLK_PASSWD +- | BCM2708_CLK_MASH(mash) +- | BCM2708_CLK_SRC(clk_src)); ++ /* Clock should only be set up here if CPU is clock master */ ++ if (((dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBS_CFS) || ++ ((dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBS_CFM)) { ++ /* Set clock divider */ ++ regmap_write(dev->clk_regmap, BCM2708_CLK_PCMDIV_REG, BCM2708_CLK_PASSWD ++ | BCM2708_CLK_DIVI(divi) ++ | BCM2708_CLK_DIVF(divf)); ++ ++ /* Setup clock, but don't start it yet */ ++ regmap_write(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, BCM2708_CLK_PASSWD ++ | BCM2708_CLK_MASH(mash) ++ | BCM2708_CLK_SRC(clk_src)); ++ } + + /* Setup the frame format */ + format = BCM2708_I2S_CHEN; +@@ -981,12 +985,19 @@ static int bcm2708_i2s_remove(struct platform_device *pdev) + return 0; + } + ++static const struct of_device_id bcm2708_i2s_of_match[] = { ++ { .compatible = "brcm,bcm2708-i2s", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, bcm2708_i2s_of_match); ++ + static struct platform_driver bcm2708_i2s_driver = { + .probe = bcm2708_i2s_probe, + .remove = bcm2708_i2s_remove, + .driver = { + .name = "bcm2708-i2s", + .owner = THIS_MODULE, ++ .of_match_table = bcm2708_i2s_of_match, + }, + }; + +diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c +index 2685fe4..e2c61d1 100644 +--- a/sound/soc/bcm/bcm2835-i2s.c ++++ b/sound/soc/bcm/bcm2835-i2s.c +@@ -861,6 +861,7 @@ static const struct of_device_id bcm2835_i2s_of_match[] = { + { .compatible = "brcm,bcm2835-i2s", }, + {}, + }; ++MODULE_DEVICE_TABLE(of, bcm2835_i2s_of_match); + + static struct platform_driver bcm2835_i2s_driver = { + .probe = bcm2835_i2s_probe, +-- +1.8.3.2 + |