summaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-3.18/0063-bcm2708-Allow-option-card-devices-to-be-configured-v.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm2708/patches-3.18/0063-bcm2708-Allow-option-card-devices-to-be-configured-v.patch')
-rwxr-xr-xtarget/linux/brcm2708/patches-3.18/0063-bcm2708-Allow-option-card-devices-to-be-configured-v.patch461
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
+