aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-01-10 14:51:31 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-01-10 14:51:31 -0800
commit17d64023e21da27fbb8c6621d70ea1456cc90707 (patch)
tree1d73bf774d8d5aee316dfb79668fb1f0b229a5bb
parentd23a9b6caf604d279aa43103018ca0176c373a66 (diff)
downloadltsi-kernel-17d64023e21da27fbb8c6621d70ea1456cc90707.tar.gz
2 more zynq patches added
-rw-r--r--patches.zynq/i2c-si570-merge-support-for-si570-clock-generator.patch667
-rw-r--r--patches.zynq/of-remove-ifdef-from-linux-of_platform.h.patch77
-rw-r--r--series2
3 files changed, 746 insertions, 0 deletions
diff --git a/patches.zynq/i2c-si570-merge-support-for-si570-clock-generator.patch b/patches.zynq/i2c-si570-merge-support-for-si570-clock-generator.patch
new file mode 100644
index 0000000000000..58be836572e9e
--- /dev/null
+++ b/patches.zynq/i2c-si570-merge-support-for-si570-clock-generator.patch
@@ -0,0 +1,667 @@
+From foo@baz Fri Jan 10 14:47:34 PST 2014
+From: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp>
+Date: Tue, 7 Jan 2014 15:48:10 +0900
+Subject: [PATCH V2 02/12] i2c: si570: merge support for si570 clock generator
+To: ltsi-dev@lists.linuxfoundation.org
+Cc: gregkh@linuxfoundation.org, michal.simek@xilinx.com
+Message-ID: <1389077290-13613-3-git-send-email-daniel.sangorrin@toshiba.co.jp>
+
+
+From: Rob Armstrong <ra@xilinx.com>
+
+This merges support for the si5790 clock generator from the Xilinx
+repository (commit efc27505715e64526653f35274717c0fc56491e3 from
+master branch).
+
+Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp>
+Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp>
+---
+ drivers/misc/Kconfig | 10
+ drivers/misc/Makefile | 1
+ drivers/misc/si570.c | 575 ++++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/i2c/si570.h | 31 ++
+ 4 files changed, 617 insertions(+)
+ create mode 100644 drivers/misc/si570.c
+ create mode 100644 include/linux/i2c/si570.h
+
+--- a/drivers/misc/Kconfig
++++ b/drivers/misc/Kconfig
+@@ -507,6 +507,16 @@ config USB_SWITCH_FSA9480
+ stereo and mono audio, video, microphone and UART data to use
+ a common connector port.
+
++config SI570
++ tristate "Silicon Labs Si570 Clock Generator"
++ depends on I2C && SYSFS
++ help
++ If you say yes here you get support for the Silicon Labs Si570
++ digital clock generator.
++
++ To compile this driver as a module, choose M here: the module
++ will be called si570
++
+ config LATTICE_ECP3_CONFIG
+ tristate "Lattice ECP3 FPGA bitstream configuration via SPI"
+ depends on SPI && SYSFS
+--- a/drivers/misc/Makefile
++++ b/drivers/misc/Makefile
+@@ -50,6 +50,7 @@ obj-y += carma/
+ obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
+ obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
+ obj-$(CONFIG_INTEL_MEI) += mei/
++obj-$(CONFIG_SI570) += si570.o
+ obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/
+ obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o
+ obj-$(CONFIG_SRAM) += sram.o
+--- /dev/null
++++ b/drivers/misc/si570.c
+@@ -0,0 +1,575 @@
++/*
++ * Driver for Silicon Labs Si570/Si571 Programmable XO/VCXO
++ *
++ * Copyright (C) 2010, 2011 Ericsson AB.
++ * Copyright (C) 2011 Guenter Roeck.
++ *
++ * Author: Guenter Roeck <guenter.roeck@ericsson.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <linux/module.h>
++#include <linux/jiffies.h>
++#include <linux/i2c.h>
++#include <linux/err.h>
++#include <linux/mutex.h>
++#include <linux/delay.h>
++#include <linux/log2.h>
++#include <linux/slab.h>
++#include <linux/i2c/si570.h>
++
++/* Si570 registers */
++#define SI570_REG_HS_N1 7
++#define SI570_REG_N1_RFREQ0 8
++#define SI570_REG_RFREQ1 9
++#define SI570_REG_RFREQ2 10
++#define SI570_REG_RFREQ3 11
++#define SI570_REG_RFREQ4 12
++#define SI570_REG_CONTROL 135
++#define SI570_REG_FREEZE_DCO 137
++
++#define HS_DIV_SHIFT 5
++#define HS_DIV_MASK 0xe0
++#define HS_DIV_OFFSET 4
++#define N1_6_2_MASK 0x1f
++#define N1_1_0_MASK 0xc0
++#define RFREQ_37_32_MASK 0x3f
++
++#define SI570_FOUT_FACTORY_DFLT 156250000LL
++#define SI598_FOUT_FACTORY_DFLT 10000000LL
++
++#define SI570_MIN_FREQ 10000000L
++#define SI570_MAX_FREQ 1417500000L
++#define SI598_MAX_FREQ 525000000L
++
++#define FDCO_MIN 4850000000LL
++#define FDCO_MAX 5670000000LL
++#define FDCO_CENTER ((FDCO_MIN + FDCO_MAX) / 2)
++
++#define SI570_CNTRL_RECALL (1 << 0)
++#define SI570_CNTRL_FREEZE_ADC (1 << 4)
++#define SI570_CNTRL_FREEZE_M (1 << 5)
++#define SI570_CNTRL_NEWFREQ (1 << 6)
++#define SI570_CNTRL_RESET (1 << 7)
++
++#define SI570_FREEZE_DCO (1 << 4)
++#define SI570_UNFREEZE_DCO 0xEF
++
++struct si570_data {
++ struct attribute_group attrs;
++ struct mutex lock;
++ u64 max_freq;
++ u64 fout; /* Factory default frequency */
++ u64 fxtal; /* Factory xtal frequency */
++ unsigned int n1;
++ unsigned int hs_div;
++ u64 rfreq;
++ u64 frequency;
++};
++
++
++static struct i2c_client *si570_client;
++
++
++static int si570_get_defaults(struct i2c_client *client)
++{
++ struct si570_data *data = i2c_get_clientdata(client);
++ int reg1, reg2, reg3, reg4, reg5, reg6;
++ u64 fdco;
++
++ i2c_smbus_write_byte_data(client, SI570_REG_CONTROL,
++ SI570_CNTRL_RECALL);
++
++ reg1 = i2c_smbus_read_byte_data(client, SI570_REG_HS_N1);
++ if (reg1 < 0)
++ return reg1;
++ reg2 = i2c_smbus_read_byte_data(client, SI570_REG_N1_RFREQ0);
++ if (reg2 < 0)
++ return reg2;
++ reg3 = i2c_smbus_read_byte_data(client, SI570_REG_RFREQ1);
++ if (reg3 < 0)
++ return reg3;
++ reg4 = i2c_smbus_read_byte_data(client, SI570_REG_RFREQ2);
++ if (reg4 < 0)
++ return reg4;
++ reg5 = i2c_smbus_read_byte_data(client, SI570_REG_RFREQ3);
++ if (reg5 < 0)
++ return reg5;
++ reg6 = i2c_smbus_read_byte_data(client, SI570_REG_RFREQ4);
++ if (reg6 < 0)
++ return reg6;
++
++ data->hs_div = ((reg1 & HS_DIV_MASK) >> HS_DIV_SHIFT) + HS_DIV_OFFSET;
++ data->n1 = ((reg1 & N1_6_2_MASK) << 2) + ((reg2 & N1_1_0_MASK) >> 6)
++ + 1;
++ /* Handle invalid cases */
++ if (data->n1 > 1)
++ data->n1 &= ~1;
++
++ data->rfreq = reg2 & RFREQ_37_32_MASK;
++ data->rfreq = (data->rfreq << 8) + reg3;
++ data->rfreq = (data->rfreq << 8) + reg4;
++ data->rfreq = (data->rfreq << 8) + reg5;
++ data->rfreq = (data->rfreq << 8) + reg6;
++
++ /*
++ * Accept optional precision loss to avoid arithmetic overflows.
++ * Acceptable per Silicon Labs Application Note AN334.
++ */
++ fdco = data->fout * data->n1 * data->hs_div;
++ if (fdco >= (1LL << 36))
++ data->fxtal = div64_u64((fdco << 24), (data->rfreq >> 4));
++ else
++ data->fxtal = div64_u64((fdco << 28), data->rfreq);
++
++ data->frequency = data->fout;
++
++ return 0;
++}
++
++/*
++ * Update rfreq registers
++ * This function must be called with update mutex lock held.
++ */
++static void si570_update_rfreq(struct i2c_client *client,
++ struct si570_data *data)
++{
++ int status;
++ status = i2c_smbus_write_byte_data(client, SI570_REG_N1_RFREQ0,
++ ((data->n1 - 1) << 6)
++ | ((data->rfreq >> 32) & RFREQ_37_32_MASK));
++ if (status < 0)
++ dev_err(&client->dev,
++ "unable to write 0x%llX to REG_N1_RFREQ0: %d\n",
++ (((data->n1 - 1) << 6) | ((data->rfreq >> 32) &
++ RFREQ_37_32_MASK)) & 0xff, status);
++ status = i2c_smbus_write_byte_data(client, SI570_REG_RFREQ1,
++ (data->rfreq >> 24) & 0xff);
++ if (status < 0)
++ dev_err(&client->dev,
++ "unable to write 0x%llX to REG_RFREQ1: %d\n",
++ (data->rfreq >> 24) & 0xff, status);
++ status = i2c_smbus_write_byte_data(client, SI570_REG_RFREQ2,
++ (data->rfreq >> 16) & 0xff);
++ if (status < 0)
++ dev_err(&client->dev,
++ "unable to write 0x%llX to REG_RFREQ2: %d\n",
++ (data->rfreq >> 16) & 0xff, status);
++ status = i2c_smbus_write_byte_data(client, SI570_REG_RFREQ3,
++ (data->rfreq >> 8) & 0xff);
++ if (status < 0)
++ dev_err(&client->dev,
++ "unable to write 0x%llX to REG_RFREQ3: %d\n",
++ (data->rfreq >> 8) & 0xff, status);
++ status = i2c_smbus_write_byte_data(client, SI570_REG_RFREQ4,
++ data->rfreq & 0xff);
++ if (status < 0)
++ dev_err(&client->dev,
++ "unable to write 0x%llX to REG_RFREQ4: %d\n",
++ data->rfreq & 0xff, status);
++}
++
++/*
++ * Update si570 frequency for small frequency changes (< 3,500 ppm)
++ * This function must be called with update mutex lock held.
++ */
++static int si570_set_frequency_small(struct i2c_client *client,
++ struct si570_data *data,
++ unsigned long frequency)
++{
++ data->frequency = frequency;
++ /* This is a re-implementation of DIV_ROUND_CLOSEST
++ * using the div64_u64 function lieu of letting the compiler
++ * insert EABI calls
++ */
++ data->rfreq = div64_u64((data->rfreq * frequency) +
++ div64_u64(data->frequency, 2), data->frequency);
++ i2c_smbus_write_byte_data(client, SI570_REG_CONTROL,
++ SI570_CNTRL_FREEZE_M);
++ si570_update_rfreq(client, data);
++ i2c_smbus_write_byte_data(client, SI570_REG_CONTROL, 0);
++
++ return 0;
++}
++
++static const uint8_t si570_hs_div_values[] = { 11, 9, 7, 6, 5, 4 };
++
++/*
++ * Set si570 frequency.
++ * This function must be called with update mutex lock held.
++ */
++static int si570_set_frequency(struct i2c_client *client,
++ struct si570_data *data,
++ unsigned long frequency)
++{
++ int i, n1, hs_div;
++ u64 fdco, best_fdco = ULLONG_MAX;
++
++ for (i = 0; i < ARRAY_SIZE(si570_hs_div_values); i++) {
++ hs_div = si570_hs_div_values[i];
++ /* Calculate lowest possible value for n1 */
++ n1 = div64_u64(div64_u64(FDCO_MIN, (u64)hs_div),
++ (u64)frequency);
++ if (!n1 || (n1 & 1))
++ n1++;
++ while (n1 <= 128) {
++ fdco = (u64)frequency * (u64)hs_div * (u64)n1;
++ if (fdco > FDCO_MAX)
++ break;
++ if (fdco >= FDCO_MIN && fdco < best_fdco) {
++ data->n1 = n1;
++ data->hs_div = hs_div;
++ data->frequency = frequency;
++ data->rfreq = div64_u64((fdco << 28),
++ data->fxtal);
++ best_fdco = fdco;
++ }
++ n1 += (n1 == 1 ? 1 : 2);
++ }
++ }
++ if (best_fdco == ULLONG_MAX) {
++ dev_err(&client->dev, "error - best FDCO is out of range\n");
++ return -EINVAL;
++ }
++
++ /* The DCO reg should be accessed with a read-modify-write operation
++ * per AN334
++ */
++ i2c_smbus_write_byte_data(client, SI570_REG_FREEZE_DCO,
++ SI570_FREEZE_DCO);
++ i2c_smbus_write_byte_data(client, SI570_REG_HS_N1,
++ ((data->hs_div - HS_DIV_OFFSET) <<
++ HS_DIV_SHIFT)
++ | (((data->n1 - 1) >> 2) & N1_6_2_MASK));
++ si570_update_rfreq(client, data);
++ i2c_smbus_write_byte_data(client, SI570_REG_FREEZE_DCO,
++ 0);
++ i2c_smbus_write_byte_data(client, SI570_REG_CONTROL,
++ SI570_CNTRL_NEWFREQ);
++ return 0;
++}
++
++/*
++ * Reset chip.
++ * This function must be called with update mutex lock held.
++ */
++static int si570_reset(struct i2c_client *client, struct si570_data *data)
++{
++ i2c_smbus_write_byte_data(client, SI570_REG_CONTROL,
++ SI570_CNTRL_RESET);
++ usleep_range(1000, 5000);
++ return si570_set_frequency(client, data, data->frequency);
++}
++
++static ssize_t show_frequency_attr(struct device *dev,
++ struct device_attribute *devattr,
++ char *buf)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct si570_data *data = i2c_get_clientdata(client);
++
++ return sprintf(buf, "%llu\n", data->frequency);
++}
++
++int get_frequency_si570(struct device *dev, unsigned long *freq)
++{
++ int err;
++ char buf[10+1];
++
++ if ((!dev) || (to_i2c_client(dev) != si570_client))
++ return -EINVAL;
++
++ show_frequency_attr(dev, NULL, buf);
++
++ err = kstrtoul(buf, 10, freq);
++ if (err)
++ return err;
++
++ return 0;
++}
++EXPORT_SYMBOL(get_frequency_si570);
++
++static ssize_t set_frequency_attr(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct si570_data *data = i2c_get_clientdata(client);
++ unsigned long val;
++ int err;
++
++ err = kstrtoul(buf, 10, &val);
++ if (err)
++ return err;
++
++ if (val < SI570_MIN_FREQ || val > data->max_freq) {
++ dev_err(&client->dev,
++ "requested frequency %lu Hz is out of range\n", val);
++ return -EINVAL;
++ }
++
++ mutex_lock(&data->lock);
++
++ if (div64_u64(abs(val - data->frequency) * 10000LL,
++ data->frequency) < 35)
++ err = si570_set_frequency_small(client, data, val);
++ else
++ err = si570_set_frequency(client, data, val);
++ mutex_unlock(&data->lock);
++ if (err) {
++ dev_warn(&client->dev,
++ "unable to set output frequency %lu Hz: %d\n",
++ val, err);
++ return err;
++ }
++
++ dev_info(&client->dev,
++ "set new output frequency %lu Hz\n", val);
++
++ return count;
++}
++
++int set_frequency_si570(struct device *dev, unsigned long freq)
++{
++ char buf[10+1];
++
++ if ((!dev) || (to_i2c_client(dev) != si570_client))
++ return -EINVAL;
++
++ sprintf(buf, "%lu", freq);
++
++ return set_frequency_attr(dev, NULL, buf, 0);
++}
++EXPORT_SYMBOL(set_frequency_si570);
++
++static ssize_t show_reset_attr(struct device *dev,
++ struct device_attribute *devattr,
++ char *buf)
++{
++ return sprintf(buf, "%d\n", 0);
++}
++
++static ssize_t set_reset_attr(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct si570_data *data = i2c_get_clientdata(client);
++ unsigned long val;
++ int err;
++
++ err = kstrtoul(buf, 10, &val);
++ if (err)
++ return err;
++ if (val == 0)
++ goto done;
++
++ mutex_lock(&data->lock);
++ err = si570_reset(client, data);
++ mutex_unlock(&data->lock);
++ if (err)
++ return err;
++done:
++ return count;
++}
++
++int reset_si570(struct device *dev, int id)
++{
++ char buf[4];
++
++ if ((!dev) || (to_i2c_client(dev) != si570_client))
++ return -EINVAL;
++
++ sprintf(buf, "%lu", (unsigned long)id);
++ return set_reset_attr(dev, NULL, buf, 0);
++}
++EXPORT_SYMBOL(reset_si570);
++
++struct i2c_client *get_i2c_client_si570(void)
++{
++ return si570_client;
++}
++EXPORT_SYMBOL(get_i2c_client_si570);
++
++static DEVICE_ATTR(frequency, S_IWUSR | S_IRUGO, show_frequency_attr,
++ set_frequency_attr);
++static DEVICE_ATTR(reset, S_IWUSR | S_IRUGO, show_reset_attr, set_reset_attr);
++
++static struct attribute *si570_attr[] = {
++ &dev_attr_frequency.attr,
++ &dev_attr_reset.attr,
++ NULL
++};
++
++static const struct i2c_device_id si570_id[] = {
++ { "si570", 0 },
++ { "si571", 0 },
++ { "si598", 1 },
++ { "si599", 1 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, si570_id);
++
++static int si570_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ struct si570_platform_data *pdata = client->dev.platform_data;
++ struct si570_data *data;
++ int err;
++ unsigned long initial_fout;
++ u32 tmp = SI570_FOUT_FACTORY_DFLT;
++
++ data = kzalloc(sizeof(struct si570_data), GFP_KERNEL);
++ if (!data) {
++ err = -ENOMEM;
++ goto exit;
++ }
++
++ if (id->driver_data) {
++ data->fout = SI598_FOUT_FACTORY_DFLT;
++ data->max_freq = SI598_MAX_FREQ;
++ } else {
++ data->fout = SI570_FOUT_FACTORY_DFLT;
++ data->max_freq = SI570_MAX_FREQ;
++ }
++
++ if (pdata && pdata->factory_fout)
++ data->fout = pdata->factory_fout;
++
++ if (client->dev.of_node &&
++ (of_property_read_u32(client->dev.of_node, "factory-fout",
++ &tmp) < 0))
++ dev_warn(&client->dev,
++ "DTS does not contain factory-fout, using default\n");
++ else
++ data->fout = tmp;
++
++ i2c_set_clientdata(client, data);
++ err = si570_get_defaults(client);
++ if (err < 0)
++ goto exit_free;
++
++ mutex_init(&data->lock);
++
++ /* Register sysfs hooks */
++ data->attrs.attrs = si570_attr;
++ err = sysfs_create_group(&client->dev.kobj, &data->attrs);
++ if (err)
++ goto exit_free;
++
++ /* Display a message indicating that we've successfully registered */
++ dev_info(&client->dev,
++ "registered %s with default frequency %llu Hz\n",
++ id->name, data->fout);
++
++ /* Read the requested initial fout from either platform data or the
++ * device tree
++ */
++ initial_fout = 0;
++ if (pdata && pdata->initial_fout)
++ initial_fout = pdata->initial_fout;
++ if (client->dev.of_node) {
++ of_property_read_u32(client->dev.of_node, "initial-fout",
++ (u32 *)&initial_fout);
++ if (pdata && pdata->initial_fout &&
++ (pdata->initial_fout != initial_fout)) {
++ dev_warn(&client->dev,
++ "OF initial fout %lu overrides platform data fout %lu\n",
++ initial_fout,
++ pdata->initial_fout);
++ }
++ }
++
++ if (initial_fout != 0) {
++ if (initial_fout < SI570_MIN_FREQ ||
++ initial_fout > data->max_freq) {
++ dev_err(&client->dev,
++ "requested initial frequency %lu is out of range, using default\n",
++ initial_fout);
++ return 0;
++ }
++
++ mutex_lock(&data->lock);
++
++ if (div64_u64(abs(initial_fout - data->frequency) *
++ 10000LL, data->frequency) < 35)
++ err = si570_set_frequency_small(client, data,
++ initial_fout);
++ else
++ err = si570_set_frequency(client, data,
++ initial_fout);
++ mutex_unlock(&data->lock);
++ if (err) {
++ dev_warn(&client->dev,
++ "unable to set initial output frequency %lu: %d\n",
++ initial_fout, err);
++ return err;
++ }
++
++ dev_info(&client->dev,
++ "set initial output frequency %lu Hz\n",
++ initial_fout);
++ }
++
++ si570_client = client;
++
++ return 0;
++
++exit_free:
++ kfree(data);
++exit:
++ return err;
++}
++
++static int si570_remove(struct i2c_client *client)
++{
++ struct si570_data *data = i2c_get_clientdata(client);
++
++ sysfs_remove_group(&client->dev.kobj, &data->attrs);
++ kfree(data);
++ return 0;
++}
++
++#ifdef CONFIG_OF
++static const struct of_device_id i2c_si570_of_match[] = {
++ { .compatible = "si570" },
++ { },
++};
++MODULE_DEVICE_TABLE(of, i2c_si570_of_match);
++#endif
++
++static struct i2c_driver si570_driver = {
++ .driver = {
++ .name = "si570",
++ .of_match_table = of_match_ptr(i2c_si570_of_match),
++ },
++ .probe = si570_probe,
++ .remove = si570_remove,
++ .id_table = si570_id,
++};
++
++static int __init si570_init(void)
++{
++ return i2c_add_driver(&si570_driver);
++}
++
++static void __exit si570_exit(void)
++{
++ i2c_del_driver(&si570_driver);
++}
++
++MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>");
++MODULE_DESCRIPTION("Si570 driver");
++MODULE_LICENSE("GPL");
++
++module_init(si570_init);
++module_exit(si570_exit);
+--- /dev/null
++++ b/include/linux/i2c/si570.h
+@@ -0,0 +1,31 @@
++/*
++ * si570.h - Configuration for si570 misc driver.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation (version 2 of the License only).
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef __LINUX_SI570_H
++#define __LINUX_SI570_H
++
++#include <linux/types.h>
++#include <linux/device.h>
++#include <linux/i2c.h>
++
++struct si570_platform_data {
++ u64 factory_fout; /* Factory default output frequency */
++ unsigned long initial_fout; /* Requested initial frequency */
++};
++
++int get_frequency_si570(struct device *dev, unsigned long *freq);
++int set_frequency_si570(struct device *dev, unsigned long freq);
++int reset_si570(struct device *dev, int id);
++struct i2c_client *get_i2c_client_si570(void);
++
++#endif /* __LINUX_SI570_H */
diff --git a/patches.zynq/of-remove-ifdef-from-linux-of_platform.h.patch b/patches.zynq/of-remove-ifdef-from-linux-of_platform.h.patch
new file mode 100644
index 0000000000000..b168a924fce2e
--- /dev/null
+++ b/patches.zynq/of-remove-ifdef-from-linux-of_platform.h.patch
@@ -0,0 +1,77 @@
+From foo@baz Fri Jan 10 14:47:34 PST 2014
+From: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp>
+Date: Tue, 7 Jan 2014 15:48:09 +0900
+Subject: [PATCH] of: remove #ifdef from linux/of_platform.h
+To: ltsi-dev@lists.linuxfoundation.org
+Cc: gregkh@linuxfoundation.org, michal.simek@xilinx.com
+Message-ID: <1389077290-13613-2-git-send-email-daniel.sangorrin@toshiba.co.jp>
+
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+A lot of code uses the functions from of_platform.h when built for
+devicetree-enabled platforms but can also be built without them.
+In order to avoid using #ifdef everywhere in drivers, this
+makes all the function declarations visible, which means we
+can use "if (IS_ENABLED(CONFIG_OF))" in driver code and get build
+coverage over the code but let the compiler drop the reference
+in the object code.
+
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Cc: Grant Likely <grant.likely@linaro.org>
+Cc: Rob Herring <rob.herring@calxeda.com>
+Signed-off-by: Grant Likely <grant.likely@linaro.org>
+(cherry picked from commit 8a46f4f7f95f2bece108998a2e1b87b58f99d590)
+Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp>
+Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp>
+---
+ include/linux/of_platform.h | 14 +++-----------
+ 1 file changed, 3 insertions(+), 11 deletions(-)
+
+--- a/include/linux/of_platform.h
++++ b/include/linux/of_platform.h
+@@ -13,8 +13,6 @@
+
+ #include <linux/device.h>
+ #include <linux/mod_devicetable.h>
+-
+-#ifdef CONFIG_OF_DEVICE
+ #include <linux/pm.h>
+ #include <linux/of_device.h>
+ #include <linux/platform_device.h>
+@@ -82,7 +80,6 @@ extern struct platform_device *of_device
+ struct device *parent);
+ extern struct platform_device *of_find_device_by_node(struct device_node *np);
+
+-#ifdef CONFIG_OF_ADDRESS /* device reg helpers depend on OF_ADDRESS */
+ /* Platform devices and busses creation */
+ extern struct platform_device *of_platform_device_create(struct device_node *np,
+ const char *bus_id,
+@@ -91,17 +88,12 @@ extern struct platform_device *of_platfo
+ extern int of_platform_bus_probe(struct device_node *root,
+ const struct of_device_id *matches,
+ struct device *parent);
++#ifdef CONFIG_OF_ADDRESS
+ extern int of_platform_populate(struct device_node *root,
+ const struct of_device_id *matches,
+ const struct of_dev_auxdata *lookup,
+ struct device *parent);
+-#endif /* CONFIG_OF_ADDRESS */
+-
+-#endif /* CONFIG_OF_DEVICE */
+-
+-#if !defined(CONFIG_OF_ADDRESS)
+-struct of_dev_auxdata;
+-struct device_node;
++#else
+ static inline int of_platform_populate(struct device_node *root,
+ const struct of_device_id *matches,
+ const struct of_dev_auxdata *lookup,
+@@ -109,6 +101,6 @@ static inline int of_platform_populate(s
+ {
+ return -ENODEV;
+ }
+-#endif /* !CONFIG_OF_ADDRESS */
++#endif
+
+ #endif /* _LINUX_OF_PLATFORM_H */
diff --git a/series b/series
index 225bd504c5c75..c86d90272cdf1 100644
--- a/series
+++ b/series
@@ -2537,6 +2537,8 @@ patches.zynq/0009-usb-zynq-merge-usb-support-for-xilinx-zynq-soc.patch
patches.zynq/0010-memory-zynq-merge-driver-for-Zynq-SMC.patch
patches.zynq/0011-arm-dts-zynq-Merge-zynq-zc702.dts-with-Xilinx-reposi.patch
patches.zynq/0012-defconfig-zynq-merge-xilinx-zynq-defconfig-from-xili.patch
+patches.zynq/of-remove-ifdef-from-linux-of_platform.h.patch
+patches.zynq/i2c-si570-merge-support-for-si570-clock-generator.patch
#############################################################################