* [PATCH 0/9] ARM: Kirkwood: Convert to pinctrl
From: Andrew Lunn @ 2012-10-25 5:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121024233356.1bda95bf@skate>
On Wed, Oct 24, 2012 at 11:33:56PM +0200, Thomas Petazzoni wrote:
> Andrew,
>
> On Wed, 24 Oct 2012 22:01:28 +0200, Andrew Lunn wrote:
>
> > I guess it is too early to use gpio. I don't think the gpio driver has
> > not been configured yet.
> >
> > I need to think about this.
> >
> > What happens if you comment out these two gpio_set_value calls?
>
> The problem is (probably, I haven't tested) that in
> mach-kirkwood/board-dt.c, the of_platform_populate() function is called
> after all the board-specific init. So all the devices described in the
> DT, including GPIO banks, have not been registered yet. Most likely the
> of_platform_populate() should come before the board specific inits.
Thanks Thomas, i will play around with this.
I'm just wondering if we are going to get into ordering issues. These
gpio operations are providing power to subsystems. We probably need
that to happen before the driver is loaded. If we call
of_platform_populate() too early, do we have the danger the driver
probing is going to happen before the init routine can enable the
power?
It seems like we want pinctrl/gpio working first, with pins hogged as
specified in DT, then the board init() function, then the rest of DT
setup.
> Also there should probably be a gpio_request() before those
> gpio_set_value().
Yes. That worked before, but might break now. Most of the init()
functions do actually make a gpip_request() call.
Andrew
^ permalink raw reply
* [PATCH v2 2/3] serial: mxs-auart: add the DMA support for mx28
From: Huang Shijie @ 2012-10-25 5:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351138689.5263.68.camel@vkoul-udesk3>
? 2012?10?25? 12:18, Vinod Koul ??:
>
>> +
>> +static int mxs_auart_dma_tx(struct mxs_auart_port *s, int size)
>> +{
>> + struct dma_async_tx_descriptor *desc;
>> + struct scatterlist *sgl =&s->tx_sgl;
>> + struct dma_chan *channel = s->tx_dma_chan;
>> + u32 pio;
>> +
>> + /* [1] : send PIO. Note, the first pio word is CTRL1. */
>> + pio = AUART_CTRL1_XFER_COUNT(size);
>> + desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)&pio,
>> + 1, DMA_TRANS_NONE, 0);
> this seems like a hack. API expects a scatterlist as argument.
> Same thing about direction, NONE doesnt mean anything for dma transfer.
It's not a hack. this DMA descriptor is used to set the registers.
Please see the code in drivers/dma/mxs-dma.c:mxs_dam_prep_slave_sg().
>> + if (!desc) {
>> + dev_err(s->dev, "step 1 error\n");
>> + return -EINVAL;
>> + }
>> +
>> + /* [2] : set DMA buffer. */
>> + sg_init_one(sgl, s->tx_dma_buf, size);
>> + dma_map_sg(s->dev, sgl, 1, DMA_TO_DEVICE);
>> + desc = dmaengine_prep_slave_sg(channel, sgl,
>> + 1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
>> + if (!desc) {
>> + dev_err(s->dev, "step 2 error\n");
>> + return -EINVAL;
>> + }
>> +
>> + /* [3] : submit the DMA */
>> + desc->callback = dma_tx_callback;
>> + desc->callback_param = s;
>> + dmaengine_submit(desc);
>> + dma_async_issue_pending(channel);
>> + return 0;
>> +}
>> +
>>
>> +static bool mxs_auart_dma_filter(struct dma_chan *chan, void *param)
>> +{
>> + struct mxs_auart_port *s = param;
>> +
>> + if (!mxs_dma_is_apbx(chan))
>> + return false;
>> +
>> + if (s->dma_channel == chan->chan_id) {
>> + chan->private =&s->dma_data;
> dont use chan->private. You need to dmaengine_slave_config API
please see the drivers/dma/mxs-dma.c:mxs_dam_alloc_chan_resoures().
The mxs-dma driver uses ->private to store the channel interrupt number.
thanks
Huang Shijie
>> + return true;
>> + }
>> + return false;
>> +}
>> +
^ permalink raw reply
* [PATCH] i2c: omap: re-factor omap_i2c_init function
From: Shubhrajyoti Datta @ 2012-10-25 5:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121023175706.GC32517@arwen.pp.htv.fi>
On Tue, Oct 23, 2012 at 11:27 PM, Felipe Balbi <balbi@ti.com> wrote:
> Hi,
>
> On Tue, Oct 23, 2012 at 11:26:15PM +0530, Shubhrajyoti Datta wrote:
>> >> @@ -1268,23 +1271,8 @@ static int omap_i2c_runtime_resume(struct device *dev)
>> >> {
>> >> struct omap_i2c_dev *_dev = dev_get_drvdata(dev);
>> >>
>> >> - if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
>> >> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
>> >> - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
>> >> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
>> >> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
>> >> - omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
>> >> - omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
>> >> - omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
>> >> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
>> >> - }
>> >> -
>> >> - /*
>> >> - * Don't write to this register if the IE state is 0 as it can
>> >> - * cause deadlock.
>> >> - */
>> >> - if (_dev->iestate)
>> >> - omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate);
>> >
>> > this part is not on __omap_i2c_init() so you're potentially causing a
>> > regression here.
>>
>> iestate is set at init so cannot be zero. so the check was removed.
>
Hmm thinking a little more, there is a case that I missed the resume
handler may get called before
the omap_i2c_init will restore the check and send another version.
^ permalink raw reply
* [PATCH v2 2/3] serial: mxs-auart: add the DMA support for mx28
From: Vinod Koul @ 2012-10-25 6:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5088D336.7040206@freescale.com>
On Thu, 2012-10-25 at 13:50 +0800, Huang Shijie wrote:
> ? 2012?10?25? 12:18, Vinod Koul ??:
> >
> >> +
> >> +static int mxs_auart_dma_tx(struct mxs_auart_port *s, int size)
> >> +{
> >> + struct dma_async_tx_descriptor *desc;
> >> + struct scatterlist *sgl =&s->tx_sgl;
> >> + struct dma_chan *channel = s->tx_dma_chan;
> >> + u32 pio;
> >> +
> >> + /* [1] : send PIO. Note, the first pio word is CTRL1. */
> >> + pio = AUART_CTRL1_XFER_COUNT(size);
> >> + desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)&pio,
> >> + 1, DMA_TRANS_NONE, 0);
> > this seems like a hack. API expects a scatterlist as argument.
> > Same thing about direction, NONE doesnt mean anything for dma transfer.
> It's not a hack. this DMA descriptor is used to set the registers.
> Please see the code in drivers/dma/mxs-dma.c:mxs_dam_prep_slave_sg().
yes it is, and also an abuse of the api.
prep_slave_sg() expects a scatter list and you are passing something
else and using DMA_TRANS_NONE to do that, which makes no sense!!!
If you have to setup your registers you need to setup based on what APIs
passed you and not by abusing.
> >> + if (!desc) {
> >> + dev_err(s->dev, "step 1 error\n");
> >> + return -EINVAL;
> >> + }
> >> +
> >> + /* [2] : set DMA buffer. */
> >> + sg_init_one(sgl, s->tx_dma_buf, size);
> >> + dma_map_sg(s->dev, sgl, 1, DMA_TO_DEVICE);
> >> + desc = dmaengine_prep_slave_sg(channel, sgl,
> >> + 1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> >> + if (!desc) {
> >> + dev_err(s->dev, "step 2 error\n");
> >> + return -EINVAL;
> >> + }
> >> +
> >> + /* [3] : submit the DMA */
> >> + desc->callback = dma_tx_callback;
> >> + desc->callback_param = s;
> >> + dmaengine_submit(desc);
> >> + dma_async_issue_pending(channel);
> >> + return 0;
> >> +}
> >> +
> >>
> >> +static bool mxs_auart_dma_filter(struct dma_chan *chan, void *param)
> >> +{
> >> + struct mxs_auart_port *s = param;
> >> +
> >> + if (!mxs_dma_is_apbx(chan))
> >> + return false;
> >> +
> >> + if (s->dma_channel == chan->chan_id) {
> >> + chan->private =&s->dma_data;
> > dont use chan->private. You need to dmaengine_slave_config API
> please see the drivers/dma/mxs-dma.c:mxs_dam_alloc_chan_resoures().
>
> The mxs-dma driver uses ->private to store the channel interrupt number.
And which it should not be doing. private is not supposed to be used for
passing info. If it is generic add to slave config.
--
Vinod Koul
Intel Corp.
^ permalink raw reply
* [PATCH v2 1/3] drivers: bus: ocp2scp: add pdata support
From: Felipe Balbi @ 2012-10-25 6:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121025004806.GK11928@atomide.com>
Hi,
On Wed, Oct 24, 2012 at 05:48:07PM -0700, Tony Lindgren wrote:
> * Tony Lindgren <tony@atomide.com> [121016 09:53]:
> > * Kishon Vijay Abraham I <kishon@ti.com> [121007 23:01]:
> > > ocp2scp was not having pdata support which makes *musb* fail for non-dt
> > > boot in OMAP platform. The pdata will have information about the devices
> > > that is connected to ocp2scp. ocp2scp driver will now make use of this
> > > information to create the devices that is attached to ocp2scp.
> > >
> > > Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> >
> > This fixes the regression on my panda es for musb port:
> >
> > Acked-by: Tony Lindgren <tony@atomide.com>
>
> Looks like nobody has picked this one up and we need it to
> fix the musb regression on omap, so I'll queue these up.
I don't seem to have the patches around in any mailbox :-(
--
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121025/aa8ffc49/attachment.sig>
^ permalink raw reply
* [PATCH 1/4] net: mvneta: driver for Marvell Armada 370/XP network unit
From: Thomas Petazzoni @ 2012-10-25 6:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121024.230648.1888101216213031807.davem@davemloft.net>
David,
On Wed, 24 Oct 2012 23:06:48 -0400 (EDT), David Miller wrote:
> From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> Date: Tue, 23 Oct 2012 18:54:57 +0200
>
> > + u32 cause_rx_tx[CONFIG_NR_CPUS];
>
> Please use per-cpu variables instead of explicitly sized
> arrays.
Ok, thanks. In fact, this per-cpu array is not needed in the current
version of the driver, it will only be needed when we make improvements
to it that bind RX queues to specific CPUs. So for now, I'll get rid of
it.
I'll wait a bit more to see if there are any comments, and I'll repost
an updated v4 of the patches.
Thanks a lot for your review,
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* [PATCH 0/9] ARM: Kirkwood: Convert to pinctrl
From: Thomas Petazzoni @ 2012-10-25 6:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121025054638.GB8590@lunn.ch>
Andrew,
On Thu, 25 Oct 2012 07:46:38 +0200, Andrew Lunn wrote:
> Thanks Thomas, i will play around with this.
>
> I'm just wondering if we are going to get into ordering issues. These
> gpio operations are providing power to subsystems. We probably need
> that to happen before the driver is loaded. If we call
> of_platform_populate() too early, do we have the danger the driver
> probing is going to happen before the init routine can enable the
> power?
>
> It seems like we want pinctrl/gpio working first, with pins hogged as
> specified in DT, then the board init() function, then the rest of DT
> setup.
If those GPIO value settings are needed to get a particular driver to
work, then I'd recommend letting the driver do the GPIO value setting.
For example, in the lsxl board, I see:
/* usb and sata power on */
gpio_set_value(LSXL_GPIO_USB_POWER, 1);
gpio_set_value(LSXL_GPIO_HDD_POWER, 1);
If the LSXL_GPIO_USB_POWER GPIO should be set to one to get the EHCI
driver to work properly, then I think we should let the EHCI driver set
this GPIO value in its ->probe() operation. Of course, the GPIO
reference will be passed in the platform_data (for old-style probing),
or through specific DT properties (for new-style, DT-based, probing).
Regarding the LSXL_GPIO_HDD_POWER GPIO, I am not sure. Is it required
to apply power on this GPIO to get the SATA driver to probe properly,
or is it possible to get the SATA driver to probe properly, then apply
power and have the HDD still being recognized? I haven't looked at all
at how SATA drivers were working, so I can't say.
Also, ultimately, if those GPIOs are providing power, then they should
probably not be handled as simple GPIOs, but rather as regulator, using
the gpio-regulator driver. But let's do things steps by steps :-)
Best regards,
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* [PATCH 0/4] Implement device tree support for ab8500 BM Devices
From: Rajanikanth H.V @ 2012-10-25 6:30 UTC (permalink / raw)
To: linux-arm-kernel
From: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>
This patch-set adds device tree binding for ab8500 battery-managed
devices. Removes the redundant platform structure maintained
across bm devices and implements common DT probe routine across all the
modules.
Test status:
a) Tested across 'legacy platform data' and DT binding support
a.1) ab8500_charger driver fails to get regulator in the
legacy platform mode.
b) Interrupt numbers assigned differs between legacy and FDT mode.
(a) Legacy platform_data Mode:
root at ME:/ cat /proc/interrupts
CPU0 CPU1
483: 0 0 ab8500 ab8500-ponkey-dbf
484: 0 0 ab8500 ab8500-ponkey-dbr
485: 0 0 ab8500 BATT_OVV
494: 0 1 ab8500
495: 0 0 ab8500 ab8500-rtc
501: 0 13 ab8500 NCONV_ACCU
503: 7 22 ab8500 CCEOC
504: 0 1 ab8500 CC_INT_CALIB
505: 0 0 ab8500 LOW_BAT_F
516: 0 34 ab8500 ab8500-gpadc
556: 0 0 ab8500 usb-link-status
(b) FDT Mode:
root at ME:/ cat /proc/interrupts
CPU0 CPU1
6: 0 0 ab8500 ab8500-ponkey-dbf
7: 0 0 ab8500 ab8500-ponkey-dbr
8: 0 0 ab8500 BATT_OVV
162: 0 7 ab8500 ab8500-gpadc
163: 0 1 ab8500
164: 0 0 ab8500 ab8500-rtc
484: 0 0 ab8500 usb-link-status
499: 0 4 ab8500 NCONV_ACCU
500: 0 0 ab8500 LOW_BAT_F
502: 0 1 ab8500 CC_INT_CALIB
503: 0 6 ab8500 CCEOC
c) Event handlers across bm-modules have been verified only
during 'battery discharge process' as 'battery charging process'
depends on ab8500-usb code
Rajanikanth H.V (4):
mfd: ab8500: add devicetree support for fuelgauge
mfd: ab8500: add devicetree support for btemp
mfd: ab8500: add devicetree support for charger
mfd: ab8500: add devicetree support for chargalg
Documentation/devicetree/bindings/mfd/ab8500.txt | 27 +-
.../bindings/power_supply/ab8500/btemp.txt | 16 +
.../bindings/power_supply/ab8500/chargalg.txt | 16 +
.../bindings/power_supply/ab8500/charger.txt | 25 +
.../devicetree/bindings/power_supply/ab8500/fg.txt | 58 +++
arch/arm/boot/dts/dbx5x0.dtsi | 28 +-
drivers/mfd/ab8500-core.c | 20 +
drivers/power/Kconfig | 6 -
drivers/power/Makefile | 2 +-
drivers/power/ab8500_bmdata.c | 513 ++++++++++++++++++++
drivers/power/ab8500_btemp.c | 76 +--
drivers/power/ab8500_charger.c | 82 ++--
drivers/power/ab8500_fg.c | 80 +--
drivers/power/abx500_chargalg.c | 56 ++-
include/linux/mfd/abx500.h | 34 +-
15 files changed, 876 insertions(+), 163 deletions(-)
create mode 100644 Documentation/devicetree/bindings/power_supply/ab8500/btemp.txt
create mode 100644 Documentation/devicetree/bindings/power_supply/ab8500/chargalg.txt
create mode 100644 Documentation/devicetree/bindings/power_supply/ab8500/charger.txt
create mode 100644 Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
create mode 100644 drivers/power/ab8500_bmdata.c
--
1.7.10.4
^ permalink raw reply
* [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge
From: Rajanikanth H.V @ 2012-10-25 6:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351146654-9110-1-git-send-email-rajanikanth.hv@stericsson.com>
From: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>
- This patch adds device tree support for fuelgauge driver
- optimize bm devices platform_data usage and of_probe(...)
Note: of_probe() routine for battery managed devices is made
common across all bm drivers.
- test status:
- interrupt numbers assigned differs between legacy and FDT mode.
Signed-off-by: Rajanikanth H.V <rajanikanth.hv@stericsson.com>
---
Documentation/devicetree/bindings/mfd/ab8500.txt | 7 +-
.../devicetree/bindings/power_supply/ab8500/fg.txt | 58 +++
arch/arm/boot/dts/dbx5x0.dtsi | 12 +-
drivers/mfd/ab8500-core.c | 5 +
drivers/power/Makefile | 2 +-
drivers/power/ab8500_bmdata.c | 513 ++++++++++++++++++++
drivers/power/ab8500_btemp.c | 16 +-
drivers/power/ab8500_charger.c | 16 +-
drivers/power/ab8500_fg.c | 80 +--
drivers/power/abx500_chargalg.c | 8 +-
include/linux/mfd/abx500.h | 36 +-
11 files changed, 659 insertions(+), 94 deletions(-)
create mode 100644 Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
create mode 100644 drivers/power/ab8500_bmdata.c
diff --git a/Documentation/devicetree/bindings/mfd/ab8500.txt b/Documentation/devicetree/bindings/mfd/ab8500.txt
index ce83c8d..6ca8d81 100644
--- a/Documentation/devicetree/bindings/mfd/ab8500.txt
+++ b/Documentation/devicetree/bindings/mfd/ab8500.txt
@@ -24,7 +24,12 @@ ab8500-bm : : : Battery Manager
ab8500-btemp : : : Battery Temperature
ab8500-charger : : : Battery Charger
ab8500-codec : : : Audio Codec
-ab8500-fg : : : Fuel Gauge
+ab8500-fg : : vddadc : Fuel Gauge
+ : NCONV_ACCU : : Accumulate N Sample Conversion
+ : BATT_OVV : : Battery Over Voltage
+ : LOW_BAT_F : : LOW threshold battery voltage
+ : CC_INT_CALIB : : Coulomb Counter Internal Calibration
+ : CCEOC : : Coulomb Counter End of Conversion
ab8500-gpadc : HW_CONV_END : vddadc : Analogue to Digital Converter
SW_CONV_END : :
ab8500-gpio : : : GPIO Controller
diff --git a/Documentation/devicetree/bindings/power_supply/ab8500/fg.txt b/Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
new file mode 100644
index 0000000..28eaf35
--- /dev/null
+++ b/Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
@@ -0,0 +1,58 @@
+=== AB8500 Fuel Gauge Driver ===
+
+AB8500 is a mixed signal multimedia and power management
+device comprising: power and energy-management-module,
+wall-charger, usb-charger, audio codec, general purpose adc,
+tvout, clock management and sim card interface.
+
+Fuelgauge support is part of energy-management-modules, other
+components of this module are:
+main-charger, usb-combo-charger and battery-temperature-monitoring.
+
+The properties below describes the node for fuelgauge driver.
+
+Required Properties:
+- compatible = This shall be: "stericsson,ab8500-fg"
+- battery = Shall be battery specific information
+ Example:
+ ab8500_fg {
+ compatible = "stericsson,ab8500-fg";
+ battery = <&ab8500_battery>;
+ };
+
+dependent node:
+ ab8500_battery: ab8500_battery {
+ };
+ This node will provide information on 'thermistor interface' and
+ 'battery technology type' used.
+
+Properties of this node are:
+thermistor-on-batctrl:
+ A boolean value indicating thermistor interface to battery
+
+ Note:
+ 'btemp' and 'batctrl' are the pins interfaced for battery temperature
+ measurement, 'btemp' signal is used when NTC(negative temperature
+ coefficient) resister is interfaced external to battery whereas
+ 'batctrl' pin is used when NTC resister is internal to battery.
+
+ Example:
+ ab8500_battery: ab8500_battery {
+ thermistor-on-batctrl;
+ };
+ indiactes: NTC resister is internal to battery, 'batctrl' is used
+ for thermal measurement.
+
+ The absence of property 'thermal-on-batctrl' indicates
+ NTC resister is external to battery and 'btemp' signal is used
+ for thermal measurement.
+
+battery-type:
+ This shall be the battery manufacturing technology type,
+ allowed types are:
+ "UNKNOWN" "NiMH" "LION" "LIPO" "LiFe" "NiCd" "LiMn"
+ Example:
+ ab8500_battery: ab8500_battery {
+ stericsson,battery-type = "LIPO";
+ }
+
diff --git a/arch/arm/boot/dts/dbx5x0.dtsi b/arch/arm/boot/dts/dbx5x0.dtsi
index 748ba7a..68317f5 100644
--- a/arch/arm/boot/dts/dbx5x0.dtsi
+++ b/arch/arm/boot/dts/dbx5x0.dtsi
@@ -352,7 +352,17 @@
vddadc-supply = <&ab8500_ldo_tvout_reg>;
};
- ab8500-usb {
+ ab8500_battery: ab8500_battery {
+ stericsson,battery-type = "LIPO";
+ thermistor-on-batctrl;
+ };
+
+ ab8500_fg {
+ compatible = "stericsson,ab8500-fg";
+ battery = <&ab8500_battery>;
+ };
+
+ ab8500_usb {
compatible = "stericsson,ab8500-usb";
interrupts = < 90 0x4
96 0x4
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index 1667c77..7c3017b 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -1051,8 +1051,13 @@ static struct mfd_cell __devinitdata ab8500_bm_devs[] = {
},
{
.name = "ab8500-fg",
+ .of_compatible = "stericsson,ab8500-fg",
.num_resources = ARRAY_SIZE(ab8500_fg_resources),
.resources = ab8500_fg_resources,
+#ifndef CONFIG_OF
+ .platform_data = &ab8500_bm_data,
+ .pdata_size = sizeof(ab8500_bm_data),
+#endif
},
{
.name = "ab8500-chargalg",
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index ee58afb..2c58d4e 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -34,7 +34,7 @@ obj-$(CONFIG_BATTERY_S3C_ADC) += s3c_adc_battery.o
obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o
obj-$(CONFIG_BATTERY_INTEL_MID) += intel_mid_battery.o
-obj-$(CONFIG_AB8500_BM) += ab8500_charger.o ab8500_btemp.o ab8500_fg.o abx500_chargalg.o
+obj-$(CONFIG_AB8500_BM) += ab8500_bmdata.o ab8500_charger.o ab8500_fg.o ab8500_btemp.o abx500_chargalg.o
obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o
obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o
obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o
diff --git a/drivers/power/ab8500_bmdata.c b/drivers/power/ab8500_bmdata.c
new file mode 100644
index 0000000..393ac2b
--- /dev/null
+++ b/drivers/power/ab8500_bmdata.c
@@ -0,0 +1,513 @@
+#include <linux/export.h>
+#include <linux/power_supply.h>
+#include <linux/of.h>
+#include <linux/mfd/abx500.h>
+#include <linux/mfd/abx500/ab8500.h>
+#include <linux/mfd/abx500/ab8500-bm.h>
+
+/*
+ * These are the defined batteries that uses a NTC and ID resistor placed
+ * inside of the battery pack.
+ * Note that the res_to_temp table must be strictly sorted by falling resistance
+ * values to work.
+ */
+static struct abx500_res_to_temp temp_tbl_A_thermistor[] = {
+ {-5, 53407},
+ { 0, 48594},
+ { 5, 43804},
+ {10, 39188},
+ {15, 34870},
+ {20, 30933},
+ {25, 27422},
+ {30, 24347},
+ {35, 21694},
+ {40, 19431},
+ {45, 17517},
+ {50, 15908},
+ {55, 14561},
+ {60, 13437},
+ {65, 12500},
+};
+static struct abx500_res_to_temp temp_tbl_B_thermistor[] = {
+ {-5, 165418},
+ { 0, 159024},
+ { 5, 151921},
+ {10, 144300},
+ {15, 136424},
+ {20, 128565},
+ {25, 120978},
+ {30, 113875},
+ {35, 107397},
+ {40, 101629},
+ {45, 96592},
+ {50, 92253},
+ {55, 88569},
+ {60, 85461},
+ {65, 82869},
+};
+static struct abx500_v_to_cap cap_tbl_A_thermistor[] = {
+ {4171, 100},
+ {4114, 95},
+ {4009, 83},
+ {3947, 74},
+ {3907, 67},
+ {3863, 59},
+ {3830, 56},
+ {3813, 53},
+ {3791, 46},
+ {3771, 33},
+ {3754, 25},
+ {3735, 20},
+ {3717, 17},
+ {3681, 13},
+ {3664, 8},
+ {3651, 6},
+ {3635, 5},
+ {3560, 3},
+ {3408, 1},
+ {3247, 0},
+};
+static struct abx500_v_to_cap cap_tbl_B_thermistor[] = {
+ {4161, 100},
+ {4124, 98},
+ {4044, 90},
+ {4003, 85},
+ {3966, 80},
+ {3933, 75},
+ {3888, 67},
+ {3849, 60},
+ {3813, 55},
+ {3787, 47},
+ {3772, 30},
+ {3751, 25},
+ {3718, 20},
+ {3681, 16},
+ {3660, 14},
+ {3589, 10},
+ {3546, 7},
+ {3495, 4},
+ {3404, 2},
+ {3250, 0},
+};
+
+static struct abx500_v_to_cap cap_tbl[] = {
+ {4186, 100},
+ {4163, 99},
+ {4114, 95},
+ {4068, 90},
+ {3990, 80},
+ {3926, 70},
+ {3898, 65},
+ {3866, 60},
+ {3833, 55},
+ {3812, 50},
+ {3787, 40},
+ {3768, 30},
+ {3747, 25},
+ {3730, 20},
+ {3705, 15},
+ {3699, 14},
+ {3684, 12},
+ {3672, 9},
+ {3657, 7},
+ {3638, 6},
+ {3556, 4},
+ {3424, 2},
+ {3317, 1},
+ {3094, 0},
+};
+
+/*
+ * Note that the res_to_temp table must be strictly sorted by falling
+ * resistance values to work.
+ */
+static struct abx500_res_to_temp temp_tbl[] = {
+ {-5, 214834},
+ { 0, 162943},
+ { 5, 124820},
+ {10, 96520},
+ {15, 75306},
+ {20, 59254},
+ {25, 47000},
+ {30, 37566},
+ {35, 30245},
+ {40, 24520},
+ {45, 20010},
+ {50, 16432},
+ {55, 13576},
+ {60, 11280},
+ {65, 9425},
+};
+
+/*
+ * Note that the batres_vs_temp table must be strictly sorted by falling
+ * temperature values to work.
+ */
+struct batres_vs_temp temp_to_batres_tbl_thermistor[] = {
+ { 40, 120},
+ { 30, 135},
+ { 20, 165},
+ { 10, 230},
+ { 00, 325},
+ {-10, 445},
+ {-20, 595},
+};
+
+/*
+ * Note that the batres_vs_temp table must be strictly sorted by falling
+ * temperature values to work.
+ */
+struct batres_vs_temp temp_to_batres_tbl_ext_thermistor[] = {
+ { 60, 300},
+ { 30, 300},
+ { 20, 300},
+ { 10, 300},
+ { 00, 300},
+ {-10, 300},
+ {-20, 300},
+};
+
+/* battery resistance table for LI ION 9100 battery */
+struct batres_vs_temp temp_to_batres_tbl_9100[] = {
+ { 60, 180},
+ { 30, 180},
+ { 20, 180},
+ { 10, 180},
+ { 00, 180},
+ {-10, 180},
+ {-20, 180},
+};
+
+struct abx500_battery_type bat_type_thermistor[] = {
+[BATTERY_UNKNOWN] = {
+ /* First element always represent the UNKNOWN battery */
+ .name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN,
+ .resis_high = 0,
+ .resis_low = 0,
+ .battery_resistance = 300,
+ .charge_full_design = 612,
+ .nominal_voltage = 3700,
+ .termination_vol = 4050,
+ .termination_curr = 200,
+ .recharge_vol = 3990,
+ .normal_cur_lvl = 400,
+ .normal_vol_lvl = 4100,
+ .maint_a_cur_lvl = 400,
+ .maint_a_vol_lvl = 4050,
+ .maint_a_chg_timer_h = 60,
+ .maint_b_cur_lvl = 400,
+ .maint_b_vol_lvl = 4000,
+ .maint_b_chg_timer_h = 200,
+ .low_high_cur_lvl = 300,
+ .low_high_vol_lvl = 4000,
+ .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
+ .r_to_t_tbl = temp_tbl,
+ .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
+ .v_to_cap_tbl = cap_tbl,
+ .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+ .batres_tbl = temp_to_batres_tbl_thermistor,
+},
+{
+ .name = POWER_SUPPLY_TECHNOLOGY_LIPO,
+ .resis_high = 53407,
+ .resis_low = 12500,
+ .battery_resistance = 300,
+ .charge_full_design = 900,
+ .nominal_voltage = 3600,
+ .termination_vol = 4150,
+ .termination_curr = 80,
+ .recharge_vol = 4130,
+ .normal_cur_lvl = 700,
+ .normal_vol_lvl = 4200,
+ .maint_a_cur_lvl = 600,
+ .maint_a_vol_lvl = 4150,
+ .maint_a_chg_timer_h = 60,
+ .maint_b_cur_lvl = 600,
+ .maint_b_vol_lvl = 4100,
+ .maint_b_chg_timer_h = 200,
+ .low_high_cur_lvl = 300,
+ .low_high_vol_lvl = 4000,
+ .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl_A_thermistor),
+ .r_to_t_tbl = temp_tbl_A_thermistor,
+ .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl_A_thermistor),
+ .v_to_cap_tbl = cap_tbl_A_thermistor,
+ .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+ .batres_tbl = temp_to_batres_tbl_thermistor,
+
+},
+{
+ .name = POWER_SUPPLY_TECHNOLOGY_LIPO,
+ .resis_high = 165418,
+ .resis_low = 82869,
+ .battery_resistance = 300,
+ .charge_full_design = 900,
+ .nominal_voltage = 3600,
+ .termination_vol = 4150,
+ .termination_curr = 80,
+ .recharge_vol = 4130,
+ .normal_cur_lvl = 700,
+ .normal_vol_lvl = 4200,
+ .maint_a_cur_lvl = 600,
+ .maint_a_vol_lvl = 4150,
+ .maint_a_chg_timer_h = 60,
+ .maint_b_cur_lvl = 600,
+ .maint_b_vol_lvl = 4100,
+ .maint_b_chg_timer_h = 200,
+ .low_high_cur_lvl = 300,
+ .low_high_vol_lvl = 4000,
+ .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl_B_thermistor),
+ .r_to_t_tbl = temp_tbl_B_thermistor,
+ .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl_B_thermistor),
+ .v_to_cap_tbl = cap_tbl_B_thermistor,
+ .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+ .batres_tbl = temp_to_batres_tbl_thermistor,
+},
+};
+
+struct abx500_battery_type bat_type_ext_thermistor[] = {
+[BATTERY_UNKNOWN] = {
+ /* First element always represent the UNKNOWN battery */
+ .name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN,
+ .resis_high = 0,
+ .resis_low = 0,
+ .battery_resistance = 300,
+ .charge_full_design = 612,
+ .nominal_voltage = 3700,
+ .termination_vol = 4050,
+ .termination_curr = 200,
+ .recharge_vol = 3990,
+ .normal_cur_lvl = 400,
+ .normal_vol_lvl = 4100,
+ .maint_a_cur_lvl = 400,
+ .maint_a_vol_lvl = 4050,
+ .maint_a_chg_timer_h = 60,
+ .maint_b_cur_lvl = 400,
+ .maint_b_vol_lvl = 4000,
+ .maint_b_chg_timer_h = 200,
+ .low_high_cur_lvl = 300,
+ .low_high_vol_lvl = 4000,
+ .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
+ .r_to_t_tbl = temp_tbl,
+ .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
+ .v_to_cap_tbl = cap_tbl,
+ .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+ .batres_tbl = temp_to_batres_tbl_thermistor,
+},
+/*
+ * These are the batteries that doesn't have an internal NTC resistor to measure
+ * its temperature. The temperature in this case is measure with a NTC placed
+ * near the battery but on the PCB.
+ */
+{
+ .name = POWER_SUPPLY_TECHNOLOGY_LIPO,
+ .resis_high = 76000,
+ .resis_low = 53000,
+ .battery_resistance = 300,
+ .charge_full_design = 900,
+ .nominal_voltage = 3700,
+ .termination_vol = 4150,
+ .termination_curr = 100,
+ .recharge_vol = 4130,
+ .normal_cur_lvl = 700,
+ .normal_vol_lvl = 4200,
+ .maint_a_cur_lvl = 600,
+ .maint_a_vol_lvl = 4150,
+ .maint_a_chg_timer_h = 60,
+ .maint_b_cur_lvl = 600,
+ .maint_b_vol_lvl = 4100,
+ .maint_b_chg_timer_h = 200,
+ .low_high_cur_lvl = 300,
+ .low_high_vol_lvl = 4000,
+ .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
+ .r_to_t_tbl = temp_tbl,
+ .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
+ .v_to_cap_tbl = cap_tbl,
+ .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+ .batres_tbl = temp_to_batres_tbl_thermistor,
+},
+{
+ .name = POWER_SUPPLY_TECHNOLOGY_LION,
+ .resis_high = 30000,
+ .resis_low = 10000,
+ .battery_resistance = 300,
+ .charge_full_design = 950,
+ .nominal_voltage = 3700,
+ .termination_vol = 4150,
+ .termination_curr = 100,
+ .recharge_vol = 4130,
+ .normal_cur_lvl = 700,
+ .normal_vol_lvl = 4200,
+ .maint_a_cur_lvl = 600,
+ .maint_a_vol_lvl = 4150,
+ .maint_a_chg_timer_h = 60,
+ .maint_b_cur_lvl = 600,
+ .maint_b_vol_lvl = 4100,
+ .maint_b_chg_timer_h = 200,
+ .low_high_cur_lvl = 300,
+ .low_high_vol_lvl = 4000,
+ .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
+ .r_to_t_tbl = temp_tbl,
+ .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
+ .v_to_cap_tbl = cap_tbl,
+ .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+ .batres_tbl = temp_to_batres_tbl_thermistor,
+},
+{
+ .name = POWER_SUPPLY_TECHNOLOGY_LION,
+ .resis_high = 95000,
+ .resis_low = 76001,
+ .battery_resistance = 300,
+ .charge_full_design = 950,
+ .nominal_voltage = 3700,
+ .termination_vol = 4150,
+ .termination_curr = 100,
+ .recharge_vol = 4130,
+ .normal_cur_lvl = 700,
+ .normal_vol_lvl = 4200,
+ .maint_a_cur_lvl = 600,
+ .maint_a_vol_lvl = 4150,
+ .maint_a_chg_timer_h = 60,
+ .maint_b_cur_lvl = 600,
+ .maint_b_vol_lvl = 4100,
+ .maint_b_chg_timer_h = 200,
+ .low_high_cur_lvl = 300,
+ .low_high_vol_lvl = 4000,
+ .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
+ .r_to_t_tbl = temp_tbl,
+ .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
+ .v_to_cap_tbl = cap_tbl,
+ .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+ .batres_tbl = temp_to_batres_tbl_thermistor,
+},
+};
+
+static const struct abx500_bm_capacity_levels cap_levels = {
+ .critical = 2,
+ .low = 10,
+ .normal = 70,
+ .high = 95,
+ .full = 100,
+};
+
+static const struct abx500_fg_parameters fg = {
+ .recovery_sleep_timer = 10,
+ .recovery_total_time = 100,
+ .init_timer = 1,
+ .init_discard_time = 5,
+ .init_total_time = 40,
+ .high_curr_time = 60,
+ .accu_charging = 30,
+ .accu_high_curr = 30,
+ .high_curr_threshold = 50,
+ .lowbat_threshold = 3100,
+ .battok_falling_th_sel0 = 2860,
+ .battok_raising_th_sel1 = 2860,
+ .user_cap_limit = 15,
+ .maint_thres = 97,
+};
+
+static const struct abx500_maxim_parameters maxi_params = {
+ .ena_maxi = true,
+ .chg_curr = 910,
+ .wait_cycles = 10,
+ .charger_curr_step = 100,
+};
+
+static const struct abx500_bm_charger_parameters chg = {
+ .usb_volt_max = 5500,
+ .usb_curr_max = 1500,
+ .ac_volt_max = 7500,
+ .ac_curr_max = 1500,
+};
+
+struct abx500_bm_data ab8500_bm_data = {
+ .temp_under = 3,
+ .temp_low = 8,
+ .temp_high = 43,
+ .temp_over = 48,
+ .main_safety_tmr_h = 4,
+ .temp_interval_chg = 20,
+ .temp_interval_nochg = 120,
+ .usb_safety_tmr_h = 4,
+ .bkup_bat_v = BUP_VCH_SEL_2P6V,
+ .bkup_bat_i = BUP_ICH_SEL_150UA,
+ .no_maintenance = false,
+ .adc_therm = ABx500_ADC_THERM_BATCTRL,
+ .chg_unknown_bat = false,
+ .enable_overshoot = false,
+ .fg_res = 100,
+ .cap_levels = &cap_levels,
+ .bat_type = bat_type_thermistor,
+ .n_btypes = 3,
+ .batt_id = 0,
+ .interval_charging = 5,
+ .interval_not_charging = 120,
+ .temp_hysteresis = 3,
+ .gnd_lift_resistance = 34,
+ .maxi = &maxi_params,
+ .chg_params = &chg,
+ .fg_params = &fg,
+};
+
+int __devinit
+bmdevs_of_probe(struct device *dev,
+ struct device_node *np,
+ struct abx500_bm_data **battery)
+{
+ struct abx500_battery_type *btype;
+ struct device_node *np_bat_supply;
+ struct abx500_bm_data *bat;
+ const char *bat_tech;
+ int i, thermistor;
+
+ *battery = &ab8500_bm_data;
+
+ /* get phandle to 'battery-info' node */
+ np_bat_supply = of_parse_phandle(np, "battery", 0);
+ if (!np_bat_supply) {
+ dev_err(dev, "missing property battery\n");
+ return -EINVAL;
+ }
+ if (of_property_read_bool(np_bat_supply,
+ "thermistor-on-batctrl"))
+ thermistor = NTC_INTERNAL;
+ else
+ thermistor = NTC_EXTERNAL;
+
+ bat = *battery;
+ if (thermistor == NTC_EXTERNAL) {
+ bat->n_btypes = 4;
+ bat->bat_type = bat_type_ext_thermistor;
+ bat->adc_therm = ABx500_ADC_THERM_BATTEMP;
+ }
+ bat_tech = of_get_property(np_bat_supply,
+ "stericsson,battery-type", NULL);
+ if (!bat_tech)
+ dev_warn(dev, "missing property battery-name/type\n");
+
+ if (strncmp(bat_tech, "LION", 4) == 0) {
+ bat->no_maintenance = true;
+ bat->chg_unknown_bat = true;
+ bat->bat_type[BATTERY_UNKNOWN].charge_full_design = 2600;
+ bat->bat_type[BATTERY_UNKNOWN].termination_vol = 4150;
+ bat->bat_type[BATTERY_UNKNOWN].recharge_vol = 4130;
+ bat->bat_type[BATTERY_UNKNOWN].normal_cur_lvl = 520;
+ bat->bat_type[BATTERY_UNKNOWN].normal_vol_lvl = 4200;
+ }
+ /* select the battery resolution table */
+ for (i = 0; i < bat->n_btypes; ++i) {
+ btype = (bat->bat_type + i);
+ if (thermistor == NTC_EXTERNAL) {
+ btype->batres_tbl =
+ temp_to_batres_tbl_ext_thermistor;
+ } else if (strncmp(bat_tech, "LION", 4) == 0) {
+ btype->batres_tbl =
+ temp_to_batres_tbl_9100;
+ } else {
+ btype->batres_tbl =
+ temp_to_batres_tbl_thermistor;
+ }
+ }
+ of_node_put(np_bat_supply);
+ return 0;
+}
diff --git a/drivers/power/ab8500_btemp.c b/drivers/power/ab8500_btemp.c
index bba3cca..803870e 100644
--- a/drivers/power/ab8500_btemp.c
+++ b/drivers/power/ab8500_btemp.c
@@ -93,7 +93,7 @@ struct ab8500_btemp {
struct ab8500 *parent;
struct ab8500_gpadc *gpadc;
struct ab8500_fg *fg;
- struct abx500_btemp_platform_data *pdata;
+ struct abx500_bmdevs_plat_data *pdata;
struct abx500_bm_data *bat;
struct power_supply btemp_psy;
struct ab8500_btemp_events events;
@@ -962,10 +962,10 @@ static int __devexit ab8500_btemp_remove(struct platform_device *pdev)
static int __devinit ab8500_btemp_probe(struct platform_device *pdev)
{
+ struct abx500_bmdevs_plat_data *plat_data = pdev->dev.platform_data;
+ struct ab8500_btemp *di;
int irq, i, ret = 0;
u8 val;
- struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data;
- struct ab8500_btemp *di;
if (!plat_data) {
dev_err(&pdev->dev, "No platform data\n");
@@ -982,21 +982,13 @@ static int __devinit ab8500_btemp_probe(struct platform_device *pdev)
di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
/* get btemp specific platform data */
- di->pdata = plat_data->btemp;
+ di->pdata = plat_data;
if (!di->pdata) {
dev_err(di->dev, "no btemp platform data supplied\n");
ret = -EINVAL;
goto free_device_info;
}
- /* get battery specific platform data */
- di->bat = plat_data->battery;
- if (!di->bat) {
- dev_err(di->dev, "no battery platform data supplied\n");
- ret = -EINVAL;
- goto free_device_info;
- }
-
/* BTEMP supply */
di->btemp_psy.name = "ab8500_btemp";
di->btemp_psy.type = POWER_SUPPLY_TYPE_BATTERY;
diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c
index d4f0c98..78a730c 100644
--- a/drivers/power/ab8500_charger.c
+++ b/drivers/power/ab8500_charger.c
@@ -220,7 +220,7 @@ struct ab8500_charger {
bool autopower;
struct ab8500 *parent;
struct ab8500_gpadc *gpadc;
- struct abx500_charger_platform_data *pdata;
+ struct abx500_bmdevs_plat_data *pdata;
struct abx500_bm_data *bat;
struct ab8500_charger_event_flags flags;
struct ab8500_charger_usb_state usb_state;
@@ -2533,9 +2533,9 @@ static int __devexit ab8500_charger_remove(struct platform_device *pdev)
static int __devinit ab8500_charger_probe(struct platform_device *pdev)
{
- int irq, i, charger_status, ret = 0;
- struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data;
+ struct abx500_bmdevs_plat_data *plat_data = pdev->dev.platform_data;
struct ab8500_charger *di;
+ int irq, i, charger_status, ret = 0;
if (!plat_data) {
dev_err(&pdev->dev, "No platform data\n");
@@ -2555,21 +2555,13 @@ static int __devinit ab8500_charger_probe(struct platform_device *pdev)
spin_lock_init(&di->usb_state.usb_lock);
/* get charger specific platform data */
- di->pdata = plat_data->charger;
+ di->pdata = plat_data;
if (!di->pdata) {
dev_err(di->dev, "no charger platform data supplied\n");
ret = -EINVAL;
goto free_device_info;
}
- /* get battery specific platform data */
- di->bat = plat_data->battery;
- if (!di->bat) {
- dev_err(di->dev, "no battery platform data supplied\n");
- ret = -EINVAL;
- goto free_device_info;
- }
-
di->autopower = false;
/* AC supply */
diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c
index bf02225..e117920 100644
--- a/drivers/power/ab8500_fg.c
+++ b/drivers/power/ab8500_fg.c
@@ -22,15 +22,16 @@
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/kobject.h>
-#include <linux/mfd/abx500/ab8500.h>
-#include <linux/mfd/abx500.h>
#include <linux/slab.h>
-#include <linux/mfd/abx500/ab8500-bm.h>
#include <linux/delay.h>
-#include <linux/mfd/abx500/ab8500-gpadc.h>
-#include <linux/mfd/abx500.h>
#include <linux/time.h>
+#include <linux/of.h>
#include <linux/completion.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/abx500.h>
+#include <linux/mfd/abx500/ab8500.h>
+#include <linux/mfd/abx500/ab8500-bm.h>
+#include <linux/mfd/abx500/ab8500-gpadc.h>
#define MILLI_TO_MICRO 1000
#define FG_LSB_IN_MA 1627
@@ -212,7 +213,6 @@ struct ab8500_fg {
struct ab8500_fg_avg_cap avg_cap;
struct ab8500 *parent;
struct ab8500_gpadc *gpadc;
- struct abx500_fg_platform_data *pdata;
struct abx500_bm_data *bat;
struct power_supply fg_psy;
struct workqueue_struct *fg_wq;
@@ -2429,7 +2429,6 @@ static int __devexit ab8500_fg_remove(struct platform_device *pdev)
flush_scheduled_work();
power_supply_unregister(&di->fg_psy);
platform_set_drvdata(pdev, NULL);
- kfree(di);
return ret;
}
@@ -2442,21 +2441,39 @@ static struct ab8500_fg_interrupts ab8500_fg_irq[] = {
{"CCEOC", ab8500_fg_cc_data_end_handler},
};
+static char *supply_interface[] = {
+ "ab8500_chargalg",
+ "ab8500_usb",
+};
+
static int __devinit ab8500_fg_probe(struct platform_device *pdev)
{
+ struct device_node *np = pdev->dev.of_node;
+ struct ab8500_fg *di;
int i, irq;
int ret = 0;
- struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data;
- struct ab8500_fg *di;
-
- if (!plat_data) {
- dev_err(&pdev->dev, "No platform data\n");
- return -EINVAL;
- }
- di = kzalloc(sizeof(*di), GFP_KERNEL);
- if (!di)
+ di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
+ if (!di) {
+ dev_err(&pdev->dev, "%s no mem for ab8500_fg\n", __func__);
return -ENOMEM;
+ }
+ di->bat = pdev->mfd_cell->platform_data;
+ if (!di->bat) {
+ if (np) {
+ ret = bmdevs_of_probe(&pdev->dev, np, &di->bat);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed to get battery information\n");
+ return ret;
+ }
+ } else {
+ dev_err(&pdev->dev, "missing dt node for ab8500_fg\n");
+ return -EINVAL;
+ }
+ } else {
+ dev_info(&pdev->dev, "falling back to legacy platform data\n");
+ }
mutex_init(&di->cc_lock);
@@ -2465,29 +2482,13 @@ static int __devinit ab8500_fg_probe(struct platform_device *pdev)
di->parent = dev_get_drvdata(pdev->dev.parent);
di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
- /* get fg specific platform data */
- di->pdata = plat_data->fg;
- if (!di->pdata) {
- dev_err(di->dev, "no fg platform data supplied\n");
- ret = -EINVAL;
- goto free_device_info;
- }
-
- /* get battery specific platform data */
- di->bat = plat_data->battery;
- if (!di->bat) {
- dev_err(di->dev, "no battery platform data supplied\n");
- ret = -EINVAL;
- goto free_device_info;
- }
-
di->fg_psy.name = "ab8500_fg";
di->fg_psy.type = POWER_SUPPLY_TYPE_BATTERY;
di->fg_psy.properties = ab8500_fg_props;
di->fg_psy.num_properties = ARRAY_SIZE(ab8500_fg_props);
di->fg_psy.get_property = ab8500_fg_get_property;
- di->fg_psy.supplied_to = di->pdata->supplied_to;
- di->fg_psy.num_supplicants = di->pdata->num_supplicants;
+ di->fg_psy.supplied_to = supply_interface;
+ di->fg_psy.num_supplicants = ARRAY_SIZE(supply_interface),
di->fg_psy.external_power_changed = ab8500_fg_external_power_changed;
di->bat_cap.max_mah_design = MILLI_TO_MICRO *
@@ -2506,7 +2507,7 @@ static int __devinit ab8500_fg_probe(struct platform_device *pdev)
di->fg_wq = create_singlethread_workqueue("ab8500_fg_wq");
if (di->fg_wq == NULL) {
dev_err(di->dev, "failed to create work queue\n");
- goto free_device_info;
+ return -ENOMEM;
}
/* Init work for running the fg algorithm instantly */
@@ -2605,12 +2606,14 @@ free_irq:
}
free_inst_curr_wq:
destroy_workqueue(di->fg_wq);
-free_device_info:
- kfree(di);
-
return ret;
}
+static const struct of_device_id ab8500_fg_match[] = {
+ { .compatible = "stericsson,ab8500-fg", },
+ { },
+};
+
static struct platform_driver ab8500_fg_driver = {
.probe = ab8500_fg_probe,
.remove = __devexit_p(ab8500_fg_remove),
@@ -2619,6 +2622,7 @@ static struct platform_driver ab8500_fg_driver = {
.driver = {
.name = "ab8500-fg",
.owner = THIS_MODULE,
+ .of_match_table = ab8500_fg_match,
},
};
diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c
index 804b88c..88b5cc1 100644
--- a/drivers/power/abx500_chargalg.c
+++ b/drivers/power/abx500_chargalg.c
@@ -231,7 +231,7 @@ struct abx500_chargalg {
struct abx500_chargalg_charger_info chg_info;
struct abx500_chargalg_battery_data batt_data;
struct abx500_chargalg_suspension_status susp_status;
- struct abx500_chargalg_platform_data *pdata;
+ struct abx500_bmdevs_plat_data *pdata;
struct abx500_bm_data *bat;
struct power_supply chargalg_psy;
struct ux500_charger *ac_chg;
@@ -1802,7 +1802,7 @@ static int __devexit abx500_chargalg_remove(struct platform_device *pdev)
static int __devinit abx500_chargalg_probe(struct platform_device *pdev)
{
- struct abx500_bm_plat_data *plat_data;
+ struct abx500_bmdevs_plat_data *plat_data;
int ret = 0;
struct abx500_chargalg *di =
@@ -1812,10 +1812,8 @@ static int __devinit abx500_chargalg_probe(struct platform_device *pdev)
/* get device struct */
di->dev = &pdev->dev;
-
plat_data = pdev->dev.platform_data;
- di->pdata = plat_data->chargalg;
- di->bat = plat_data->battery;
+ di->pdata = plat_data;
/* chargalg supply */
di->chargalg_psy.name = "abx500_chargalg";
diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h
index 1318ca6..bbf3ad6 100644
--- a/include/linux/mfd/abx500.h
+++ b/include/linux/mfd/abx500.h
@@ -382,39 +382,27 @@ struct abx500_bm_data {
int gnd_lift_resistance;
const struct abx500_maxim_parameters *maxi;
const struct abx500_bm_capacity_levels *cap_levels;
- const struct abx500_battery_type *bat_type;
+ struct abx500_battery_type *bat_type;
const struct abx500_bm_charger_parameters *chg_params;
const struct abx500_fg_parameters *fg_params;
};
-struct abx500_chargalg_platform_data {
- char **supplied_to;
- size_t num_supplicants;
-};
-
-struct abx500_charger_platform_data {
- char **supplied_to;
- size_t num_supplicants;
- bool autopower_cfg;
-};
+extern struct abx500_bm_data ab8500_bm_data;
-struct abx500_btemp_platform_data {
- char **supplied_to;
- size_t num_supplicants;
+struct abx500_bmdevs_plat_data {
+ char **supplied_to;
+ size_t num_supplicants;
+ bool autopower_cfg;
};
-struct abx500_fg_platform_data {
- char **supplied_to;
- size_t num_supplicants;
+enum {
+ NTC_EXTERNAL = 0,
+ NTC_INTERNAL,
};
-struct abx500_bm_plat_data {
- struct abx500_bm_data *battery;
- struct abx500_charger_platform_data *charger;
- struct abx500_btemp_platform_data *btemp;
- struct abx500_fg_platform_data *fg;
- struct abx500_chargalg_platform_data *chargalg;
-};
+int bmdevs_of_probe(struct device *dev,
+ struct device_node *np,
+ struct abx500_bm_data **battery);
int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg,
u8 value);
--
1.7.10.4
^ permalink raw reply related
* [PATCH 2/4] mfd: ab8500: add devicetree support for btemp
From: Rajanikanth H.V @ 2012-10-25 6:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351146654-9110-1-git-send-email-rajanikanth.hv@stericsson.com>
From: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>
This patch adds device tree support for
battery-temperature-monitor driver
Signed-off-by: Rajanikanth H.V <rajanikanth.hv@stericsson.com>
---
Documentation/devicetree/bindings/mfd/ab8500.txt | 6 ++
.../bindings/power_supply/ab8500/btemp.txt | 16 +++++
arch/arm/boot/dts/dbx5x0.dtsi | 5 ++
drivers/mfd/ab8500-core.c | 5 ++
drivers/power/Kconfig | 6 --
drivers/power/ab8500_bmdata.c | 4 +-
drivers/power/ab8500_btemp.c | 66 ++++++++++++--------
7 files changed, 73 insertions(+), 35 deletions(-)
create mode 100644 Documentation/devicetree/bindings/power_supply/ab8500/btemp.txt
diff --git a/Documentation/devicetree/bindings/mfd/ab8500.txt b/Documentation/devicetree/bindings/mfd/ab8500.txt
index 6ca8d81..179c802 100644
--- a/Documentation/devicetree/bindings/mfd/ab8500.txt
+++ b/Documentation/devicetree/bindings/mfd/ab8500.txt
@@ -30,6 +30,12 @@ ab8500-fg : : vddadc : Fuel Gauge
: LOW_BAT_F : : LOW threshold battery voltage
: CC_INT_CALIB : : Coulomb Counter Internal Calibration
: CCEOC : : Coulomb Counter End of Conversion
+ab8500-btemp : : vtvout : Battery Temperature
+ : BAT_CTRL_INDB : : Battery Removal Indicator
+ : BTEMP_LOW : : Btemp < BtempLow, if battery temperature is lower than -10?C
+ : BTEMP_HIGH : : BtempLow < Btemp < BtempMedium,if battery temperature is between -10 and 0?C
+ : BTEMP_LOW_MEDIUM : : BtempMedium < Btemp < BtempHigh,if battery temperature is between 0?C and?MaxTemp
+ : BTEMP_MEDIUM_HIGH : : Btemp > BtempHigh, if battery temperature is higher than ?MaxTemp?
ab8500-gpadc : HW_CONV_END : vddadc : Analogue to Digital Converter
SW_CONV_END : :
ab8500-gpio : : : GPIO Controller
diff --git a/Documentation/devicetree/bindings/power_supply/ab8500/btemp.txt b/Documentation/devicetree/bindings/power_supply/ab8500/btemp.txt
new file mode 100644
index 0000000..0ba1bcc
--- /dev/null
+++ b/Documentation/devicetree/bindings/power_supply/ab8500/btemp.txt
@@ -0,0 +1,16 @@
+=== AB8500 Battery Temperature Monitor Driver ===
+
+The properties below describes the node for btemp driver.
+
+Required Properties:
+- compatible = Shall be: "stericsson,ab8500-btemp"
+- battery = Shall be battery specific information
+
+ Example:
+ ab8500_btemp {
+ compatible = "stericsson,ab8500-btemp";
+ battery = <&ab8500_battery>;
+ };
+
+For information on battery specific node, Ref:
+Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
diff --git a/arch/arm/boot/dts/dbx5x0.dtsi b/arch/arm/boot/dts/dbx5x0.dtsi
index 68317f5..79fdee4 100644
--- a/arch/arm/boot/dts/dbx5x0.dtsi
+++ b/arch/arm/boot/dts/dbx5x0.dtsi
@@ -362,6 +362,11 @@
battery = <&ab8500_battery>;
};
+ ab8500_btemp {
+ compatible = "stericsson,ab8500-btemp";
+ battery = <&ab8500_battery>;
+ };
+
ab8500_usb {
compatible = "stericsson,ab8500-usb";
interrupts = < 90 0x4
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index 7c3017b..94d45be 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -1046,8 +1046,13 @@ static struct mfd_cell __devinitdata ab8500_bm_devs[] = {
},
{
.name = "ab8500-btemp",
+ .of_compatible = "stericsson,ab8500-btemp",
.num_resources = ARRAY_SIZE(ab8500_btemp_resources),
.resources = ab8500_btemp_resources,
+#ifndef CONFIG_OF
+ .platform_data = &ab8500_bm_data,
+ .pdata_size = sizeof(ab8500_bm_data),
+#endif
},
{
.name = "ab8500-fg",
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index c1892f3..1434871 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -304,12 +304,6 @@ config AB8500_BM
help
Say Y to include support for AB8500 battery management.
-config AB8500_BATTERY_THERM_ON_BATCTRL
- bool "Thermistor connected on BATCTRL ADC"
- depends on AB8500_BM
- help
- Say Y to enable battery temperature measurements using
- thermistor connected on BATCTRL ADC.
endif # POWER_SUPPLY
source "drivers/power/avs/Kconfig"
diff --git a/drivers/power/ab8500_bmdata.c b/drivers/power/ab8500_bmdata.c
index 393ac2b..0475db0 100644
--- a/drivers/power/ab8500_bmdata.c
+++ b/drivers/power/ab8500_bmdata.c
@@ -29,7 +29,7 @@ static struct abx500_res_to_temp temp_tbl_A_thermistor[] = {
{65, 12500},
};
static struct abx500_res_to_temp temp_tbl_B_thermistor[] = {
- {-5, 165418},
+ {-5, 200000},
{ 0, 159024},
{ 5, 151921},
{10, 144300},
@@ -237,7 +237,7 @@ struct abx500_battery_type bat_type_thermistor[] = {
},
{
.name = POWER_SUPPLY_TECHNOLOGY_LIPO,
- .resis_high = 165418,
+ .resis_high = 200000,
.resis_low = 82869,
.battery_resistance = 300,
.charge_full_design = 900,
diff --git a/drivers/power/ab8500_btemp.c b/drivers/power/ab8500_btemp.c
index 803870e..a6633b4 100644
--- a/drivers/power/ab8500_btemp.c
+++ b/drivers/power/ab8500_btemp.c
@@ -20,11 +20,13 @@
#include <linux/power_supply.h>
#include <linux/completion.h>
#include <linux/workqueue.h>
-#include <linux/mfd/abx500/ab8500.h>
+#include <linux/jiffies.h>
+#include <linux/of.h>
+#include <linux/mfd/core.h>
#include <linux/mfd/abx500.h>
+#include <linux/mfd/abx500/ab8500.h>
#include <linux/mfd/abx500/ab8500-bm.h>
#include <linux/mfd/abx500/ab8500-gpadc.h>
-#include <linux/jiffies.h>
#define VTVOUT_V 1800
@@ -76,7 +78,6 @@ struct ab8500_btemp_ranges {
* @parent: Pointer to the struct ab8500
* @gpadc: Pointer to the struct gpadc
* @fg: Pointer to the struct fg
- * @pdata: Pointer to the abx500_btemp platform data
* @bat: Pointer to the abx500_bm platform data
* @btemp_psy: Structure for BTEMP specific battery properties
* @events: Structure for information about events triggered
@@ -93,7 +94,6 @@ struct ab8500_btemp {
struct ab8500 *parent;
struct ab8500_gpadc *gpadc;
struct ab8500_fg *fg;
- struct abx500_bmdevs_plat_data *pdata;
struct abx500_bm_data *bat;
struct power_supply btemp_psy;
struct ab8500_btemp_events events;
@@ -955,48 +955,57 @@ static int __devexit ab8500_btemp_remove(struct platform_device *pdev)
flush_scheduled_work();
power_supply_unregister(&di->btemp_psy);
platform_set_drvdata(pdev, NULL);
- kfree(di);
return 0;
}
+static char *supply_interface[] = {
+ "ab8500_chargalg",
+ "ab8500_fg",
+};
+
static int __devinit ab8500_btemp_probe(struct platform_device *pdev)
{
- struct abx500_bmdevs_plat_data *plat_data = pdev->dev.platform_data;
+ struct device_node *np = pdev->dev.of_node;
struct ab8500_btemp *di;
int irq, i, ret = 0;
u8 val;
- if (!plat_data) {
- dev_err(&pdev->dev, "No platform data\n");
- return -EINVAL;
- }
-
- di = kzalloc(sizeof(*di), GFP_KERNEL);
- if (!di)
+ di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
+ if (!di) {
+ dev_err(&pdev->dev, "%s no mem for ab8500_btemp\n", __func__);
return -ENOMEM;
+ }
+ di->bat = pdev->mfd_cell->platform_data;
+ if (!di->bat) {
+ if (np) {
+ ret = bmdevs_of_probe(&pdev->dev, np, &di->bat);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed to get battery information\n");
+ return ret;
+ }
+ } else {
+ dev_err(&pdev->dev, "missing dt node for ab8500_btemp\n");
+ return -EINVAL;
+ }
+ } else {
+ dev_info(&pdev->dev, "falling back to legacy platform data\n");
+ }
/* get parent data */
di->dev = &pdev->dev;
di->parent = dev_get_drvdata(pdev->dev.parent);
di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
- /* get btemp specific platform data */
- di->pdata = plat_data;
- if (!di->pdata) {
- dev_err(di->dev, "no btemp platform data supplied\n");
- ret = -EINVAL;
- goto free_device_info;
- }
-
/* BTEMP supply */
di->btemp_psy.name = "ab8500_btemp";
di->btemp_psy.type = POWER_SUPPLY_TYPE_BATTERY;
di->btemp_psy.properties = ab8500_btemp_props;
di->btemp_psy.num_properties = ARRAY_SIZE(ab8500_btemp_props);
di->btemp_psy.get_property = ab8500_btemp_get_property;
- di->btemp_psy.supplied_to = di->pdata->supplied_to;
- di->btemp_psy.num_supplicants = di->pdata->num_supplicants;
+ di->btemp_psy.supplied_to = supply_interface;
+ di->btemp_psy.num_supplicants = ARRAY_SIZE(supply_interface);
di->btemp_psy.external_power_changed =
ab8500_btemp_external_power_changed;
@@ -1006,7 +1015,7 @@ static int __devinit ab8500_btemp_probe(struct platform_device *pdev)
create_singlethread_workqueue("ab8500_btemp_wq");
if (di->btemp_wq == NULL) {
dev_err(di->dev, "failed to create work queue\n");
- goto free_device_info;
+ return -ENOMEM;
}
/* Init work for measuring temperature periodically */
@@ -1084,12 +1093,14 @@ free_irq:
}
free_btemp_wq:
destroy_workqueue(di->btemp_wq);
-free_device_info:
- kfree(di);
-
return ret;
}
+static const struct of_device_id ab8500_btemp_match[] = {
+ { .compatible = "stericsson,ab8500-btemp", },
+ { },
+};
+
static struct platform_driver ab8500_btemp_driver = {
.probe = ab8500_btemp_probe,
.remove = __devexit_p(ab8500_btemp_remove),
@@ -1098,6 +1109,7 @@ static struct platform_driver ab8500_btemp_driver = {
.driver = {
.name = "ab8500-btemp",
.owner = THIS_MODULE,
+ .of_match_table = ab8500_btemp_match,
},
};
--
1.7.10.4
^ permalink raw reply related
* [PATCH 3/4] mfd: ab8500: add devicetree support for charger
From: Rajanikanth H.V @ 2012-10-25 6:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351146654-9110-1-git-send-email-rajanikanth.hv@stericsson.com>
From: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>
This patch adds device tree support for ab8500-charger
driver
Signed-off-by: Rajanikanth H.V <rajanikanth.hv@stericsson.com>
---
Documentation/devicetree/bindings/mfd/ab8500.txt | 14 ++++
.../bindings/power_supply/ab8500/charger.txt | 25 +++++++
arch/arm/boot/dts/dbx5x0.dtsi | 6 ++
drivers/mfd/ab8500-core.c | 5 ++
drivers/power/ab8500_charger.c | 72 ++++++++++++--------
5 files changed, 94 insertions(+), 28 deletions(-)
create mode 100644 Documentation/devicetree/bindings/power_supply/ab8500/charger.txt
diff --git a/Documentation/devicetree/bindings/mfd/ab8500.txt b/Documentation/devicetree/bindings/mfd/ab8500.txt
index 179c802..045dd87 100644
--- a/Documentation/devicetree/bindings/mfd/ab8500.txt
+++ b/Documentation/devicetree/bindings/mfd/ab8500.txt
@@ -36,6 +36,20 @@ ab8500-btemp : : vtvout : Battery Temperature
: BTEMP_HIGH : : BtempLow < Btemp < BtempMedium,if battery temperature is between -10 and 0?C
: BTEMP_LOW_MEDIUM : : BtempMedium < Btemp < BtempHigh,if battery temperature is between 0?C and?MaxTemp
: BTEMP_MEDIUM_HIGH : : Btemp > BtempHigh, if battery temperature is higher than ?MaxTemp?
+ab8500-charger : : vddadc : Charger interface
+ : MAIN_CH_UNPLUG_DET : : main charger unplug detection management (not in 8505)
+ : MAIN_CHARGE_PLUG_DET : : main charger plug detection management (not in 8505)
+ : MAIN_EXT_CH_NOT_OK : : main charger not OK
+ : MAIN_CH_TH_PROT_R : : Die temp is above main charger
+ : MAIN_CH_TH_PROT_F : : Die temp is below main charger
+ : VBUS_DET_F : : VBUS falling detected
+ : VBUS_DET_R : : VBUS rising detected
+ : USB_LINK_STATUS : : USB link status has changed
+ : USB_CH_TH_PROT_R : : Die temp is above usb charger
+ : USB_CH_TH_PROT_F : : Die temp is below usb charger
+ : USB_CHARGER_NOT_OKR : : allowed USB charger not ok detection
+ : VBUS_OVV : : Overvoltage on Vbus ball detected (USB charge is stopped)
+ : CH_WD_EXP : : Charger watchdog detected
ab8500-gpadc : HW_CONV_END : vddadc : Analogue to Digital Converter
SW_CONV_END : :
ab8500-gpio : : : GPIO Controller
diff --git a/Documentation/devicetree/bindings/power_supply/ab8500/charger.txt b/Documentation/devicetree/bindings/power_supply/ab8500/charger.txt
new file mode 100644
index 0000000..6bdbb08
--- /dev/null
+++ b/Documentation/devicetree/bindings/power_supply/ab8500/charger.txt
@@ -0,0 +1,25 @@
+=== AB8500 Charger Driver ===
+
+Required Properties:
+- compatible = Shall be "stericsson,ab8500-charger"
+- battery = Shall be battery specific information
+ Example:
+ ab8500_charger {
+ compatible = "stericsson,ab8500-charger";
+ battery = <&ab8500_battery>;
+ };
+
+- vddadc-supply: Supply for USB and Main charger
+ Example:
+ ab8500-charger {
+ vddadc-supply = <&ab8500_ldo_tvout_reg>;
+ }
+- autopower_cfg:
+ Boolean value depicting the presence of 'automatic poweron after powerloss'
+ Example:
+ ab8500-charger {
+ autopower_cfg;
+ };
+
+For information on battery specific node, Ref:
+Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
diff --git a/arch/arm/boot/dts/dbx5x0.dtsi b/arch/arm/boot/dts/dbx5x0.dtsi
index 79fdee4..b1ecb5d 100644
--- a/arch/arm/boot/dts/dbx5x0.dtsi
+++ b/arch/arm/boot/dts/dbx5x0.dtsi
@@ -367,6 +367,12 @@
battery = <&ab8500_battery>;
};
+ ab8500_charger {
+ compatible = "stericsson,ab8500-charger";
+ battery = <&ab8500_battery>;
+ vddadc-supply = <&ab8500_ldo_tvout_reg>;
+ };
+
ab8500_usb {
compatible = "stericsson,ab8500-usb";
interrupts = < 90 0x4
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index 94d45be..c7a120b 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -1041,8 +1041,13 @@ static struct mfd_cell __devinitdata abx500_common_devs[] = {
static struct mfd_cell __devinitdata ab8500_bm_devs[] = {
{
.name = "ab8500-charger",
+ .of_compatible = "stericsson,ab8500-charger",
.num_resources = ARRAY_SIZE(ab8500_charger_resources),
.resources = ab8500_charger_resources,
+#ifndef CONFIG_OF
+ .platform_data = &ab8500_bm_data,
+ .pdata_size = sizeof(ab8500_bm_data),
+#endif
},
{
.name = "ab8500-btemp",
diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c
index 78a730c..956943e 100644
--- a/drivers/power/ab8500_charger.c
+++ b/drivers/power/ab8500_charger.c
@@ -23,6 +23,8 @@
#include <linux/err.h>
#include <linux/workqueue.h>
#include <linux/kobject.h>
+#include <linux/of.h>
+#include <linux/mfd/core.h>
#include <linux/mfd/abx500/ab8500.h>
#include <linux/mfd/abx500.h>
#include <linux/mfd/abx500/ab8500-bm.h>
@@ -183,7 +185,6 @@ struct ab8500_charger_usb_state {
* @autopower Indicate if we should have automatic pwron after pwrloss
* @parent: Pointer to the struct ab8500
* @gpadc: Pointer to the struct gpadc
- * @pdata: Pointer to the abx500_charger platform data
* @bat: Pointer to the abx500_bm platform data
* @flags: Structure for information about events triggered
* @usb_state: Structure for usb stack information
@@ -218,9 +219,9 @@ struct ab8500_charger {
int vbat;
int old_vbat;
bool autopower;
+ bool autopower_cfg;
struct ab8500 *parent;
struct ab8500_gpadc *gpadc;
- struct abx500_bmdevs_plat_data *pdata;
struct abx500_bm_data *bat;
struct ab8500_charger_event_flags flags;
struct ab8500_charger_usb_state usb_state;
@@ -322,7 +323,7 @@ static void ab8500_power_loss_handling(struct ab8500_charger *di)
static void ab8500_power_supply_changed(struct ab8500_charger *di,
struct power_supply *psy)
{
- if (di->pdata->autopower_cfg) {
+ if (di->autopower_cfg) {
if (!di->usb.charger_connected &&
!di->ac.charger_connected &&
di->autopower) {
@@ -2526,25 +2527,45 @@ static int __devexit ab8500_charger_remove(struct platform_device *pdev)
power_supply_unregister(&di->usb_chg.psy);
power_supply_unregister(&di->ac_chg.psy);
platform_set_drvdata(pdev, NULL);
- kfree(di);
return 0;
}
+static char *supply_interface[] = {
+ "ab8500_chargalg",
+ "ab8500_fg",
+ "ab8500_btemp",
+};
+
static int __devinit ab8500_charger_probe(struct platform_device *pdev)
{
- struct abx500_bmdevs_plat_data *plat_data = pdev->dev.platform_data;
+ struct device_node *np = pdev->dev.of_node;
struct ab8500_charger *di;
int irq, i, charger_status, ret = 0;
- if (!plat_data) {
- dev_err(&pdev->dev, "No platform data\n");
- return -EINVAL;
- }
-
- di = kzalloc(sizeof(*di), GFP_KERNEL);
- if (!di)
+ di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
+ if (!di) {
+ dev_err(&pdev->dev, "%s no mem for ab8500_charger\n", __func__);
return -ENOMEM;
+ }
+ di->bat = pdev->mfd_cell->platform_data;
+ if (!di->bat) {
+ if (np) {
+ ret = bmdevs_of_probe(&pdev->dev, np, &di->bat);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed to get battery information\n");
+ return ret;
+ }
+ di->autopower_cfg = of_property_read_bool(np, "autopower_cfg");
+ } else {
+ dev_err(&pdev->dev, "missing dt node for ab8500_charger\n");
+ return -EINVAL;
+ }
+ } else {
+ dev_info(&pdev->dev, "falling back to legacy platform data\n");
+ di->autopower_cfg = false;
+ }
/* get parent data */
di->dev = &pdev->dev;
@@ -2554,14 +2575,6 @@ static int __devinit ab8500_charger_probe(struct platform_device *pdev)
/* initialize lock */
spin_lock_init(&di->usb_state.usb_lock);
- /* get charger specific platform data */
- di->pdata = plat_data;
- if (!di->pdata) {
- dev_err(di->dev, "no charger platform data supplied\n");
- ret = -EINVAL;
- goto free_device_info;
- }
-
di->autopower = false;
/* AC supply */
@@ -2571,8 +2584,8 @@ static int __devinit ab8500_charger_probe(struct platform_device *pdev)
di->ac_chg.psy.properties = ab8500_charger_ac_props;
di->ac_chg.psy.num_properties = ARRAY_SIZE(ab8500_charger_ac_props);
di->ac_chg.psy.get_property = ab8500_charger_ac_get_property;
- di->ac_chg.psy.supplied_to = di->pdata->supplied_to;
- di->ac_chg.psy.num_supplicants = di->pdata->num_supplicants;
+ di->ac_chg.psy.supplied_to = supply_interface;
+ di->ac_chg.psy.num_supplicants = ARRAY_SIZE(supply_interface),
/* ux500_charger sub-class */
di->ac_chg.ops.enable = &ab8500_charger_ac_en;
di->ac_chg.ops.kick_wd = &ab8500_charger_watchdog_kick;
@@ -2589,8 +2602,8 @@ static int __devinit ab8500_charger_probe(struct platform_device *pdev)
di->usb_chg.psy.properties = ab8500_charger_usb_props;
di->usb_chg.psy.num_properties = ARRAY_SIZE(ab8500_charger_usb_props);
di->usb_chg.psy.get_property = ab8500_charger_usb_get_property;
- di->usb_chg.psy.supplied_to = di->pdata->supplied_to;
- di->usb_chg.psy.num_supplicants = di->pdata->num_supplicants;
+ di->usb_chg.psy.supplied_to = supply_interface;
+ di->usb_chg.psy.num_supplicants = ARRAY_SIZE(supply_interface),
/* ux500_charger sub-class */
di->usb_chg.ops.enable = &ab8500_charger_usb_en;
di->usb_chg.ops.kick_wd = &ab8500_charger_watchdog_kick;
@@ -2606,7 +2619,7 @@ static int __devinit ab8500_charger_probe(struct platform_device *pdev)
create_singlethread_workqueue("ab8500_charger_wq");
if (di->charger_wq == NULL) {
dev_err(di->dev, "failed to create work queue\n");
- goto free_device_info;
+ return -ENOMEM;
}
/* Init work for HW failure check */
@@ -2748,12 +2761,14 @@ free_regulator:
regulator_put(di->regu);
free_charger_wq:
destroy_workqueue(di->charger_wq);
-free_device_info:
- kfree(di);
-
return ret;
}
+static const struct of_device_id ab8500_charger_match[] = {
+ { .compatible = "stericsson,ab8500-charger", },
+ { },
+};
+
static struct platform_driver ab8500_charger_driver = {
.probe = ab8500_charger_probe,
.remove = __devexit_p(ab8500_charger_remove),
@@ -2762,6 +2777,7 @@ static struct platform_driver ab8500_charger_driver = {
.driver = {
.name = "ab8500-charger",
.owner = THIS_MODULE,
+ .of_match_table = ab8500_charger_match,
},
};
--
1.7.10.4
^ permalink raw reply related
* [PATCH 4/4] mfd: ab8500: add devicetree support for chargalg
From: Rajanikanth H.V @ 2012-10-25 6:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351146654-9110-1-git-send-email-rajanikanth.hv@stericsson.com>
From: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>
This patch adds device tree support for charging algorithm
driver
Signed-off-by: Rajanikanth H.V <rajanikanth.hv@stericsson.com>
---
.../bindings/power_supply/ab8500/chargalg.txt | 16 ++++++
arch/arm/boot/dts/dbx5x0.dtsi | 5 ++
drivers/mfd/ab8500-core.c | 5 ++
drivers/power/abx500_chargalg.c | 54 ++++++++++++++------
include/linux/mfd/abx500.h | 6 ---
5 files changed, 65 insertions(+), 21 deletions(-)
create mode 100644 Documentation/devicetree/bindings/power_supply/ab8500/chargalg.txt
diff --git a/Documentation/devicetree/bindings/power_supply/ab8500/chargalg.txt b/Documentation/devicetree/bindings/power_supply/ab8500/chargalg.txt
new file mode 100644
index 0000000..ef53283
--- /dev/null
+++ b/Documentation/devicetree/bindings/power_supply/ab8500/chargalg.txt
@@ -0,0 +1,16 @@
+=== AB8500 Charging Algorithm Driver ===
+
+The properties below describes the node for chargalg driver.
+
+Required Properties:
+- compatible = Shall be: "stericsson,ab8500-chargalg"
+- battery = Shall be battery specific information
+
+Example:
+ab8500_chargalg {
+ compatible = "stericsson,ab8500-chargalg";
+ battery = <&ab8500_battery>;
+};
+
+For information on battery specific node, Ref:
+Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
diff --git a/arch/arm/boot/dts/dbx5x0.dtsi b/arch/arm/boot/dts/dbx5x0.dtsi
index b1ecb5d..a678afa 100644
--- a/arch/arm/boot/dts/dbx5x0.dtsi
+++ b/arch/arm/boot/dts/dbx5x0.dtsi
@@ -373,6 +373,11 @@
vddadc-supply = <&ab8500_ldo_tvout_reg>;
};
+ ab8500_chargalg {
+ compatible = "stericsson,ab8500-chargalg";
+ battery = <&ab8500_battery>;
+ };
+
ab8500_usb {
compatible = "stericsson,ab8500-usb";
interrupts = < 90 0x4
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index c7a120b..afe835b 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -1071,8 +1071,13 @@ static struct mfd_cell __devinitdata ab8500_bm_devs[] = {
},
{
.name = "ab8500-chargalg",
+ .of_compatible = "stericsson,ab8500-chargalg",
.num_resources = ARRAY_SIZE(ab8500_chargalg_resources),
.resources = ab8500_chargalg_resources,
+#ifndef CONFIG_USE_OF
+ .platform_data = &ab8500_bm_data,
+ .pdata_size = sizeof(ab8500_bm_data),
+#endif
},
};
diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c
index 88b5cc1..829fcfd 100644
--- a/drivers/power/abx500_chargalg.c
+++ b/drivers/power/abx500_chargalg.c
@@ -21,6 +21,8 @@
#include <linux/completion.h>
#include <linux/workqueue.h>
#include <linux/kobject.h>
+#include <linux/of.h>
+#include <linux/mfd/core.h>
#include <linux/mfd/abx500.h>
#include <linux/mfd/abx500/ux500_chargalg.h>
#include <linux/mfd/abx500/ab8500-bm.h>
@@ -231,7 +233,6 @@ struct abx500_chargalg {
struct abx500_chargalg_charger_info chg_info;
struct abx500_chargalg_battery_data batt_data;
struct abx500_chargalg_suspension_status susp_status;
- struct abx500_bmdevs_plat_data *pdata;
struct abx500_bm_data *bat;
struct power_supply chargalg_psy;
struct ux500_charger *ac_chg;
@@ -1795,25 +1796,45 @@ static int __devexit abx500_chargalg_remove(struct platform_device *pdev)
flush_scheduled_work();
power_supply_unregister(&di->chargalg_psy);
platform_set_drvdata(pdev, NULL);
- kfree(di);
return 0;
}
+static char *supply_interface[] = {
+ "ab8500_fg",
+};
+
static int __devinit abx500_chargalg_probe(struct platform_device *pdev)
{
- struct abx500_bmdevs_plat_data *plat_data;
+ struct device_node *np = pdev->dev.of_node;
+ struct abx500_chargalg *di;
int ret = 0;
- struct abx500_chargalg *di =
- kzalloc(sizeof(struct abx500_chargalg), GFP_KERNEL);
- if (!di)
+ di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
+ if (!di) {
+ dev_err(&pdev->dev, "%s no mem for ab8500_chargalg\n", __func__);
return -ENOMEM;
+ }
+ di->bat = pdev->mfd_cell->platform_data;
+ if (!di->bat) {
+ if (np) {
+ ret = bmdevs_of_probe(&pdev->dev, np, &di->bat);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed to get battery information\n");
+ return ret;
+ }
+ } else {
+ dev_err(&pdev->dev, "missing dt node for ab8500_chargalg\n");
+ return -EINVAL;
+ }
+ } else {
+ dev_info(&pdev->dev, "falling back to legacy platform data\n");
+ printk("%s falling back to legacy platform data\n", __func__);
+ }
/* get device struct */
di->dev = &pdev->dev;
- plat_data = pdev->dev.platform_data;
- di->pdata = plat_data;
/* chargalg supply */
di->chargalg_psy.name = "abx500_chargalg";
@@ -1821,8 +1842,8 @@ static int __devinit abx500_chargalg_probe(struct platform_device *pdev)
di->chargalg_psy.properties = abx500_chargalg_props;
di->chargalg_psy.num_properties = ARRAY_SIZE(abx500_chargalg_props);
di->chargalg_psy.get_property = abx500_chargalg_get_property;
- di->chargalg_psy.supplied_to = di->pdata->supplied_to;
- di->chargalg_psy.num_supplicants = di->pdata->num_supplicants;
+ di->chargalg_psy.supplied_to = supply_interface;
+ di->chargalg_psy.num_supplicants = ARRAY_SIZE(supply_interface),
di->chargalg_psy.external_power_changed =
abx500_chargalg_external_power_changed;
@@ -1842,7 +1863,7 @@ static int __devinit abx500_chargalg_probe(struct platform_device *pdev)
create_singlethread_workqueue("abx500_chargalg_wq");
if (di->chargalg_wq == NULL) {
dev_err(di->dev, "failed to create work queue\n");
- goto free_device_info;
+ return -ENOMEM;
}
/* Init work for chargalg */
@@ -1883,20 +1904,23 @@ free_psy:
power_supply_unregister(&di->chargalg_psy);
free_chargalg_wq:
destroy_workqueue(di->chargalg_wq);
-free_device_info:
- kfree(di);
-
return ret;
}
+static const struct of_device_id ab8500_chargalg_match[] = {
+ { .compatible = "stericsson,ab8500-chargalg", },
+ { },
+};
+
static struct platform_driver abx500_chargalg_driver = {
.probe = abx500_chargalg_probe,
.remove = __devexit_p(abx500_chargalg_remove),
.suspend = abx500_chargalg_suspend,
.resume = abx500_chargalg_resume,
.driver = {
- .name = "abx500-chargalg",
+ .name = "ab8500-chargalg",
.owner = THIS_MODULE,
+ .of_match_table = ab8500_chargalg_match,
},
};
diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h
index bbf3ad6..a14c1a6 100644
--- a/include/linux/mfd/abx500.h
+++ b/include/linux/mfd/abx500.h
@@ -389,12 +389,6 @@ struct abx500_bm_data {
extern struct abx500_bm_data ab8500_bm_data;
-struct abx500_bmdevs_plat_data {
- char **supplied_to;
- size_t num_supplicants;
- bool autopower_cfg;
-};
-
enum {
NTC_EXTERNAL = 0,
NTC_INTERNAL,
--
1.7.10.4
^ permalink raw reply related
* [PATCH] ARM: dt: tegra: ventana: define pinmux for ddc
From: Mark Zhang @ 2012-10-25 6:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50857EEF.2070707@wwwdotorg.org>
On 10/23/2012 01:14 AM, Stephen Warren wrote:
> On 10/22/2012 01:29 AM, Mark Zhang wrote:
>> On 10/19/2012 11:48 PM, Stephen Warren wrote:
>>> On 10/18/2012 11:58 PM, Mark Zhang wrote:
>>>> Define pinmux for DDC. The DDC pinmux in Ventana is 2 pins in I2C2.
>>>
>>>> +++ b/arch/arm/boot/dts/tegra20-ventana.dts
>>>
>>>> - ddc {
>>>> - nvidia,pins = "ddc", "owc", "spdi", "spdo",
>>>> - "uac";
>>>> - nvidia,function = "rsvd2";
>>>> - };
>>>
>>> So that removes the entries for 5 pin groups, yet below, entries are
>>> only added for the ddc and pta pingroups, so the other 4 pin groups
>>> become unconfigured.
>>>
>>
>> Right. So I think it should be changed to:
>>
>> owc {
>> nvidia,pins = "owc", "spdi", "spdo", "uac";
>> nvidia,function = "rsvd2";
>> };
>>
>> Is this right?
>
> Looks correct, yes.
>
>>>> +
>>>> + state_i2cmux_ddc: pinmux_i2cmux_ddc {
>>>> + ddc {
>>>> + nvidia,pins = "ddc";
>>>> + nvidia,function = "i2c2";
>>>> + };
>>>> + pta {
>>>> + nvidia,pins = "pta";
>>>> + nvidia,function = "rsvd4";
>>>> + };
>>>
>>> Does this actually work? The pta pingroup is configured by the "hog"
>>> pinctrl state of the pinctrl node itself, so this state should fail to
>>> be applied since it attempts to touch the same pingroup.
>>
>> I know little about kernel pinctrl subsystem. After reading some docs
>> and codes, I think what you mean is, in Ventana's pinmux configuration,
>> pta pingroup has been defined as "hdmi" function and this can't be
>> changed(non-dynamic pinmuxing).
>> So I want to know why we have defined pta pingroup as hdmi function?
>> Can we remove this definition to make the i2cmux above working?
>
> I don't recall why pta was defined to be HDMI. The issue isn't that this
> patch changes the pinmux selection for the pta pingroup, but simply that
> both the pinctrl node's state definition, and the new I2C mux node's
> state definition both attempt to configure pingroup pta. The solution is
> most likely to simply remove the pta configuration from the main pinctrl
> node.
>
Understood. I tried to remove the hdmi function definition of pta
pingroup yesterday then found HDMI can't work anymore. The EDID of HDMI
monitor can't be fetched. After some debugging, I have found that it's
caused by "i2c-mux-pinctrl" driver is loaded after drm driver. That
makes drm driver can't get EDID data via this i2c mux adapter because it
doesn't exist at that time. So I think we need to promote the load level
of "i2c-mux-pinctrl" driver. Any other ideas?
Mark
^ permalink raw reply
* [PATCH] drivers: bus: omap_interconnect: Fix rand-config build warning
From: Santosh Shilimkar @ 2012-10-25 6:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121025004216.GJ11928@atomide.com>
On Thursday 25 October 2012 06:12 AM, Tony Lindgren wrote:
> * Tony Lindgren <tony@atomide.com> [121024 17:36]:
>> * Santosh Shilimkar <santosh.shilimkar@ti.com> [121017 06:35]:
>>> (Looping Arnd and Olof)
>>>
>>> On Wednesday 17 October 2012 06:58 PM, Lokesh Vutla wrote:
>>>> When building omap_l3_noc/smx drivers as modules, the following
>>>> warning appears:
>>>>
>>>> CC [M] drivers/bus/omap_l3_smx.o
>>>> drivers/bus/omap_l3_smx.c:291: warning: data definition has no type or storage class
>>>> drivers/bus/omap_l3_smx.c:291: warning: type defaults to 'int' in declaration of 'postcore_initcall_sync'
>>>> drivers/bus/omap_l3_smx.c:291: warning: parameter names (without types) in function declaration
>>>> drivers/bus/omap_l3_smx.c:287: warning: 'omap3_l3_init' defined but not used
>>>> CC [M] drivers/bus/omap_l3_noc.o
>>>> drivers/bus/omap_l3_noc.c:260: warning: data definition has no type or storage class
>>>> drivers/bus/omap_l3_noc.c:260: warning: type defaults to 'int' in declaration of 'arch_initcall_sync'
>>>> drivers/bus/omap_l3_noc.c:260: warning: parameter names (without types) in function declaration
>>>> drivers/bus/omap_l3_noc.c:256: warning: 'omap4_l3_init' defined but not used
>>>>
>>>> Adding module_init() and macros in omap_l3_noc/smx drivers when building
>>>> as modules to remove the above warning.
>>>>
>>>> Reported-by: Tony Lindgren <tony@atomide.com>
>>>> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
>>>> ---
>>> Thanks for the fix Lokesh. Looks fine to me.
>>>
>>> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>
>> Looks like nobody else has picked this up so I'll queue this along
>> with few other omap warnings and regressions.
>
> Hmm actually this might require some more discussion. If we make
> it use regular initcalls, then the ugly ifdefs can be left
> out. Is there a reason to init this early, can't we just use regular
> initcalls?
>
I thought about it. The whole reason we want interconnect errors enabled
early in the boot to avoid bad accesses issued on interconnect
in early boot by various init codes. We managed to discovered many
init sequence issues where the a driver is trying to access registers
when clocks are not active, or drivers are using bad mapping. At times
these errors gets un-noticed because of the behavior of interconnect
and later causes serious issues. Leaving the driver init late in the
boot means we can't catch any of the issues happen till the L3 driver
init happens.
Regards
Santosh
^ permalink raw reply
* [RFC] cpufreq: Make sure target freq is within limits
From: Viresh Kumar @ 2012-10-25 6:33 UTC (permalink / raw)
To: linux-arm-kernel
Hi Rafael,
__cpufreq_driver_target() must not pass target frequency beyond the limits of
current policy.
Today most of cpufreq platform drivers are doing this check in their target
routines. Why not move it to __cpufreq_driver_target().
I wanted to get your opinion on this before making changes in all driver files.
That's why this is an RFC.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
drivers/cpufreq/cpufreq.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index f552d5f..59264f1 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1470,12 +1470,19 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
unsigned int relation)
{
int retval = -EINVAL;
+ unsigned int old_target_freq = target_freq;
if (cpufreq_disabled())
return -ENODEV;
- pr_debug("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
- target_freq, relation);
+ /* Make sure that target_freq is within supported range */
+ if (target_freq > policy->max)
+ target_freq = policy->max;
+ if (target_freq < policy->min)
+ target_freq = policy->min;
+
+ pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
+ policy->cpu, target_freq, relation, old_target_freq);
if (cpu_online(policy->cpu) && cpufreq_driver->target)
retval = cpufreq_driver->target(policy, target_freq, relation);
--
1.7.12.rc2.18.g61b472e
^ permalink raw reply related
* [PATCH v2] i2c: omap: re-factor omap_i2c_init function
From: Felipe Balbi @ 2012-10-25 6:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351147011-6500-1-git-send-email-shubhrajyoti@ti.com>
Hi,
On Thu, Oct 25, 2012 at 12:06:51PM +0530, Shubhrajyoti D wrote:
> re-factor omap_i2c_init() so that we can re-use it for resume.
> While at it also remove the bufstate variable as we write it
> in omap_i2c_resize_fifo for every transfer.
>
> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
> ---
> v2 - add the iestate 0 check back.
> - Remove a stray change.
> - Applies on top of Felipe's patches.
> http://www.spinics.net/lists/linux-omap/msg79995.html
>
>
> Tested with Terro sys fix + Felipe's stop sched_clock() during suspend
> on omap3636 beagle both idle and suspend.
>
> Functional testing on omap4sdp.
>
> drivers/i2c/busses/i2c-omap.c | 71 ++++++++++++++++++----------------------
> 1 files changed, 32 insertions(+), 39 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index 5e5cefb..3d400b1 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -209,7 +209,6 @@ struct omap_i2c_dev {
> u16 pscstate;
> u16 scllstate;
> u16 sclhstate;
> - u16 bufstate;
> u16 syscstate;
> u16 westate;
> u16 errata;
> @@ -285,9 +284,31 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
> }
> }
>
> +static void __omap_i2c_init(struct omap_i2c_dev *dev)
> +{
> +
> + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
> + /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */
> + omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
> +
> + /* SCL low and high time values */
> + omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
> + if (dev->rev >= OMAP_I2C_REV_ON_3430_3530)
> + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
> + /* Take the I2C module out of reset: */
> + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
a few blank lines in this function wouldn't hurt and they would help
with readability.
> + /*
> + * Don't write to this register if the IE state is 0 as it can
> + * cause deadlock.
> + */
> + if (dev->iestate)
> + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
> +}
> +
> static int omap_i2c_init(struct omap_i2c_dev *dev)
> {
> - u16 psc = 0, scll = 0, sclh = 0, buf = 0;
> + u16 psc = 0, scll = 0, sclh = 0;
> u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
> unsigned long fclk_rate = 12000000;
> unsigned long timeout;
> @@ -337,11 +358,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
> * REVISIT: Some wkup sources might not be needed.
> */
> dev->westate = OMAP_I2C_WE_ALL;
> - omap_i2c_write_reg(dev, OMAP_I2C_WE_REG,
> - dev->westate);
remove the comment too since now that's done by some other function ?
> }
> }
> - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
>
> if (dev->flags & OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) {
> /*
> @@ -426,28 +444,18 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
> sclh = fclk_rate / (dev->speed * 2) - 7 + psc;
> }
>
> - /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */
> - omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, psc);
> -
> - /* SCL low and high time values */
> - omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
> - omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);
> -
> - /* Take the I2C module out of reset: */
> - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
> -
> /* Enable interrupts */
> dev->iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
> OMAP_I2C_IE_NACK | OMAP_I2C_IE_AL) |
> ((dev->fifo_size) ? (OMAP_I2C_IE_RDR |
> OMAP_I2C_IE_XDR) : 0);
> - omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
> - if (dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
> - dev->pscstate = psc;
> - dev->scllstate = scll;
> - dev->sclhstate = sclh;
> - dev->bufstate = buf;
> - }
> +
> + dev->pscstate = psc;
> + dev->scllstate = scll;
> + dev->sclhstate = sclh;
> +
> + __omap_i2c_init(dev);
> +
> return 0;
> }
>
> @@ -1268,23 +1276,8 @@ static int omap_i2c_runtime_resume(struct device *dev)
> {
> struct omap_i2c_dev *_dev = dev_get_drvdata(dev);
>
> - if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
> - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
> - }
> -
> - /*
> - * Don't write to this register if the IE state is 0 as it can
> - * cause deadlock.
> - */
> - if (_dev->iestate)
> - omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate);
> + if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE)
> + __omap_i2c_init(_dev);
>
> return 0;
> }
you continue to miss the changes in omap_i2c_xfer_msg() and your
explanation of why not doing it wasn't good enough IMHO.
--
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121025/7ee5fe9b/attachment-0001.sig>
^ permalink raw reply
* [PATCH v2] i2c: omap: re-factor omap_i2c_init function
From: Shubhrajyoti D @ 2012-10-25 6:36 UTC (permalink / raw)
To: linux-arm-kernel
re-factor omap_i2c_init() so that we can re-use it for resume.
While at it also remove the bufstate variable as we write it
in omap_i2c_resize_fifo for every transfer.
Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
v2 - add the iestate 0 check back.
- Remove a stray change.
- Applies on top of Felipe's patches.
http://www.spinics.net/lists/linux-omap/msg79995.html
Tested with Terro sys fix + Felipe's stop sched_clock() during suspend
on omap3636 beagle both idle and suspend.
Functional testing on omap4sdp.
drivers/i2c/busses/i2c-omap.c | 71 ++++++++++++++++++----------------------
1 files changed, 32 insertions(+), 39 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 5e5cefb..3d400b1 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -209,7 +209,6 @@ struct omap_i2c_dev {
u16 pscstate;
u16 scllstate;
u16 sclhstate;
- u16 bufstate;
u16 syscstate;
u16 westate;
u16 errata;
@@ -285,9 +284,31 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
}
}
+static void __omap_i2c_init(struct omap_i2c_dev *dev)
+{
+
+ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
+ /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */
+ omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
+
+ /* SCL low and high time values */
+ omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
+ omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
+ if (dev->rev >= OMAP_I2C_REV_ON_3430_3530)
+ omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
+ /* Take the I2C module out of reset: */
+ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+ /*
+ * Don't write to this register if the IE state is 0 as it can
+ * cause deadlock.
+ */
+ if (dev->iestate)
+ omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
+}
+
static int omap_i2c_init(struct omap_i2c_dev *dev)
{
- u16 psc = 0, scll = 0, sclh = 0, buf = 0;
+ u16 psc = 0, scll = 0, sclh = 0;
u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
unsigned long fclk_rate = 12000000;
unsigned long timeout;
@@ -337,11 +358,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
* REVISIT: Some wkup sources might not be needed.
*/
dev->westate = OMAP_I2C_WE_ALL;
- omap_i2c_write_reg(dev, OMAP_I2C_WE_REG,
- dev->westate);
}
}
- omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
if (dev->flags & OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) {
/*
@@ -426,28 +444,18 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
sclh = fclk_rate / (dev->speed * 2) - 7 + psc;
}
- /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */
- omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, psc);
-
- /* SCL low and high time values */
- omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
- omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);
-
- /* Take the I2C module out of reset: */
- omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
-
/* Enable interrupts */
dev->iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
OMAP_I2C_IE_NACK | OMAP_I2C_IE_AL) |
((dev->fifo_size) ? (OMAP_I2C_IE_RDR |
OMAP_I2C_IE_XDR) : 0);
- omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
- if (dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
- dev->pscstate = psc;
- dev->scllstate = scll;
- dev->sclhstate = sclh;
- dev->bufstate = buf;
- }
+
+ dev->pscstate = psc;
+ dev->scllstate = scll;
+ dev->sclhstate = sclh;
+
+ __omap_i2c_init(dev);
+
return 0;
}
@@ -1268,23 +1276,8 @@ static int omap_i2c_runtime_resume(struct device *dev)
{
struct omap_i2c_dev *_dev = dev_get_drvdata(dev);
- if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
- omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
- omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
- omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
- }
-
- /*
- * Don't write to this register if the IE state is 0 as it can
- * cause deadlock.
- */
- if (_dev->iestate)
- omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate);
+ if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE)
+ __omap_i2c_init(_dev);
return 0;
}
--
1.7.5.4
^ permalink raw reply related
* [PATCH] [RFC] pinctrl: mvebu: reset pins to an UNKNOWN state on startup
From: Linus Walleij @ 2012-10-25 6:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351106281-31288-1-git-send-email-thomas.petazzoni@free-electrons.com>
On Wed, Oct 24, 2012 at 9:18 PM, Thomas Petazzoni
<thomas.petazzoni@free-electrons.com> wrote:
> On many platforms, most of the pinmux initialization is done in the
> bootloader, and therefore persists when we boot the Linux kernel. This
> prevents us from making sure that the pinmux configuration in the
> board device trees is correct.
>
> One idea to make sure our device trees are correct in terms of
> pinmuxing is to set the state of each pin to an unavailable function
> during the initialization of the pinctrl driver. This way, only pins
> that are explicitly configured through proper device tree attributes
> will actually be functional.
Now I don't know which kernel senior being it was that told me
never to screw around with the defaults from the boot loader
if not really needed. It is better if the driver reads the hardware
to figure out what state it's in and move on from there.
There may be cases where it's still needed, such as to save
power, if pins (in this case) are set up such that they waste
power unless the default setting is overridden.
So I think it'd be nice if the actual reasons for doing this
movement to a known state were known? Else the design
pattern should be to discover the current state from the
actual hardware registers.
Depending on complexity the above may be a bit utopic...
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH] [RFC] pinctrl: mvebu: reset pins to an UNKNOWN state on startup
From: Linus Walleij @ 2012-10-25 6:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121024222139.40fb2ad5@skate>
On Wed, Oct 24, 2012 at 10:21 PM, Thomas Petazzoni
<thomas.petazzoni@free-electrons.com> wrote:
> On Wed, 24 Oct 2012 22:15:45 +0200, Andrew Lunn wrote:
>> If you compare the two, you can see that pin 6 has probably been set by
>> uboot, but not by DT.
>
> Indeed, by correlating the two files, you can get a good view of which
> pins are configured even though no driver has claimed them.
If it is useful, please consider introducing new debugfs files, that thing
is supposed to be helpful.
For example: if a <debugfs>/pinctrl/pinctrl-foo/pins-probe-state
caching and providing the power-on-state of all pins is useful,
then just add that mechanism to the pinctrl core I'd say.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH V2] ARM: dt: tegra: ventana: define pinmux for ddc
From: Mark Zhang @ 2012-10-25 6:52 UTC (permalink / raw)
To: linux-arm-kernel
Tegra 2's I2C2 controller can be routed to either the PTA
or DDC pin group on Ventana. So:
- Remove the HDMI function definition of pta pingroup
- Define child i2c adapters(ddc & pta) for I2C2 controller
Signed-off-by: Mark Zhang <markz@nvidia.com>
---
arch/arm/boot/dts/tegra20-ventana.dts | 69 ++++++++++++++++++++++++++++++---
1 file changed, 63 insertions(+), 6 deletions(-)
diff --git a/arch/arm/boot/dts/tegra20-ventana.dts b/arch/arm/boot/dts/tegra20-ventana.dts
index bec8bb2..1dde0d3 100644
--- a/arch/arm/boot/dts/tegra20-ventana.dts
+++ b/arch/arm/boot/dts/tegra20-ventana.dts
@@ -64,11 +64,6 @@
nvidia,pins = "dap4";
nvidia,function = "dap4";
};
- ddc {
- nvidia,pins = "ddc", "owc", "spdi", "spdo",
- "uac";
- nvidia,function = "rsvd2";
- };
dta {
nvidia,pins = "dta", "dtb", "dtc", "dtd", "dte";
nvidia,function = "vi";
@@ -98,7 +93,7 @@
nvidia,function = "pcie";
};
hdint {
- nvidia,pins = "hdint", "pta";
+ nvidia,pins = "hdint";
nvidia,function = "hdmi";
};
i2cp {
@@ -129,6 +124,10 @@
"lspi", "lvp1", "lvs";
nvidia,function = "displaya";
};
+ owc {
+ nvidia,pins = "owc", "spdi", "spdo", "uac";
+ nvidia,function = "rsvd2";
+ };
pmc {
nvidia,pins = "pmc";
nvidia,function = "pwr_on";
@@ -248,6 +247,39 @@
nvidia,slew-rate-falling = <3>;
};
};
+
+ state_i2cmux_ddc: pinmux_i2cmux_ddc {
+ ddc {
+ nvidia,pins = "ddc";
+ nvidia,function = "i2c2";
+ };
+ pta {
+ nvidia,pins = "pta";
+ nvidia,function = "rsvd4";
+ };
+ };
+
+ state_i2cmux_pta: pinmux_i2cmux_pta {
+ ddc {
+ nvidia,pins = "ddc";
+ nvidia,function = "rsvd4";
+ };
+ pta {
+ nvidia,pins = "pta";
+ nvidia,function = "i2c2";
+ };
+ };
+
+ state_i2cmux_idle: pinmux_i2cmux_idle {
+ ddc {
+ nvidia,pins = "ddc";
+ nvidia,function = "rsvd4";
+ };
+ pta {
+ nvidia,pins = "pta";
+ nvidia,function = "rsvd4";
+ };
+ };
};
i2s at 70002800 {
@@ -291,6 +323,31 @@
clock-frequency = <400000>;
};
+ i2cmux {
+ compatible = "i2c-mux-pinctrl";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c-parent = <&{/i2c@7000c400}>;
+
+ pinctrl-names = "ddc", "pta", "idle";
+ pinctrl-0 = <&state_i2cmux_ddc>;
+ pinctrl-1 = <&state_i2cmux_pta>;
+ pinctrl-2 = <&state_i2cmux_idle>;
+
+ i2c at 0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c at 1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
i2c at 7000c500 {
status = "okay";
clock-frequency = <400000>;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2] i2c: omap: re-factor omap_i2c_init function
From: Shubhrajyoti Datta @ 2012-10-25 6:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121025063608.GA5084@arwen.pp.htv.fi>
On Thu, Oct 25, 2012 at 12:06 PM, Felipe Balbi <balbi@ti.com> wrote:
> Hi,
>
> On Thu, Oct 25, 2012 at 12:06:51PM +0530, Shubhrajyoti D wrote:
>> re-factor omap_i2c_init() so that we can re-use it for resume.
>> While at it also remove the bufstate variable as we write it
>> in omap_i2c_resize_fifo for every transfer.
>>
>> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
>> ---
>> v2 - add the iestate 0 check back.
>> - Remove a stray change.
>> - Applies on top of Felipe's patches.
>> http://www.spinics.net/lists/linux-omap/msg79995.html
>>
>>
>> Tested with Terro sys fix + Felipe's stop sched_clock() during suspend
>> on omap3636 beagle both idle and suspend.
>>
>> Functional testing on omap4sdp.
>>
>> drivers/i2c/busses/i2c-omap.c | 71 ++++++++++++++++++----------------------
>> 1 files changed, 32 insertions(+), 39 deletions(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
>> index 5e5cefb..3d400b1 100644
>> --- a/drivers/i2c/busses/i2c-omap.c
>> +++ b/drivers/i2c/busses/i2c-omap.c
>> @@ -209,7 +209,6 @@ struct omap_i2c_dev {
>> u16 pscstate;
>> u16 scllstate;
>> u16 sclhstate;
>> - u16 bufstate;
>> u16 syscstate;
>> u16 westate;
>> u16 errata;
>> @@ -285,9 +284,31 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
>> }
>> }
>>
>> +static void __omap_i2c_init(struct omap_i2c_dev *dev)
>> +{
>> +
>> + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
>> + /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */
>> + omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
>> +
>> + /* SCL low and high time values */
>> + omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
>> + omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
>> + if (dev->rev >= OMAP_I2C_REV_ON_3430_3530)
>> + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
>> + /* Take the I2C module out of reset: */
>> + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
>
> a few blank lines in this function wouldn't hurt and they would help
> with readability.
Will add .
>
>> + /*
>> + * Don't write to this register if the IE state is 0 as it can
>> + * cause deadlock.
>> + */
>> + if (dev->iestate)
>> + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
>> +}
>> +
>> static int omap_i2c_init(struct omap_i2c_dev *dev)
>> {
>> - u16 psc = 0, scll = 0, sclh = 0, buf = 0;
>> + u16 psc = 0, scll = 0, sclh = 0;
>> u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
>> unsigned long fclk_rate = 12000000;
>> unsigned long timeout;
>> @@ -337,11 +358,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
>> * REVISIT: Some wkup sources might not be needed.
>> */
>> dev->westate = OMAP_I2C_WE_ALL;
>> - omap_i2c_write_reg(dev, OMAP_I2C_WE_REG,
>> - dev->westate);
>
> remove the comment too since now that's done by some other function ?
>
>> }
>> }
>> - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
>>
>> if (dev->flags & OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) {
>> /*
>> @@ -426,28 +444,18 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
>> sclh = fclk_rate / (dev->speed * 2) - 7 + psc;
>> }
>>
>> - /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */
>> - omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, psc);
>> -
>> - /* SCL low and high time values */
>> - omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
>> - omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);
>> -
>> - /* Take the I2C module out of reset: */
>> - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
>> -
>> /* Enable interrupts */
>> dev->iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
>> OMAP_I2C_IE_NACK | OMAP_I2C_IE_AL) |
>> ((dev->fifo_size) ? (OMAP_I2C_IE_RDR |
>> OMAP_I2C_IE_XDR) : 0);
>> - omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
>> - if (dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
>> - dev->pscstate = psc;
>> - dev->scllstate = scll;
>> - dev->sclhstate = sclh;
>> - dev->bufstate = buf;
>> - }
>> +
>> + dev->pscstate = psc;
>> + dev->scllstate = scll;
>> + dev->sclhstate = sclh;
>> +
>> + __omap_i2c_init(dev);
>> +
>> return 0;
>> }
>>
>> @@ -1268,23 +1276,8 @@ static int omap_i2c_runtime_resume(struct device *dev)
>> {
>> struct omap_i2c_dev *_dev = dev_get_drvdata(dev);
>>
>> - if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
>> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
>> - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
>> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
>> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
>> - omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
>> - omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
>> - omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
>> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
>> - }
>> -
>> - /*
>> - * Don't write to this register if the IE state is 0 as it can
>> - * cause deadlock.
>> - */
>> - if (_dev->iestate)
>> - omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate);
>> + if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE)
>> + __omap_i2c_init(_dev);
>>
>> return 0;
>> }
>
> you continue to miss the changes in omap_i2c_xfer_msg() and your
> explanation of why not doing it wasn't good enough IMHO.
Will do that . I am preparing a seperate patch for moving the
calculation to a seperate function.
>
> --
> balbi
^ permalink raw reply
* Possible regression in arm/io.h
From: Artem Bityutskiy @ 2012-10-25 6:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121024105223.GC23775@mudshark.cambridge.arm.com>
On Wed, 2012-10-24 at 11:52 +0100, Will Deacon wrote:
> (a) Understand what has changed in GCC to cause this error to start
> cropping up.
This is about already quite old gcc 4.6.3, which I use for about 4 last
kernel releases already. So it is only the kernel that changed.
You can download the GCC I used from here:
http://kernel.org/pub/tools/crosstool/
--
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121025/15484097/attachment.sig>
^ permalink raw reply
* [PATCH 1/3] pinctrl: mvebu: allow plat-orion architectures to use pinctrl-mvebu
From: Linus Walleij @ 2012-10-25 6:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351114738-26793-1-git-send-email-thomas.petazzoni@free-electrons.com>
On Wed, Oct 24, 2012 at 11:38 PM, Thomas Petazzoni
<thomas.petazzoni@free-electrons.com> wrote:
> The mach-kirkwood and mach-dove architectures have not yet been
> integrated into the mach-mvebu directory, which should ultimately
> contain the support for all Marvell SoCs from the Engineering Business
> Unit.
>
> However, before this can happen, we need to let mach-kirkwood and
> mach-dove use the pinctrl-mvebu driver, which supports the kirkwood
> and dove SoC families. In order to do that, we make this driver
> available as soon as PLAT_ORION is selected, instead of using
> ARCH_MVEBU as a condition. In the long term, PLAT_ORION should
> disappear and be fully replaced by ARCH_MVEBU, but the plan is to make
> the migration step by step, by first having the existing mach-*
> directories for Marvell SoCs converge on several infrastructures,
> including the pinctrl one.
>
> Also, like the spear pinctrl driver, we put all pinctrl-mvebu Kconfig
> options under a if, in order to avoid having certain options
> (PINCTRL_DOVE, PINCTRL_KIRKWOOD, etc.) selecting an option
> (PINCTLR_MVEBU) which itself has a dependency (on ARCH_MVEBU). In this
> a construct, the dependency is in fact ignored due to the selects.
>
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
OK makes sense, patch applied.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH 2/3] pinctrl: mvebu: remove useless include
From: Linus Walleij @ 2012-10-25 6:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351114738-26793-2-git-send-email-thomas.petazzoni@free-electrons.com>
On Wed, Oct 24, 2012 at 11:38 PM, Thomas Petazzoni
<thomas.petazzoni@free-electrons.com> wrote:
> Including the core.h header for the pinctrl subsystem is not
> necessary, and it is actually causing problems when moving the
> pinctrl-mvebu drivers into a separate subdirectory.
>
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Applied, thanks!
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH 3/3] pinctrl: mvebu: move to its own directory
From: Linus Walleij @ 2012-10-25 6:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351114738-26793-3-git-send-email-thomas.petazzoni@free-electrons.com>
On Wed, Oct 24, 2012 at 11:38 PM, Thomas Petazzoni
<thomas.petazzoni@free-electrons.com> wrote:
> Like the spear platform, the mvebu platform has multiple files: one
> core file, and then one file per SoC family. More files will be added
> later, as support for mach-orion5x and mach-mv78xx0 SoCs is added to
> pinctrl-mvebu. For those reasons, having a separate subdirectory,
> drivers/pinctrl/mvebu/ makes sense, and it had already been suggested
> by Linus Wallej when the driver was originally submitted.
>
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Thanks, patch applied.
Yours,
Linus Walleij
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox