diff options
Diffstat (limited to 'drivers')
89 files changed, 2685 insertions, 1767 deletions
diff --git a/drivers/Makefile b/drivers/Makefile index c1bf4173793..2618a6169a1 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -36,13 +36,14 @@ obj-$(CONFIG_FB_INTEL) += video/intelfb/ obj-y += serial/ obj-$(CONFIG_PARPORT) += parport/ -obj-y += base/ block/ misc/ mfd/ net/ media/ +obj-y += base/ block/ misc/ mfd/ media/ obj-$(CONFIG_NUBUS) += nubus/ -obj-$(CONFIG_ATM) += atm/ obj-y += macintosh/ obj-$(CONFIG_IDE) += ide/ obj-$(CONFIG_SCSI) += scsi/ obj-$(CONFIG_ATA) += ata/ +obj-y += net/ +obj-$(CONFIG_ATM) += atm/ obj-$(CONFIG_FUSION) += message/ obj-$(CONFIG_FIREWIRE) += firewire/ obj-y += ieee1394/ diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c index e7347db5b6c..b663b7ffae4 100644 --- a/drivers/ata/pata_icside.c +++ b/drivers/ata/pata_icside.c @@ -45,8 +45,6 @@ static const struct portinfo pata_icside_portinfo_v6_2 = { .stepping = 6, }; -#define PATA_ICSIDE_MAX_SG 128 - struct pata_icside_state { void __iomem *irq_port; void __iomem *ioc_base; @@ -57,7 +55,6 @@ struct pata_icside_state { u8 disabled; unsigned int speed[ATA_MAX_DEVICES]; } port[2]; - struct scatterlist sg[PATA_ICSIDE_MAX_SG]; }; struct pata_icside_info { @@ -222,9 +219,7 @@ static void pata_icside_bmdma_setup(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct pata_icside_state *state = ap->host->private_data; - struct scatterlist *sg, *rsg = state->sg; unsigned int write = qc->tf.flags & ATA_TFLAG_WRITE; - unsigned int si; /* * We are simplex; BUG if we try to fiddle with DMA @@ -233,20 +228,12 @@ static void pata_icside_bmdma_setup(struct ata_queued_cmd *qc) BUG_ON(dma_channel_active(state->dma)); /* - * Copy ATAs scattered sg list into a contiguous array of sg - */ - for_each_sg(qc->sg, sg, qc->n_elem, si) { - memcpy(rsg, sg, sizeof(*sg)); - rsg++; - } - - /* * Route the DMA signals to the correct interface */ writeb(state->port[ap->port_no].port_sel, state->ioc_base); set_dma_speed(state->dma, state->port[ap->port_no].speed[qc->dev->devno]); - set_dma_sg(state->dma, state->sg, rsg - state->sg); + set_dma_sg(state->dma, qc->sg, qc->n_elem); set_dma_mode(state->dma, write ? DMA_MODE_WRITE : DMA_MODE_READ); /* issue r/w command */ @@ -306,8 +293,8 @@ static int icside_dma_init(struct pata_icside_info *info) static struct scsi_host_template pata_icside_sht = { ATA_BASE_SHT(DRV_NAME), - .sg_tablesize = PATA_ICSIDE_MAX_SG, - .dma_boundary = ~0, /* no dma boundaries */ + .sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS, + .dma_boundary = IOMD_DMA_BOUNDARY, }; static void pata_icside_postreset(struct ata_link *link, unsigned int *classes) diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c index ba68a4671cb..538313f9e7a 100644 --- a/drivers/char/hw_random/omap-rng.c +++ b/drivers/char/hw_random/omap-rng.c @@ -102,7 +102,7 @@ static int __init omap_rng_probe(struct platform_device *pdev) return -EBUSY; if (cpu_is_omap24xx()) { - rng_ick = clk_get(&pdev->dev, "rng_ick"); + rng_ick = clk_get(&pdev->dev, "ick"); if (IS_ERR(rng_ick)) { dev_err(&pdev->dev, "Could not get rng_ick\n"); ret = PTR_ERR(rng_ick); diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index ae50a9d1a4e..da781d10789 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -1649,7 +1649,7 @@ static int ipu_probe(struct platform_device *pdev) } /* Get IPU clock */ - ipu_data.ipu_clk = clk_get(&pdev->dev, "ipu_clk"); + ipu_data.ipu_clk = clk_get(&pdev->dev, NULL); if (IS_ERR(ipu_data.ipu_clk)) { ret = PTR_ERR(ipu_data.ipu_clk); goto err_clk_get; diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index eb8f72ca02f..d420cc5f563 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -604,9 +604,7 @@ static int i2c_bit_prepare_bus(struct i2c_adapter *adap) /* register new adapter to i2c module... */ adap->algo = &i2c_bit_algo; - - adap->timeout = 100; /* default values, should */ - adap->retries = 3; /* be replaced by defines */ + adap->retries = 3; return 0; } diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index d50b329a3c9..f68e5f8e23e 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c @@ -22,14 +22,18 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/delay.h> +#include <linux/jiffies.h> #include <linux/init.h> #include <linux/errno.h> #include <linux/i2c.h> #include <linux/i2c-algo-pca.h> -#define DEB1(fmt, args...) do { if (i2c_debug>=1) printk(fmt, ## args); } while(0) -#define DEB2(fmt, args...) do { if (i2c_debug>=2) printk(fmt, ## args); } while(0) -#define DEB3(fmt, args...) do { if (i2c_debug>=3) printk(fmt, ## args); } while(0) +#define DEB1(fmt, args...) do { if (i2c_debug >= 1) \ + printk(KERN_DEBUG fmt, ## args); } while (0) +#define DEB2(fmt, args...) do { if (i2c_debug >= 2) \ + printk(KERN_DEBUG fmt, ## args); } while (0) +#define DEB3(fmt, args...) do { if (i2c_debug >= 3) \ + printk(KERN_DEBUG fmt, ## args); } while (0) static int i2c_debug; @@ -43,19 +47,27 @@ static int i2c_debug; #define pca_wait(adap) adap->wait_for_completion(adap->data) #define pca_reset(adap) adap->reset_chip(adap->data) +static void pca9665_reset(void *pd) +{ + struct i2c_algo_pca_data *adap = pd; + pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IPRESET); + pca_outw(adap, I2C_PCA_IND, 0xA5); + pca_outw(adap, I2C_PCA_IND, 0x5A); +} + /* * Generate a start condition on the i2c bus. * * returns after the start condition has occurred */ -static void pca_start(struct i2c_algo_pca_data *adap) +static int pca_start(struct i2c_algo_pca_data *adap) { int sta = pca_get_con(adap); DEB2("=== START\n"); sta |= I2C_PCA_CON_STA; sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_SI); pca_set_con(adap, sta); - pca_wait(adap); + return pca_wait(adap); } /* @@ -63,14 +75,14 @@ static void pca_start(struct i2c_algo_pca_data *adap) * * return after the repeated start condition has occurred */ -static void pca_repeated_start(struct i2c_algo_pca_data *adap) +static int pca_repeated_start(struct i2c_algo_pca_data *adap) { int sta = pca_get_con(adap); DEB2("=== REPEATED START\n"); sta |= I2C_PCA_CON_STA; sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_SI); pca_set_con(adap, sta); - pca_wait(adap); + return pca_wait(adap); } /* @@ -96,7 +108,7 @@ static void pca_stop(struct i2c_algo_pca_data *adap) * * returns after the address has been sent */ -static void pca_address(struct i2c_algo_pca_data *adap, +static int pca_address(struct i2c_algo_pca_data *adap, struct i2c_msg *msg) { int sta = pca_get_con(adap); @@ -113,7 +125,7 @@ static void pca_address(struct i2c_algo_pca_data *adap, sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI); pca_set_con(adap, sta); - pca_wait(adap); + return pca_wait(adap); } /* @@ -121,7 +133,7 @@ static void pca_address(struct i2c_algo_pca_data *adap, * * Returns after the byte has been transmitted */ -static void pca_tx_byte(struct i2c_algo_pca_data *adap, +static int pca_tx_byte(struct i2c_algo_pca_data *adap, __u8 b) { int sta = pca_get_con(adap); @@ -131,7 +143,7 @@ static void pca_tx_byte(struct i2c_algo_pca_data *adap, sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI); pca_set_con(adap, sta); - pca_wait(adap); + return pca_wait(adap); } /* @@ -151,7 +163,7 @@ static void pca_rx_byte(struct i2c_algo_pca_data *adap, * * Returns after next byte has arrived. */ -static void pca_rx_ack(struct i2c_algo_pca_data *adap, +static int pca_rx_ack(struct i2c_algo_pca_data *adap, int ack) { int sta = pca_get_con(adap); @@ -162,7 +174,7 @@ static void pca_rx_ack(struct i2c_algo_pca_data *adap, sta |= I2C_PCA_CON_AA; pca_set_con(adap, sta); - pca_wait(adap); + return pca_wait(adap); } static int pca_xfer(struct i2c_adapter *i2c_adap, @@ -175,14 +187,17 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, int numbytes = 0; int state; int ret; - int timeout = i2c_adap->timeout; - - while ((state = pca_status(adap)) != 0xf8 && timeout--) { - msleep(10); - } - if (state != 0xf8) { - dev_dbg(&i2c_adap->dev, "bus is not idle. status is %#04x\n", state); - return -EAGAIN; + int completed = 1; + unsigned long timeout = jiffies + i2c_adap->timeout; + + while (pca_status(adap) != 0xf8) { + if (time_before(jiffies, timeout)) { + msleep(10); + } else { + dev_dbg(&i2c_adap->dev, "bus is not idle. status is " + "%#04x\n", state); + return -EAGAIN; + } } DEB1("{{{ XFER %d messages\n", num); @@ -218,18 +233,19 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, switch (state) { case 0xf8: /* On reset or stop the bus is idle */ - pca_start(adap); + completed = pca_start(adap); break; case 0x08: /* A START condition has been transmitted */ case 0x10: /* A repeated start condition has been transmitted */ - pca_address(adap, msg); + completed = pca_address(adap, msg); break; case 0x18: /* SLA+W has been transmitted; ACK has been received */ case 0x28: /* Data byte in I2CDAT has been transmitted; ACK has been received */ if (numbytes < msg->len) { - pca_tx_byte(adap, msg->buf[numbytes]); + completed = pca_tx_byte(adap, + msg->buf[numbytes]); numbytes++; break; } @@ -237,7 +253,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, if (curmsg == num) pca_stop(adap); else - pca_repeated_start(adap); + completed = pca_repeated_start(adap); break; case 0x20: /* SLA+W has been transmitted; NOT ACK has been received */ @@ -246,21 +262,22 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, goto out; case 0x40: /* SLA+R has been transmitted; ACK has been received */ - pca_rx_ack(adap, msg->len > 1); + completed = pca_rx_ack(adap, msg->len > 1); break; case 0x50: /* Data bytes has been received; ACK has been returned */ if (numbytes < msg->len) { pca_rx_byte(adap, &msg->buf[numbytes], 1); numbytes++; - pca_rx_ack(adap, numbytes < msg->len - 1); + completed = pca_rx_ack(adap, + numbytes < msg->len - 1); break; } curmsg++; numbytes = 0; if (curmsg == num) pca_stop(adap); else - pca_repeated_start(adap); + completed = pca_repeated_start(adap); break; case 0x48: /* SLA+R has been transmitted; NOT ACK has been received */ @@ -283,7 +300,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, if (curmsg == num) pca_stop(adap); else - pca_repeated_start(adap); + completed = pca_repeated_start(adap); } else { DEB2("NOT ACK sent after data byte received. " "Not final byte. numbytes %d. len %d\n", @@ -309,11 +326,13 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, break; } + if (!completed) + goto out; } ret = curmsg; out: - DEB1(KERN_CRIT "}}} transfered %d/%d messages. " + DEB1("}}} transfered %d/%d messages. " "status is %#04x. control is %#04x\n", curmsg, num, pca_status(adap), pca_get_con(adap)); @@ -330,26 +349,171 @@ static const struct i2c_algorithm pca_algo = { .functionality = pca_func, }; -static int pca_init(struct i2c_adapter *adap) +static unsigned int pca_probe_chip(struct i2c_adapter *adap) { - static int freqs[] = {330,288,217,146,88,59,44,36}; - int clock; struct i2c_algo_pca_data *pca_data = adap->algo_data; - - if (pca_data->i2c_clock > 7) { - printk(KERN_WARNING "%s: Invalid I2C clock speed selected. Trying default.\n", - adap->name); - pca_data->i2c_clock = I2C_PCA_CON_59kHz; + /* The trick here is to check if there is an indirect register + * available. If there is one, we will read the value we first + * wrote on I2C_PCA_IADR. Otherwise, we will read the last value + * we wrote on I2C_PCA_ADR + */ + pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR); + pca_outw(pca_data, I2C_PCA_IND, 0xAA); + pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ITO); + pca_outw(pca_data, I2C_PCA_IND, 0x00); + pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR); + if (pca_inw(pca_data, I2C_PCA_IND) == 0xAA) { + printk(KERN_INFO "%s: PCA9665 detected.\n", adap->name); + return I2C_PCA_CHIP_9665; + } else { + printk(KERN_INFO "%s: PCA9564 detected.\n", adap->name); + return I2C_PCA_CHIP_9564; } +} + +static int pca_init(struct i2c_adapter *adap) +{ + struct i2c_algo_pca_data *pca_data = adap->algo_data; adap->algo = &pca_algo; - pca_reset(pca_data); + if (pca_probe_chip(adap) == I2C_PCA_CHIP_9564) { + static int freqs[] = {330, 288, 217, 146, 88, 59, 44, 36}; + int clock; + + if (pca_data->i2c_clock > 7) { + switch (pca_data->i2c_clock) { + case 330000: + pca_data->i2c_clock = I2C_PCA_CON_330kHz; + break; + case 288000: + pca_data->i2c_clock = I2C_PCA_CON_288kHz; + break; + case 217000: + pca_data->i2c_clock = I2C_PCA_CON_217kHz; + break; + case 146000: + pca_data->i2c_clock = I2C_PCA_CON_146kHz; + break; + case 88000: + pca_data->i2c_clock = I2C_PCA_CON_88kHz; + break; + case 59000: + pca_data->i2c_clock = I2C_PCA_CON_59kHz; + break; + case 44000: + pca_data->i2c_clock = I2C_PCA_CON_44kHz; + break; + case 36000: + pca_data->i2c_clock = I2C_PCA_CON_36kHz; + break; + default: + printk(KERN_WARNING + "%s: Invalid I2C clock speed selected." + " Using default 59kHz.\n", adap->name); + pca_data->i2c_clock = I2C_PCA_CON_59kHz; + } + } else { + printk(KERN_WARNING "%s: " + "Choosing the clock frequency based on " + "index is deprecated." + " Use the nominal frequency.\n", adap->name); + } + + pca_reset(pca_data); + + clock = pca_clock(pca_data); + printk(KERN_INFO "%s: Clock frequency is %dkHz\n", + adap->name, freqs[clock]); + + pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock); + } else { + int clock; + int mode; + int tlow, thi; + /* Values can be found on PCA9665 datasheet section 7.3.2.6 */ + int min_tlow, min_thi; + /* These values are the maximum raise and fall values allowed + * by the I2C operation mode (Standard, Fast or Fast+) + * They are used (added) below to calculate the clock dividers + * of PCA9665. Note that they are slightly different of the + * real maximum, to allow the change on mode exactly on the + * maximum clock rate for each mode + */ + int raise_fall_time; + + struct i2c_algo_pca_data *pca_data = adap->algo_data; + + /* Ignore the reset function from the module, + * we can use the parallel bus reset + */ + pca_data->reset_chip = pca9665_reset; + + if (pca_data->i2c_clock > 1265800) { + printk(KERN_WARNING "%s: I2C clock speed too high." + " Using 1265.8kHz.\n", adap->name); + pca_data->i2c_clock = 1265800; + } + + if (pca_data->i2c_clock < 60300) { + printk(KERN_WARNING "%s: I2C clock speed too low." + " Using 60.3kHz.\n", adap->name); + pca_data->i2c_clock = 60300; + } - clock = pca_clock(pca_data); - DEB1(KERN_INFO "%s: Clock frequency is %dkHz\n", adap->name, freqs[clock]); + /* To avoid integer overflow, use clock/100 for calculations */ + clock = pca_clock(pca_data) / 100; + + if (pca_data->i2c_clock > 10000) { + mode = I2C_PCA_MODE_TURBO; + min_tlow = 14; + min_thi = 5; + raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ + } else if (pca_data->i2c_clock > 4000) { + mode = I2C_PCA_MODE_FASTP; + min_tlow = 17; + min_thi = 9; + raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ + } else if (pca_data->i2c_clock > 1000) { + mode = I2C_PCA_MODE_FAST; + min_tlow = 44; + min_thi = 20; + raise_fall_time = 58; /* Raise 29e-8s, Fall 29e-8s */ + } else { + mode = I2C_PCA_MODE_STD; + min_tlow = 157; + min_thi = 134; + raise_fall_time = 127; /* Raise 29e-8s, Fall 98e-8s */ + } + + /* The minimum clock that respects the thi/tlow = 134/157 is + * 64800 Hz. Below that, we have to fix the tlow to 255 and + * calculate the thi factor. + */ + if (clock < 648) { + tlow = 255; + thi = 1000000 - clock * raise_fall_time; + thi /= (I2C_PCA_OSC_PER * clock) - tlow; + } else { + tlow = (1000000 - clock * raise_fall_time) * min_tlow; + tlow /= I2C_PCA_OSC_PER * clock * (min_thi + min_tlow); + thi = tlow * min_thi / min_tlow; + } - pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock); + pca_reset(pca_data); + + printk(KERN_INFO + "%s: Clock frequency is %dHz\n", adap->name, clock * 100); + + pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IMODE); + pca_outw(pca_data, I2C_PCA_IND, mode); + pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLL); + pca_outw(pca_data, I2C_PCA_IND, tlow); + pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLH); + pca_outw(pca_data, I2C_PCA_IND, thi); + + pca_set_con(pca_data, I2C_PCA_CON_ENSIO); + } udelay(500); /* 500 us for oscilator to stabilise */ return 0; @@ -384,7 +548,7 @@ EXPORT_SYMBOL(i2c_pca_add_numbered_bus); MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>, " "Wolfram Sang <w.sang@pengutronix.de>"); -MODULE_DESCRIPTION("I2C-Bus PCA9564 algorithm"); +MODULE_DESCRIPTION("I2C-Bus PCA9564/PCA9665 algorithm"); MODULE_LICENSE("GPL"); module_param(i2c_debug, int, 0); diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c index 3e01992230b..7ce75775ec7 100644 --- a/drivers/i2c/algos/i2c-algo-pcf.c +++ b/drivers/i2c/algos/i2c-algo-pcf.c @@ -1,31 +1,30 @@ -/* ------------------------------------------------------------------------- */ -/* i2c-algo-pcf.c i2c driver algorithms for PCF8584 adapters */ -/* ------------------------------------------------------------------------- */ -/* Copyright (C) 1995-1997 Simon G. Vogl - 1998-2000 Hans Berglund - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* ------------------------------------------------------------------------- */ - -/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and - Frodo Looijaard <frodol@dds.nl> ,and also from Martin Bailey - <mbailey@littlefeet-inc.com> */ - -/* Partially rewriten by Oleg I. Vdovikin <vdovikin@jscc.ru> to handle multiple - messages, proper stop/repstart signaling during receive, - added detect code */ +/* + * i2c-algo-pcf.c i2c driver algorithms for PCF8584 adapters + * + * Copyright (C) 1995-1997 Simon G. Vogl + * 1998-2000 Hans Berglund + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and + * Frodo Looijaard <frodol@dds.nl>, and also from Martin Bailey + * <mbailey@littlefeet-inc.com> + * + * Partially rewriten by Oleg I. Vdovikin <vdovikin@jscc.ru> to handle multiple + * messages, proper stop/repstart signaling during receive, added detect code + */ #include <linux/kernel.h> #include <linux/module.h> @@ -38,17 +37,18 @@ #include "i2c-algo-pcf.h" -#define DEB2(x) if (i2c_debug>=2) x -#define DEB3(x) if (i2c_debug>=3) x /* print several statistical values*/ -#define DEBPROTO(x) if (i2c_debug>=9) x; - /* debug the protocol by showing transferred bits */ +#define DEB2(x) if (i2c_debug >= 2) x +#define DEB3(x) if (i2c_debug >= 3) x /* print several statistical values */ +#define DEBPROTO(x) if (i2c_debug >= 9) x; + /* debug the protocol by showing transferred bits */ #define DEF_TIMEOUT 16 -/* module parameters: +/* + * module parameters: */ static int i2c_debug; -/* --- setting states on the bus with the right timing: --------------- */ +/* setting states on the bus with the right timing: */ #define set_pcf(adap, ctl, val) adap->setpcf(adap->data, ctl, val) #define get_pcf(adap, ctl) adap->getpcf(adap->data, ctl) @@ -57,22 +57,21 @@ static int i2c_debug; #define i2c_outb(adap, val) adap->setpcf(adap->data, 0, val) #define i2c_inb(adap) adap->getpcf(adap->data, 0) -/* --- other auxiliary functions -------------------------------------- */ +/* other auxiliary functions */ -static void i2c_start(struct i2c_algo_pcf_data *adap) +static void i2c_start(struct i2c_algo_pcf_data *adap) { - DEBPROTO(printk("S ")); + DEBPROTO(printk(KERN_DEBUG "S ")); set_pcf(adap, 1, I2C_PCF_START); } -static void i2c_repstart(struct i2c_algo_pcf_data *adap) +static void i2c_repstart(struct i2c_algo_pcf_data *adap) { DEBPROTO(printk(" Sr ")); set_pcf(adap, 1, I2C_PCF_REPSTART); } - -static void i2c_stop(struct i2c_algo_pcf_data *adap) +static void i2c_stop(struct i2c_algo_pcf_data *adap) { DEBPROTO(printk("P\n")); set_pcf(adap, 1, I2C_PCF_STOP); @@ -82,17 +81,17 @@ static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status) { DEB2(printk(KERN_INFO "i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n", - *status)); - - /* Cleanup from LAB -- reset and enable ESO. + *status)); + /* + * Cleanup from LAB -- reset and enable ESO. * This resets the PCF8584; since we've lost the bus, no * further attempts should be made by callers to clean up * (no i2c_stop() etc.) */ set_pcf(adap, 1, I2C_PCF_PIN); set_pcf(adap, 1, I2C_PCF_ESO); - - /* We pause for a time period sufficient for any running + /* + * We pause for a time period sufficient for any running * I2C transaction to complete -- the arbitration logic won't * work properly until the next START is seen. * It is assumed the bus driver or client has set a proper value. @@ -108,48 +107,50 @@ static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status) get_pcf(adap, 1))); } -static int wait_for_bb(struct i2c_algo_pcf_data *adap) { +static int wait_for_bb(struct i2c_algo_pcf_data *adap) +{ int timeout = DEF_TIMEOUT; int status; status = get_pcf(adap, 1); -#ifndef STUB_I2C - while (timeout-- && !(status & I2C_PCF_BB)) { + + while (!(status & I2C_PCF_BB) && --timeout) { udelay(100); /* wait for 100 us */ status = get_pcf(adap, 1); } -#endif - if (timeout <= 0) { + + if (timeout == 0) { printk(KERN_ERR "Timeout waiting for Bus Busy\n"); + return -ETIMEDOUT; } - - return (timeout<=0); -} + return 0; +} -static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) { +static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) +{ int timeout = DEF_TIMEOUT; *status = get_pcf(adap, 1); -#ifndef STUB_I2C - while (timeout-- && (*status & I2C_PCF_PIN)) { + + while ((*status & I2C_PCF_PIN) && --timeout) { adap->waitforpin(adap->data); *status = get_pcf(adap, 1); } if (*status & I2C_PCF_LAB) { handle_lab(adap, status); - return(-EINTR); + return -EINTR; } -#endif - if (timeout <= 0) - return(-1); - else - return(0); + + if (timeout == 0) + return -ETIMEDOUT; + + return 0; } -/* +/* * This should perform the 'PCF8584 initialization sequence' as described * in the Philips IC12 data book (1995, Aug 29). * There should be a 30 clock cycle wait after reset, I assume this @@ -164,18 +165,21 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) { unsigned char temp; - DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n", get_pcf(adap, 1))); + DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n", + get_pcf(adap, 1))); /* S1=0x80: S0 selected, serial interface off */ set_pcf(adap, 1, I2C_PCF_PIN); - /* check to see S1 now used as R/W ctrl - - PCF8584 does that when ESO is zero */ + /* + * check to see S1 now used as R/W ctrl - + * PCF8584 does that when ESO is zero + */ if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) { DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp)); return -ENXIO; /* definetly not PCF8584 */ } - /* load own address in S0, effective address is (own << 1) */ + /* load own address in S0, effective address is (own << 1) */ i2c_outb(adap, get_own(adap)); /* check it's really written */ if ((temp = i2c_inb(adap)) != get_own(adap)) { @@ -183,7 +187,7 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) return -ENXIO; } - /* S1=0xA0, next byte in S2 */ + /* S1=0xA0, next byte in S2 */ set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1); /* check to see S2 now selected */ if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) { @@ -191,7 +195,7 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) return -ENXIO; } - /* load clock register S2 */ + /* load clock register S2 */ i2c_outb(adap, get_clock(adap)); /* check it's really written, the only 5 lowest bits does matter */ if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) { @@ -199,7 +203,7 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) return -ENXIO; } - /* Enable serial interface, idle, S0 selected */ + /* Enable serial interface, idle, S0 selected */ set_pcf(adap, 1, I2C_PCF_IDLE); /* check to see PCF is really idled and we can access status register */ @@ -207,57 +211,47 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp)); return -ENXIO; } - + printk(KERN_DEBUG "i2c-algo-pcf.o: detected and initialized PCF8584.\n"); return 0; } - -/* ----- Utility functions - */ - static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf, - int count, int last) + int count, int last) { struct i2c_algo_pcf_data *adap = i2c_adap->algo_data; int wrcount, status, timeout; - + for (wrcount=0; wrcount<count; ++wrcount) { DEB2(dev_dbg(&i2c_adap->dev, "i2c_write: writing %2.2X\n", - buf[wrcount]&0xff)); + buf[wrcount] & 0xff)); i2c_outb(adap, buf[wrcount]); timeout = wait_for_pin(adap, &status); if (timeout) { - if (timeout == -EINTR) { - /* arbitration lost */ - return -EINTR; - } + if (timeout == -EINTR) + return -EINTR; /* arbitration lost */ + i2c_stop(adap); dev_err(&i2c_adap->dev, "i2c_write: error - timeout.\n"); return -EREMOTEIO; /* got a better one ?? */ } -#ifndef STUB_I2C if (status & I2C_PCF_LRB) { i2c_stop(adap); dev_err(&i2c_adap->dev, "i2c_write: error - no ack.\n"); return -EREMOTEIO; /* got a better one ?? */ } -#endif } - if (last) { + if (last) i2c_stop(adap); - } - else { + else i2c_repstart(adap); - } - return (wrcount); + return wrcount; } - static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf, - int count, int last) + int count, int last) { int i, status; struct i2c_algo_pcf_data *adap = i2c_adap->algo_data; @@ -267,42 +261,36 @@ static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf, for (i = 0; i <= count; i++) { if ((wfp = wait_for_pin(adap, &status))) { - if (wfp == -EINTR) { - /* arbitration lost */ - return -EINTR; - } + if (wfp == -EINTR) + return -EINTR; /* arbitration lost */ + i2c_stop(adap); dev_err(&i2c_adap->dev, "pcf_readbytes timed out.\n"); - return (-1); + return -1; } -#ifndef STUB_I2C if ((status & I2C_PCF_LRB) && (i != count)) { i2c_stop(adap); dev_err(&i2c_adap->dev, "i2c_read: i2c_inb, No ack.\n"); - return (-1); + return -1; } -#endif - + if (i == count - 1) { set_pcf(adap, 1, I2C_PCF_ESO); - } else - if (i == count) { - if (last) { + } else if (i == count) { + if (last) i2c_stop(adap); - } else { + else i2c_repstart(adap); - } - }; + } - if (i) { + if (i) buf[i - 1] = i2c_inb(adap); - } else { + else i2c_inb(adap); /* dummy read */ - } } - return (i - 1); + return i - 1; } @@ -323,14 +311,14 @@ static int pcf_doAddress(struct i2c_algo_pcf_data *adap, } static int pcf_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg *msgs, + struct i2c_msg *msgs, int num) { struct i2c_algo_pcf_data *adap = i2c_adap->algo_data; struct i2c_msg *pmsg; int i; int ret=0, timeout, status; - + if (adap->xfer_begin) adap->xfer_begin(adap->data); @@ -338,25 +326,24 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, timeout = wait_for_bb(adap); if (timeout) { DEB2(printk(KERN_ERR "i2c-algo-pcf.o: " - "Timeout waiting for BB in pcf_xfer\n");) + "Timeout waiting for BB in pcf_xfer\n");) i = -EIO; goto out; } - + for (i = 0;ret >= 0 && i < num; i++) { pmsg = &msgs[i]; DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n", pmsg->flags & I2C_M_RD ? "read" : "write", - pmsg->len, pmsg->addr, i + 1, num);) - + pmsg->len, pmsg->addr, i + 1, num);) + ret = pcf_doAddress(adap, pmsg); /* Send START */ - if (i == 0) { - i2c_start(adap); - } - + if (i == 0) + i2c_start(adap); + /* Wait for PIN (pending interrupt NOT) */ timeout = wait_for_pin(adap, &status); if (timeout) { @@ -371,8 +358,7 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, i = -EREMOTEIO; goto out; } - -#ifndef STUB_I2C + /* Check LRB (last rcvd bit - slave ack) */ if (status & I2C_PCF_LRB) { i2c_stop(adap); @@ -380,27 +366,24 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, i = -EREMOTEIO; goto out; } -#endif - + DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n", i, msgs[i].addr, msgs[i].flags, msgs[i].len);) - - /* Read */ + if (pmsg->flags & I2C_M_RD) { - /* read bytes into buffer*/ ret = pcf_readbytes(i2c_adap, pmsg->buf, pmsg->len, - (i + 1 == num)); - + (i + 1 == num)); + if (ret != pmsg->len) { DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: " "only read %d bytes.\n",ret)); } else { DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: read %d bytes.\n",ret)); } - } else { /* Write */ + } else { ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len, - (i + 1 == num)); - + (i + 1 == num)); + if (ret != pmsg->len) { DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: " "only wrote %d bytes.\n",ret)); @@ -413,24 +396,23 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, out: if (adap->xfer_end) adap->xfer_end(adap->data); - return (i); + return i; } static u32 pcf_func(struct i2c_adapter *adap) { - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING; } -/* -----exported algorithm data: ------------------------------------- */ - +/* exported algorithm data: */ static const struct i2c_algorithm pcf_algo = { .master_xfer = pcf_xfer, .functionality = pcf_func, }; -/* - * registering functions to load algorithms at runtime +/* + * registering functions to load algorithms at runtime */ int i2c_pcf_add_bus(struct i2c_adapter *adap) { @@ -441,7 +423,6 @@ int i2c_pcf_add_bus(struct i2c_adapter *adap) /* register new adapter to i2c module... */ adap->algo = &pcf_algo; - adap->timeout = 100; if ((rval = pcf_init_8584(pcf_adap))) return rval; @@ -458,4 +439,4 @@ MODULE_LICENSE("GPL"); module_param(i2c_debug, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(i2c_debug, - "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol"); + "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol"); diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 7f95905bbb9..da809ad0996 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -132,6 +132,7 @@ config I2C_PIIX4 Serverworks CSB5 Serverworks CSB6 Serverworks HT-1000 + Serverworks HT-1100 SMSC Victory66 This driver can also be built as a module. If so, the module @@ -617,12 +618,12 @@ config I2C_ELEKTOR will be called i2c-elektor. config I2C_PCA_ISA - tristate "PCA9564 on an ISA bus" + tristate "PCA9564/PCA9665 on an ISA bus" depends on ISA select I2C_ALGOPCA default n help - This driver supports ISA boards using the Philips PCA9564 + This driver supports ISA boards using the Philips PCA9564/PCA9665 parallel bus to I2C bus controller. This driver can also be built as a module. If so, the module @@ -634,11 +635,11 @@ config I2C_PCA_ISA time). If unsure, say N. config I2C_PCA_PLATFORM - tristate "PCA9564 as platform device" + tristate "PCA9564/PCA9665 as platform device" select I2C_ALGOPCA default n help - This driver supports a memory mapped Philips PCA9564 + This driver supports a memory mapped Philips PCA9564/PCA9665 parallel bus to I2C bus controller. This driver can also be built as a module. If so, the module diff --git a/drivers/i2c/busses/i2c-acorn.c b/drivers/i2c/busses/i2c-acorn.c index 9aefb5e5864..86796488ef4 100644 --- a/drivers/i2c/busses/i2c-acorn.c +++ b/drivers/i2c/busses/i2c-acorn.c @@ -15,9 +15,9 @@ #include <linux/init.h> #include <linux/i2c.h> #include <linux/i2c-algo-bit.h> +#include <linux/io.h> #include <mach/hardware.h> -#include <asm/io.h> #include <asm/hardware/ioc.h> #include <asm/system.h> diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 5d7789834b9..3fae3a91ce5 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -216,7 +216,7 @@ static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev, { unsigned long timeout; - timeout = jiffies + DAVINCI_I2C_TIMEOUT; + timeout = jiffies + dev->adapter.timeout; while (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG) & DAVINCI_I2C_STR_BB) { if (time_after(jiffies, timeout)) { @@ -289,7 +289,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, - DAVINCI_I2C_TIMEOUT); + dev->adapter.timeout); if (r == 0) { dev_err(dev->dev, "controller timed out\n"); i2c_davinci_init(dev); @@ -546,9 +546,7 @@ static int davinci_i2c_probe(struct platform_device *pdev) strlcpy(adap->name, "DaVinci I2C adapter", sizeof(adap->name)); adap->algo = &i2c_davinci_algo; adap->dev.parent = &pdev->dev; - - /* FIXME */ - adap->timeout = 1; + adap->timeout = DAVINCI_I2C_TIMEOUT; adap->nr = pdev->id; r = i2c_add_numbered_adapter(adap); diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index 88f0db73b36..8b92a4666e0 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -415,7 +415,7 @@ static int iic_wait_for_tc(struct ibm_iic_private* dev){ if (dev->irq >= 0){ /* Interrupt mode */ ret = wait_event_interruptible_timeout(dev->wq, - !(in_8(&iic->sts) & STS_PT), dev->adap.timeout * HZ); + !(in_8(&iic->sts) & STS_PT), dev->adap.timeout); if (unlikely(ret < 0)) DBG("%d: wait interrupted\n", dev->idx); @@ -426,7 +426,7 @@ static int iic_wait_for_tc(struct ibm_iic_private* dev){ } else { /* Polling mode */ - unsigned long x = jiffies + dev->adap.timeout * HZ; + unsigned long x = jiffies + dev->adap.timeout; while (in_8(&iic->sts) & STS_PT){ if (unlikely(time_after(jiffies, x))){ @@ -748,7 +748,7 @@ static int __devinit iic_probe(struct of_device *ofdev, i2c_set_adapdata(adap, dev); adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; adap->algo = &iic_algo; - adap->timeout = 1; + adap->timeout = HZ; ret = i2c_add_adapter(adap); if (ret < 0) { diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index 3190690c26c..a75c75e77b9 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c @@ -488,7 +488,7 @@ iop3xx_i2c_probe(struct platform_device *pdev) /* * Default values...should these come in from board code? */ - new_adapter->timeout = 100; + new_adapter->timeout = HZ; new_adapter->algo = &iop3xx_i2c_algo; init_waitqueue_head(&adapter_data->waitq); diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index aedbbe6618d..2b847d87594 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -116,7 +116,7 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) } else { /* Interrupt mode */ result = wait_event_interruptible_timeout(i2c->queue, - (i2c->interrupt & CSR_MIF), timeout * HZ); + (i2c->interrupt & CSR_MIF), timeout); if (unlikely(result < 0)) { pr_debug("I2C: wait interrupted\n"); @@ -311,7 +311,7 @@ static struct i2c_adapter mpc_ops = { .owner = THIS_MODULE, .name = "MPC adapter", .algo = &mpc_algo, - .timeout = 1, + .timeout = HZ, }; static int __devinit fsl_i2c_probe(struct of_device *op, const struct of_device_id *match) diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index 7f186bbcb99..5a4945d1dba 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -358,7 +358,7 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data) char abort = 0; time_left = wait_event_interruptible_timeout(drv_data->waitq, - !drv_data->block, msecs_to_jiffies(drv_data->adapter.timeout)); + !drv_data->block, drv_data->adapter.timeout); spin_lock_irqsave(&drv_data->lock, flags); if (!time_left) { /* Timed out */ @@ -374,8 +374,7 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data) spin_unlock_irqrestore(&drv_data->lock, flags); time_left = wait_event_timeout(drv_data->waitq, - !drv_data->block, - msecs_to_jiffies(drv_data->adapter.timeout)); + !drv_data->block, drv_data->adapter.timeout); if ((time_left <= 0) && drv_data->block) { drv_data->state = MV64XXX_I2C_STATE_IDLE; @@ -530,7 +529,7 @@ mv64xxx_i2c_probe(struct platform_device *pd) drv_data->adapter.algo = &mv64xxx_i2c_algo; drv_data->adapter.owner = THIS_MODULE; drv_data->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD; - drv_data->adapter.timeout = pdata->timeout; + drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout); drv_data->adapter.nr = pd->id; platform_set_drvdata(pd, drv_data); i2c_set_adapdata(&drv_data->adapter, drv_data); diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index 05af6cd7f27..2ff4683703a 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c @@ -31,10 +31,14 @@ nForce3 250Gb MCP 00E4 nForce4 MCP 0052 nForce4 MCP-04 0034 - nForce4 MCP51 0264 - nForce4 MCP55 0368 + nForce MCP51 0264 + nForce MCP55 0368 nForce MCP61 03EB nForce MCP65 0446 + nForce MCP67 0542 + nForce MCP73 07D8 + nForce MCP78S 0752 + nForce MCP79 0AA2 This driver supports the 2 SMBuses that are included in the MCP of the nForce2/3/4/5xx chipsets. @@ -315,6 +319,10 @@ static struct pci_device_id nforce2_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP78S_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP79_SMBUS) }, { 0 } }; diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index be8ee2cac8b..ece0125a1ee 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -193,22 +193,24 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg) static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev) { - if (cpu_is_omap16xx() || cpu_class_is_omap2()) { - dev->iclk = clk_get(dev->dev, "i2c_ick"); - if (IS_ERR(dev->iclk)) { - dev->iclk = NULL; - return -ENODEV; - } + int ret; + + dev->iclk = clk_get(dev->dev, "ick"); + if (IS_ERR(dev->iclk)) { + ret = PTR_ERR(dev->iclk); + dev->iclk = NULL; + return ret; } - dev->fclk = clk_get(dev->dev, "i2c_fck"); + dev->fclk = clk_get(dev->dev, "fck"); if (IS_ERR(dev->fclk)) { + ret = PTR_ERR(dev->fclk); if (dev->iclk != NULL) { clk_put(dev->iclk); dev->iclk = NULL; } dev->fclk = NULL; - return -ENODEV; + return ret; } return 0; @@ -218,18 +220,15 @@ static void omap_i2c_put_clocks(struct omap_i2c_dev *dev) { clk_put(dev->fclk); dev->fclk = NULL; - if (dev->iclk != NULL) { - clk_put(dev->iclk); - dev->iclk = NULL; - } + clk_put(dev->iclk); + dev->iclk = NULL; } static void omap_i2c_unidle(struct omap_i2c_dev *dev) { WARN_ON(!dev->idle); - if (dev->iclk != NULL) - clk_enable(dev->iclk); + clk_enable(dev->iclk); clk_enable(dev->fclk); dev->idle = 0; if (dev->iestate) @@ -254,8 +253,7 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev) } dev->idle = 1; clk_disable(dev->fclk); - if (dev->iclk != NULL) - clk_disable(dev->iclk); + clk_disable(dev->iclk); } static int omap_i2c_init(struct omap_i2c_dev *dev) @@ -312,15 +310,14 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); if (cpu_class_is_omap1()) { - struct clk *armxor_ck; - - armxor_ck = clk_get(NULL, "armxor_ck"); - if (IS_ERR(armxor_ck)) - dev_warn(dev->dev, "Could not get armxor_ck\n"); - else { - fclk_rate = clk_get_rate(armxor_ck); - clk_put(armxor_ck); - } + /* + * The I2C functional clock is the armxor_ck, so there's + * no need to get "armxor_ck" separately. Now, if OMAP2420 + * always returns 12MHz for the functional clock, we can + * do this bit unconditionally. + */ + fclk_rate = clk_get_rate(dev->fclk); + /* TRM for 5912 says the I2C clock must be prescaled to be * between 7 - 12 MHz. The XOR input clock is typically * 12, 13 or 19.2 MHz. So we should have code that produces: diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c index 4aa8138cb0a..0ed68e2ccd2 100644 --- a/drivers/i2c/busses/i2c-pca-isa.c +++ b/drivers/i2c/busses/i2c-pca-isa.c @@ -23,6 +23,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/delay.h> +#include <linux/jiffies.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/wait.h> @@ -41,15 +42,17 @@ static int irq = -1; /* Data sheet recommends 59kHz for 100kHz operation due to variation * in the actual clock rate */ -static int clock = I2C_PCA_CON_59kHz; +static int clock = 59000; +static struct i2c_adapter pca_isa_ops; static wait_queue_head_t pca_wait; static void pca_isa_writebyte(void *pd, int reg, int val) { #ifdef DEBUG_IO static char *names[] = { "T/O", "DAT", "ADR", "CON" }; - printk("*** write %s at %#lx <= %#04x\n", names[reg], base+reg, val); + printk(KERN_DEBUG "*** write %s at %#lx <= %#04x\n", names[reg], + base+reg, val); #endif outb(val, base+reg); } @@ -60,7 +63,7 @@ static int pca_isa_readbyte(void *pd, int reg) #ifdef DEBUG_IO { static char *names[] = { "STA", "DAT", "ADR", "CON" }; - printk("*** read %s => %#04x\n", names[reg], res); + printk(KERN_DEBUG "*** read %s => %#04x\n", names[reg], res); } #endif return res; @@ -68,16 +71,22 @@ static int pca_isa_readbyte(void *pd, int reg) static int pca_isa_waitforcompletion(void *pd) { - int ret = 0; + long ret = ~0; + unsigned long timeout; if (irq > -1) { - ret = wait_event_interruptible(pca_wait, - pca_isa_readbyte(pd, I2C_PCA_CON) & I2C_PCA_CON_SI); + ret = wait_event_interruptible_timeout(pca_wait, + pca_isa_readbyte(pd, I2C_PCA_CON) + & I2C_PCA_CON_SI, pca_isa_ops.timeout); } else { - while ((pca_isa_readbyte(pd, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0) + /* Do polling */ + timeout = jiffies + pca_isa_ops.timeout; + while (((pca_isa_readbyte(pd, I2C_PCA_CON) + & I2C_PCA_CON_SI) == 0) + && (ret = time_before(jiffies, timeout))) udelay(100); } - return ret; + return ret > 0; } static void pca_isa_resetchip(void *pd) @@ -102,8 +111,8 @@ static struct i2c_algo_pca_data pca_isa_data = { static struct i2c_adapter pca_isa_ops = { .owner = THIS_MODULE, .algo_data = &pca_isa_data, - .name = "PCA9564 ISA Adapter", - .timeout = 100, + .name = "PCA9564/PCA9665 ISA Adapter", + .timeout = HZ, }; static int __devinit pca_isa_match(struct device *dev, unsigned int id) @@ -195,7 +204,7 @@ static void __exit pca_isa_exit(void) } MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>"); -MODULE_DESCRIPTION("ISA base PCA9564 driver"); +MODULE_DESCRIPTION("ISA base PCA9564/PCA9665 driver"); MODULE_LICENSE("GPL"); module_param(base, ulong, 0); @@ -204,7 +213,13 @@ MODULE_PARM_DESC(base, "I/O base address"); module_param(irq, int, 0); MODULE_PARM_DESC(irq, "IRQ"); module_param(clock, int, 0); -MODULE_PARM_DESC(clock, "Clock rate as described in table 1 of PCA9564 datasheet"); +MODULE_PARM_DESC(clock, "Clock rate in hertz.\n\t\t" + "For PCA9564: 330000,288000,217000,146000," + "88000,59000,44000,36000\n" + "\t\tFor PCA9665:\tStandard: 60300 - 100099\n" + "\t\t\t\tFast: 100100 - 400099\n" + "\t\t\t\tFast+: 400100 - 10000099\n" + "\t\t\t\tTurbo: Up to 1265800"); module_init(pca_isa_init); module_exit(pca_isa_exit); diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c index 6bb15ad0a6b..7b23891b7d5 100644 --- a/drivers/i2c/busses/i2c-pca-platform.c +++ b/drivers/i2c/busses/i2c-pca-platform.c @@ -15,6 +15,7 @@ #include <linux/init.h> #include <linux/slab.h> #include <linux/delay.h> +#include <linux/jiffies.h> #include <linux/errno.h> #include <linux/i2c.h> #include <linux/interrupt.h> @@ -81,24 +82,23 @@ static void i2c_pca_pf_writebyte32(void *pd, int reg, int val) static int i2c_pca_pf_waitforcompletion(void *pd) { struct i2c_pca_pf_data *i2c = pd; - int ret = 0; + long ret = ~0; + unsigned long timeout; if (i2c->irq) { - ret = wait_event_interruptible(i2c->wait, + ret = wait_event_interruptible_timeout(i2c->wait, i2c->algo_data.read_byte(i2c, I2C_PCA_CON) - & I2C_PCA_CON_SI); + & I2C_PCA_CON_SI, i2c->adap.timeout); } else { - /* - * Do polling... - * XXX: Could get stuck in extreme cases! - * Maybe add timeout, but using irqs is preferred anyhow. - */ - while ((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) + /* Do polling */ + timeout = jiffies + i2c->adap.timeout; + while (((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0) + && (ret = time_before(jiffies, timeout))) udelay(100); } - return ret; + return ret > 0; } static void i2c_pca_pf_dummyreset(void *pd) @@ -172,14 +172,25 @@ static int __devinit i2c_pca_pf_probe(struct platform_device *pdev) i2c->adap.nr = pdev->id >= 0 ? pdev->id : 0; i2c->adap.owner = THIS_MODULE; - snprintf(i2c->adap.name, sizeof(i2c->adap.name), "PCA9564 at 0x%08lx", - (unsigned long) res->start); + snprintf(i2c->adap.name, sizeof(i2c->adap.name), + "PCA9564/PCA9665 at 0x%08lx", + (unsigned long) res->start); i2c->adap.algo_data = &i2c->algo_data; i2c->adap.dev.parent = &pdev->dev; - i2c->adap.timeout = platform_data->timeout; - i2c->algo_data.i2c_clock = platform_data->i2c_clock_speed; + if (platform_data) { + i2c->adap.timeout = platform_data->timeout; + i2c->algo_data.i2c_clock = platform_data->i2c_clock_speed; + i2c->gpio = platform_data->gpio; + } else { + i2c->adap.timeout = HZ; + i2c->algo_data.i2c_clock = 59000; + i2c->gpio = -1; + } + i2c->algo_data.data = i2c; + i2c->algo_data.wait_for_completion = i2c_pca_pf_waitforcompletion; + i2c->algo_data.reset_chip = i2c_pca_pf_dummyreset; switch (res->flags & IORESOURCE_MEM_TYPE_MASK) { case IORESOURCE_MEM_32BIT: @@ -197,11 +208,6 @@ static int __devinit i2c_pca_pf_probe(struct platform_device *pdev) break; } - i2c->algo_data.wait_for_completion = i2c_pca_pf_waitforcompletion; - - i2c->gpio = platform_data->gpio; - i2c->algo_data.reset_chip = i2c_pca_pf_dummyreset; - /* Use gpio_is_valid() when in mainline */ if (i2c->gpio > -1) { ret = gpio_request(i2c->gpio, i2c->adap.name); @@ -246,7 +252,7 @@ e_remap: e_alloc: release_mem_region(res->start, res_len(res)); e_print: - printk(KERN_ERR "Registering PCA9564 FAILED! (%d)\n", ret); + printk(KERN_ERR "Registering PCA9564/PCA9665 FAILED! (%d)\n", ret); return ret; } @@ -290,7 +296,7 @@ static void __exit i2c_pca_pf_exit(void) } MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>"); -MODULE_DESCRIPTION("I2C-PCA9564 platform driver"); +MODULE_DESCRIPTION("I2C-PCA9564/PCA9665 platform driver"); MODULE_LICENSE("GPL"); module_init(i2c_pca_pf_init); diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 761f9dd5362..0249a7d762b 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -20,7 +20,7 @@ /* Supports: Intel PIIX4, 440MX - Serverworks OSB4, CSB5, CSB6, HT-1000 + Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100 ATI IXP200, IXP300, IXP400, SB600, SB700, SB800 SMSC Victory66 @@ -226,6 +226,70 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, return 0; } +static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev, + const struct pci_device_id *id) +{ + unsigned short smba_idx = 0xcd6; + u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en = 0x2c; + + /* SB800 SMBus does not support forcing address */ + if (force || force_addr) { + dev_err(&PIIX4_dev->dev, "SB800 SMBus does not support " + "forcing address!\n"); + return -EINVAL; + } + + /* Determine the address of the SMBus areas */ + if (!request_region(smba_idx, 2, "smba_idx")) { + dev_err(&PIIX4_dev->dev, "SMBus base address index region " + "0x%x already in use!\n", smba_idx); + return -EBUSY; + } + outb_p(smb_en, smba_idx); + smba_en_lo = inb_p(smba_idx + 1); + outb_p(smb_en + 1, smba_idx); + smba_en_hi = inb_p(smba_idx + 1); + release_region(smba_idx, 2); + + if ((smba_en_lo & 1) == 0) { + dev_err(&PIIX4_dev->dev, + "Host SMBus controller not enabled!\n"); + return -ENODEV; + } + + piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0; + if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) + return -EBUSY; + + if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) { + dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n", + piix4_smba); + return -EBUSY; + } + + /* Request the SMBus I2C bus config region */ + if (!request_region(piix4_smba + i2ccfg_offset, 1, "i2ccfg")) { + dev_err(&PIIX4_dev->dev, "SMBus I2C bus config region " + "0x%x already in use!\n", piix4_smba + i2ccfg_offset); + release_region(piix4_smba, SMBIOSIZE); + piix4_smba = 0; + return -EBUSY; + } + i2ccfg = inb_p(piix4_smba + i2ccfg_offset); + release_region(piix4_smba + i2ccfg_offset, 1); + + if (i2ccfg & 1) + dev_dbg(&PIIX4_dev->dev, "Using IRQ for SMBus.\n"); + else + dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus.\n"); + + dev_info(&PIIX4_dev->dev, + "SMBus Host Controller at 0x%x, revision %d\n", + piix4_smba, i2ccfg >> 4); + + return 0; +} + static int piix4_transaction(void) { int temp; @@ -423,6 +487,8 @@ static struct pci_device_id piix4_ids[] = { PCI_DEVICE_ID_SERVERWORKS_CSB6) }, { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000SB) }, + { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, + PCI_DEVICE_ID_SERVERWORKS_HT1100LD) }, { 0, } }; @@ -433,7 +499,14 @@ static int __devinit piix4_probe(struct pci_dev *dev, { int retval; - retval = piix4_setup(dev, id); + if ((dev->vendor == PCI_VENDOR_ID_ATI) && + (dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS) && + (dev->revision >= 0x40)) + /* base address location etc changed in SB800 */ + retval = piix4_setup_sb800(dev, id); + else + retval = piix4_setup(dev, id); + if (retval) return retval; diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c index 60ca91745e5..3c9d71f6018 100644 --- a/drivers/i2c/busses/i2c-powermac.c +++ b/drivers/i2c/busses/i2c-powermac.c @@ -191,7 +191,8 @@ static int __devexit i2c_powermac_remove(struct platform_device *dev) i2c_set_adapdata(adapter, NULL); /* We aren't that prepared to deal with this... */ if (rc) - printk("i2c-powermac.c: Failed to remove bus %s !\n", + printk(KERN_WARNING + "i2c-powermac.c: Failed to remove bus %s !\n", adapter->name); platform_set_drvdata(dev, NULL); kfree(adapter); diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index bdb1f7510e9..c1405c8f6ba 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -210,11 +210,12 @@ static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id); static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why) { unsigned int i; - printk("i2c: error: %s\n", why); - printk("i2c: msg_num: %d msg_idx: %d msg_ptr: %d\n", + printk(KERN_ERR "i2c: error: %s\n", why); + printk(KERN_ERR "i2c: msg_num: %d msg_idx: %d msg_ptr: %d\n", i2c->msg_num, i2c->msg_idx, i2c->msg_ptr); - printk("i2c: ICR: %08x ISR: %08x\n" - "i2c: log: ", readl(_ICR(i2c)), readl(_ISR(i2c))); + printk(KERN_ERR "i2c: ICR: %08x ISR: %08x\n", + readl(_ICR(i2c)), readl(_ISR(i2c))); + printk(KERN_DEBUG "i2c: log: "); for (i = 0; i < i2c->irqlogidx; i++) printk("[%08x:%08x] ", i2c->isrlog[i], i2c->icrlog[i]); printk("\n"); diff --git a/drivers/i2c/busses/i2c-versatile.c b/drivers/i2c/busses/i2c-versatile.c index 4678babd3ce..fede619ba22 100644 --- a/drivers/i2c/busses/i2c-versatile.c +++ b/drivers/i2c/busses/i2c-versatile.c @@ -102,7 +102,13 @@ static int i2c_versatile_probe(struct platform_device *dev) i2c->algo = i2c_versatile_algo; i2c->algo.data = i2c; - ret = i2c_bit_add_bus(&i2c->adap); + if (dev->id >= 0) { + /* static bus numbering */ + i2c->adap.nr = dev->id; + ret = i2c_bit_add_numbered_bus(&i2c->adap); + } else + /* dynamic bus numbering */ + ret = i2c_bit_add_bus(&i2c->adap); if (ret >= 0) { platform_set_drvdata(dev, i2c); return 0; @@ -146,7 +152,7 @@ static void __exit i2c_versatile_exit(void) platform_driver_unregister(&i2c_versatile_driver); } -module_init(i2c_versatile_init); +subsys_initcall(i2c_versatile_init); module_exit(i2c_versatile_exit); MODULE_DESCRIPTION("ARM Versatile I2C bus driver"); diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index fbb9030b68a..b6f3a0de6ca 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -152,7 +152,7 @@ static void i2c_device_shutdown(struct device *dev) driver->shutdown(to_i2c_client(dev)); } -static int i2c_device_suspend(struct device * dev, pm_message_t mesg) +static int i2c_device_suspend(struct device *dev, pm_message_t mesg) { struct i2c_driver *driver; @@ -164,7 +164,7 @@ static int i2c_device_suspend(struct device * dev, pm_message_t mesg) return driver->suspend(to_i2c_client(dev), mesg); } -static int i2c_device_resume(struct device * dev) +static int i2c_device_resume(struct device *dev) { struct i2c_driver *driver; @@ -187,13 +187,15 @@ static void i2c_client_dev_release(struct device *dev) kfree(to_i2c_client(dev)); } -static ssize_t show_client_name(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t +show_client_name(struct device *dev, struct device_attribute *attr, char *buf) { struct i2c_client *client = to_i2c_client(dev); return sprintf(buf, "%s\n", client->name); } -static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t +show_modalias(struct device *dev, struct device_attribute *attr, char *buf) { struct i2c_client *client = to_i2c_client(dev); return sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name); @@ -365,8 +367,7 @@ static struct i2c_driver dummy_driver = { * This returns the new i2c client, which should be saved for later use with * i2c_unregister_device(); or NULL to indicate an error. */ -struct i2c_client * -i2c_new_dummy(struct i2c_adapter *adapter, u16 address) +struct i2c_client *i2c_new_dummy(struct i2c_adapter *adapter, u16 address) { struct i2c_board_info info = { I2C_BOARD_INFO("dummy", address), @@ -413,8 +414,8 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter) if (devinfo->busnum == adapter->nr && !i2c_new_device(adapter, &devinfo->board_info)) - printk(KERN_ERR "i2c-core: can't create i2c%d-%04x\n", - i2c_adapter_id(adapter), + dev_err(&adapter->dev, + "Can't create device at 0x%02x\n", devinfo->board_info.addr); } mutex_unlock(&__i2c_board_lock); @@ -459,6 +460,11 @@ static int i2c_register_adapter(struct i2c_adapter *adap) pr_debug("I2C adapter driver [%s] forgot to specify " "physical device\n", adap->name); } + + /* Set default timeout to 1 second if not already set */ + if (adap->timeout == 0) + adap->timeout = HZ; + dev_set_name(&adap->dev, "i2c-%d", adap->nr); adap->dev.release = &i2c_adapter_dev_release; adap->dev.class = &i2c_adapter_class; @@ -581,7 +587,8 @@ static int i2c_do_del_adapter(struct device_driver *d, void *data) struct i2c_client *client, *_n; int res; - /* Remove the devices we created ourselves */ + /* Remove the devices we created ourselves as the result of hardware + * probing (using a driver's detect method) */ list_for_each_entry_safe(client, _n, &driver->clients, detected) { if (client->adapter == adapter) { dev_dbg(&adapter->dev, "Removing %s at 0x%x\n", @@ -749,6 +756,8 @@ static int __detach_adapter(struct device *dev, void *data) struct i2c_driver *driver = data; struct i2c_client *client, *_n; + /* Remove the devices we created ourselves as the result of hardware + * probing (using a driver's detect method) */ list_for_each_entry_safe(client, _n, &driver->clients, detected) { dev_dbg(&adapter->dev, "Removing %s at 0x%x\n", client->name, client->addr); @@ -1012,7 +1021,7 @@ module_exit(i2c_exit); * Note that there is no requirement that each message be sent to * the same slave address, although that is the most common model. */ -int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num) +int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) { int ret; @@ -1519,8 +1528,7 @@ EXPORT_SYMBOL(i2c_put_adapter); /* The SMBus parts */ #define POLY (0x1070U << 3) -static u8 -crc8(u16 data) +static u8 crc8(u16 data) { int i; @@ -1984,9 +1992,9 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, * This executes an SMBus protocol operation, and returns a negative * errno code else zero on success. */ -s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags, +s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags, char read_write, u8 command, int protocol, - union i2c_smbus_data * data) + union i2c_smbus_data *data) { s32 res; diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c index abb04c82c62..634af6a8e6b 100644 --- a/drivers/input/keyboard/corgikbd.c +++ b/drivers/input/keyboard/corgikbd.c @@ -21,8 +21,6 @@ #include <linux/slab.h> #include <mach/corgi.h> -#include <mach/hardware.h> -#include <mach/pxa-regs.h> #include <mach/pxa2xx-gpio.h> #include <asm/hardware/scoop.h> diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c index 9d1781a618e..13967422658 100644 --- a/drivers/input/keyboard/spitzkbd.c +++ b/drivers/input/keyboard/spitzkbd.c @@ -21,8 +21,6 @@ #include <linux/slab.h> #include <mach/spitz.h> -#include <mach/hardware.h> -#include <mach/pxa-regs.h> #include <mach/pxa2xx-gpio.h> #define KB_ROWS 7 diff --git a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c index 56c079ef501..272deddc8db 100644 --- a/drivers/input/mouse/rpcmouse.c +++ b/drivers/input/mouse/rpcmouse.c @@ -22,10 +22,10 @@ #include <linux/interrupt.h> #include <linux/init.h> #include <linux/input.h> +#include <linux/io.h> #include <mach/hardware.h> #include <asm/irq.h> -#include <asm/io.h> #include <asm/hardware/iomd.h> MODULE_AUTHOR("Vojtech Pavlik, Russell King"); diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c index 7f36edd34f8..ed045c99f84 100644 --- a/drivers/input/serio/rpckbd.c +++ b/drivers/input/serio/rpckbd.c @@ -33,10 +33,10 @@ #include <linux/serio.h> #include <linux/err.h> #include <linux/platform_device.h> +#include <linux/io.h> #include <asm/irq.h> #include <mach/hardware.h> -#include <asm/io.h> #include <asm/hardware/iomd.h> #include <asm/system.h> diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c index 3fb51b54fe6..94a1919d439 100644 --- a/drivers/input/touchscreen/corgi_ts.c +++ b/drivers/input/touchscreen/corgi_ts.c @@ -21,7 +21,6 @@ #include <mach/sharpsl.h> #include <mach/hardware.h> -#include <mach/pxa-regs.h> #include <mach/pxa2xx-gpio.h> diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c index 73eb656acfe..805faaea644 100644 --- a/drivers/media/video/omap24xxcam.c +++ b/drivers/media/video/omap24xxcam.c @@ -80,17 +80,17 @@ static int omap24xxcam_clock_get(struct omap24xxcam_device *cam) { int rval = 0; - cam->fck = clk_get(cam->dev, "cam_fck"); + cam->fck = clk_get(cam->dev, "fck"); if (IS_ERR(cam->fck)) { - dev_err(cam->dev, "can't get cam_fck"); + dev_err(cam->dev, "can't get camera fck"); rval = PTR_ERR(cam->fck); omap24xxcam_clock_put(cam); return rval; } - cam->ick = clk_get(cam->dev, "cam_ick"); + cam->ick = clk_get(cam->dev, "ick"); if (IS_ERR(cam->ick)) { - dev_err(cam->dev, "can't get cam_ick"); + dev_err(cam->dev, "can't get camera ick"); rval = PTR_ERR(cam->ick); omap24xxcam_clock_put(cam); } diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index 07c334f25aa..0c4ce58c53d 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c @@ -35,7 +35,6 @@ #include <linux/videodev2.h> #include <mach/dma.h> -#include <mach/pxa-regs.h> #include <mach/camera.h> #define PXA_CAM_VERSION_CODE KERNEL_VERSION(0, 0, 5) diff --git a/drivers/misc/eeprom/Kconfig b/drivers/misc/eeprom/Kconfig index c76df8cda5e..89fec052f3b 100644 --- a/drivers/misc/eeprom/Kconfig +++ b/drivers/misc/eeprom/Kconfig @@ -2,7 +2,7 @@ menu "EEPROM support" config EEPROM_AT24 tristate "I2C EEPROMs from most vendors" - depends on I2C && SYSFS && EXPERIMENTAL + depends on I2C && SYSFS help Enable this driver to get read/write support to most I2C EEPROMs, after you configure the driver to know about each EEPROM on diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 2909bbc8ad0..a663429b3d5 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -490,7 +490,7 @@ static void mmci_check_status(unsigned long data) mod_timer(&host->timer, jiffies + HZ); } -static int mmci_probe(struct amba_device *dev, void *id) +static int __devinit mmci_probe(struct amba_device *dev, void *id) { struct mmc_platform_data *plat = dev->dev.platform_data; struct mmci_host *host; @@ -633,7 +633,7 @@ static int mmci_probe(struct amba_device *dev, void *id) return ret; } -static int mmci_remove(struct amba_device *dev) +static int __devexit mmci_remove(struct amba_device *dev) { struct mmc_host *mmc = amba_get_drvdata(dev); @@ -730,7 +730,7 @@ static struct amba_driver mmci_driver = { .name = DRIVER_NAME, }, .probe = mmci_probe, - .remove = mmci_remove, + .remove = __devexit_p(mmci_remove), .suspend = mmci_suspend, .resume = mmci_resume, .id_table = mmci_ids, diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index dda0be4e25d..b4a615c55f2 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -42,7 +42,7 @@ #define HAS_DMA #endif -#define DRIVER_NAME "imx-mmc" +#define DRIVER_NAME "mxc-mmc" #define MMC_REG_STR_STP_CLK 0x00 #define MMC_REG_STATUS 0x04 @@ -707,7 +707,7 @@ static int mxcmci_probe(struct platform_device *pdev) host->res = r; host->irq = irq; - host->clk = clk_get(&pdev->dev, "sdhc_clk"); + host->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(host->clk)) { ret = PTR_ERR(host->clk); goto out_iounmap; diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 67d7b7fef08..5570849188c 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -1460,18 +1460,12 @@ static int __init mmc_omap_probe(struct platform_device *pdev) if (!host->virt_base) goto err_ioremap; - if (cpu_is_omap24xx()) { - host->iclk = clk_get(&pdev->dev, "mmc_ick"); - if (IS_ERR(host->iclk)) - goto err_free_mmc_host; - clk_enable(host->iclk); - } - - if (!cpu_is_omap24xx()) - host->fclk = clk_get(&pdev->dev, "mmc_ck"); - else - host->fclk = clk_get(&pdev->dev, "mmc_fck"); + host->iclk = clk_get(&pdev->dev, "ick"); + if (IS_ERR(host->iclk)) + goto err_free_mmc_host; + clk_enable(host->iclk); + host->fclk = clk_get(&pdev->dev, "fck"); if (IS_ERR(host->fclk)) { ret = PTR_ERR(host->fclk); goto err_free_iclk; @@ -1536,10 +1530,10 @@ static int mmc_omap_remove(struct platform_device *pdev) if (host->pdata->cleanup) host->pdata->cleanup(&pdev->dev); - if (host->iclk && !IS_ERR(host->iclk)) - clk_put(host->iclk); - if (host->fclk && !IS_ERR(host->fclk)) - clk_put(host->fclk); + mmc_omap_fclk_enable(host, 0); + clk_put(host->fclk); + clk_disable(host->iclk); + clk_put(host->iclk); iounmap(host->virt_base); release_mem_region(pdev->resource[0].start, diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index a631c81dce1..3916a5618e2 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -956,13 +956,13 @@ static int __init omap_mmc_probe(struct platform_device *pdev) sema_init(&host->sem, 1); - host->iclk = clk_get(&pdev->dev, "mmchs_ick"); + host->iclk = clk_get(&pdev->dev, "ick"); if (IS_ERR(host->iclk)) { ret = PTR_ERR(host->iclk); host->iclk = NULL; goto err1; } - host->fclk = clk_get(&pdev->dev, "mmchs_fck"); + host->fclk = clk_get(&pdev->dev, "fck"); if (IS_ERR(host->fclk)) { ret = PTR_ERR(host->fclk); host->fclk = NULL; diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index 9702ad3774c..430095725f9 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c @@ -30,9 +30,8 @@ #include <asm/sizes.h> -#include <mach/dma.h> #include <mach/hardware.h> -#include <mach/pxa-regs.h> +#include <mach/dma.h> #include <mach/mmc.h> #include "pxamci.h" diff --git a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c index d2ec262666c..c9681a339a5 100644 --- a/drivers/mtd/maps/integrator-flash.c +++ b/drivers/mtd/maps/integrator-flash.c @@ -31,6 +31,7 @@ #include <linux/ioport.h> #include <linux/platform_device.h> #include <linux/init.h> +#include <linux/io.h> #include <linux/mtd/mtd.h> #include <linux/mtd/map.h> @@ -38,7 +39,6 @@ #include <asm/mach/flash.h> #include <mach/hardware.h> -#include <asm/io.h> #include <asm/system.h> #ifdef CONFIG_ARCH_P720T diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index 6f6a0f6dafd..8f57b6f40aa 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c @@ -12,6 +12,7 @@ #include <linux/slab.h> #include <linux/platform_device.h> #include <linux/err.h> +#include <linux/io.h> #include <linux/mtd/mtd.h> #include <linux/mtd/map.h> @@ -19,7 +20,6 @@ #include <linux/mtd/concat.h> #include <mach/hardware.h> -#include <asm/io.h> #include <asm/sizes.h> #include <asm/mach/flash.h> diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/cmx270_nand.c index fa129c09bca..10081e656a6 100644 --- a/drivers/mtd/nand/cmx270_nand.c +++ b/drivers/mtd/nand/cmx270_nand.c @@ -26,8 +26,7 @@ #include <asm/irq.h> #include <asm/mach-types.h> -#include <mach/hardware.h> -#include <mach/pxa-regs.h> +#include <mach/pxa2xx-regs.h> #define GPIO_NAND_CS (11) #define GPIO_NAND_RB (89) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 21fd4f1c480..bad048aca89 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -880,7 +880,7 @@ static int __init mxcnd_probe(struct platform_device *pdev) this->read_buf = mxc_nand_read_buf; this->verify_buf = mxc_nand_verify_buf; - host->clk = clk_get(&pdev->dev, "nfc_clk"); + host->clk = clk_get(&pdev->dev, "nfc"); if (IS_ERR(host->clk)) goto eclk; diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index cc55cbc2b30..61b69cc4000 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -22,7 +22,6 @@ #include <linux/irq.h> #include <mach/dma.h> -#include <mach/pxa-regs.h> #include <mach/pxa3xx_nand.h> #define CHIP_DELAY_TIMEOUT (2 * HZ/10) diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c index c2d012fcc29..4bc6901b381 100644 --- a/drivers/net/arm/am79c961a.c +++ b/drivers/net/arm/am79c961a.c @@ -27,9 +27,9 @@ #include <linux/crc32.h> #include <linux/bitops.h> #include <linux/platform_device.h> +#include <linux/io.h> #include <mach/hardware.h> -#include <asm/io.h> #include <asm/system.h> #define TX_BUFFERS 15 diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c index 5fe17d5eaa5..448487e22fa 100644 --- a/drivers/net/arm/ixp4xx_eth.c +++ b/drivers/net/arm/ixp4xx_eth.c @@ -335,11 +335,20 @@ static int ixp4xx_mdio_register(void) if (!(mdio_bus = mdiobus_alloc())) return -ENOMEM; - /* All MII PHY accesses use NPE-B Ethernet registers */ - spin_lock_init(&mdio_lock); - mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT; - __raw_writel(DEFAULT_CORE_CNTRL, &mdio_regs->core_control); + if (cpu_is_ixp43x()) { + /* IXP43x lacks NPE-B and uses NPE-C for MII PHY access */ + if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEC_ETH)) + return -ENOSYS; + mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthC_BASE_VIRT; + } else { + /* All MII PHY accesses use NPE-B Ethernet registers */ + if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEB_ETH0)) + return -ENOSYS; + mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT; + } + __raw_writel(DEFAULT_CORE_CNTRL, &mdio_regs->core_control); + spin_lock_init(&mdio_lock); mdio_bus->name = "IXP4xx MII Bus"; mdio_bus->read = &ixp4xx_mdio_read; mdio_bus->write = &ixp4xx_mdio_write; @@ -1250,9 +1259,6 @@ static struct platform_driver ixp4xx_eth_driver = { static int __init eth_init_module(void) { int err; - if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEB_ETH0)) - return -ENOSYS; - if ((err = ixp4xx_mdio_register())) return err; return platform_driver_register(&ixp4xx_eth_driver); diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index 31794c2363e..e775338b525 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -24,9 +24,8 @@ #include <mach/dma.h> #include <mach/irda.h> -#include <mach/hardware.h> -#include <mach/pxa-regs.h> #include <mach/regs-uart.h> +#include <mach/regs-ost.h> #define FICP __REG(0x40800000) /* Start of FICP area */ #define ICCR0 __REG(0x40800000) /* ICP Control Register 0 */ diff --git a/drivers/net/smc911x.h b/drivers/net/smc911x.h index a45952e7201..8140f7cb4d8 100644 --- a/drivers/net/smc911x.h +++ b/drivers/net/smc911x.h @@ -236,8 +236,7 @@ static inline void SMC_outsl(struct smc911x_local *lp, int reg, * Use a DMA for RX and TX packets. */ #include <linux/dma-mapping.h> -#include <asm/dma.h> -#include <mach/pxa-regs.h> +#include <mach/dma.h> static dma_addr_t rx_dmabuf, tx_dmabuf; static int rx_dmalen, tx_dmalen; diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index ed9ae43523a..6c44f86ae3f 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -44,6 +44,7 @@ defined(CONFIG_MACH_MAINSTONE) ||\ defined(CONFIG_MACH_ZYLONITE) ||\ defined(CONFIG_MACH_LITTLETON) ||\ + defined(CONFIG_MACH_ZYLONITE2) ||\ defined(CONFIG_ARCH_VIPER) #include <asm/mach-types.h> @@ -494,8 +495,6 @@ struct smc_local { */ #include <linux/dma-mapping.h> #include <mach/dma.h> -#include <mach/hardware.h> -#include <mach/pxa-regs.h> #ifdef SMC_insl #undef SMC_insl diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index bb9ddb9532e..c49a7269f6d 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -28,7 +28,6 @@ #include <asm/io.h> #include <asm/irq.h> #include <asm/system.h> -#include <mach/pxa-regs.h> #include <mach/pxa2xx-regs.h> #include <asm/mach-types.h> @@ -39,6 +38,44 @@ #include "soc_common.h" #include "pxa2xx_base.h" +/* + * Personal Computer Memory Card International Association (PCMCIA) sockets + */ + +#define PCMCIAPrtSp 0x04000000 /* PCMCIA Partition Space [byte] */ +#define PCMCIASp (4*PCMCIAPrtSp) /* PCMCIA Space [byte] */ +#define PCMCIAIOSp PCMCIAPrtSp /* PCMCIA I/O Space [byte] */ +#define PCMCIAAttrSp PCMCIAPrtSp /* PCMCIA Attribute Space [byte] */ +#define PCMCIAMemSp PCMCIAPrtSp /* PCMCIA Memory Space [byte] */ + +#define PCMCIA0Sp PCMCIASp /* PCMCIA 0 Space [byte] */ +#define PCMCIA0IOSp PCMCIAIOSp /* PCMCIA 0 I/O Space [byte] */ +#define PCMCIA0AttrSp PCMCIAAttrSp /* PCMCIA 0 Attribute Space [byte] */ +#define PCMCIA0MemSp PCMCIAMemSp /* PCMCIA 0 Memory Space [byte] */ + +#define PCMCIA1Sp PCMCIASp /* PCMCIA 1 Space [byte] */ +#define PCMCIA1IOSp PCMCIAIOSp /* PCMCIA 1 I/O Space [byte] */ +#define PCMCIA1AttrSp PCMCIAAttrSp /* PCMCIA 1 Attribute Space [byte] */ +#define PCMCIA1MemSp PCMCIAMemSp /* PCMCIA 1 Memory Space [byte] */ + +#define _PCMCIA(Nb) /* PCMCIA [0..1] */ \ + (0x20000000 + (Nb) * PCMCIASp) +#define _PCMCIAIO(Nb) _PCMCIA(Nb) /* PCMCIA I/O [0..1] */ +#define _PCMCIAAttr(Nb) /* PCMCIA Attribute [0..1] */ \ + (_PCMCIA(Nb) + 2 * PCMCIAPrtSp) +#define _PCMCIAMem(Nb) /* PCMCIA Memory [0..1] */ \ + (_PCMCIA(Nb) + 3 * PCMCIAPrtSp) + +#define _PCMCIA0 _PCMCIA(0) /* PCMCIA 0 */ +#define _PCMCIA0IO _PCMCIAIO(0) /* PCMCIA 0 I/O */ +#define _PCMCIA0Attr _PCMCIAAttr(0) /* PCMCIA 0 Attribute */ +#define _PCMCIA0Mem _PCMCIAMem(0) /* PCMCIA 0 Memory */ + +#define _PCMCIA1 _PCMCIA(1) /* PCMCIA 1 */ +#define _PCMCIA1IO _PCMCIAIO(1) /* PCMCIA 1 I/O */ +#define _PCMCIA1Attr _PCMCIAAttr(1) /* PCMCIA 1 Attribute */ +#define _PCMCIA1Mem _PCMCIAMem(1) /* PCMCIA 1 Memory */ + #define MCXX_SETUP_MASK (0x7f) #define MCXX_ASST_MASK (0x1f) @@ -177,29 +214,73 @@ static void pxa2xx_configure_sockets(struct device *dev) MECR |= MECR_CIT; /* Set MECR:NOS (Number Of Sockets) */ - if (ops->nr > 1 || machine_is_viper()) + if ((ops->first + ops->nr) > 1 || machine_is_viper()) MECR |= MECR_NOS; else MECR &= ~MECR_NOS; } +static const char *skt_names[] = { + "PCMCIA socket 0", + "PCMCIA socket 1", +}; + +#define SKT_DEV_INFO_SIZE(n) \ + (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket)) + int __pxa2xx_drv_pcmcia_probe(struct device *dev) { - int ret; + int i, ret; struct pcmcia_low_level *ops; + struct skt_dev_info *sinfo; + struct soc_pcmcia_socket *skt; if (!dev || !dev->platform_data) return -ENODEV; ops = (struct pcmcia_low_level *)dev->platform_data; + sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL); + if (!sinfo) + return -ENOMEM; + + sinfo->nskt = ops->nr; + + /* Initialize processor specific parameters */ + for (i = 0; i < ops->nr; i++) { + skt = &sinfo->skt[i]; + + skt->nr = ops->first + i; + skt->irq = NO_IRQ; + + skt->res_skt.start = _PCMCIA(skt->nr); + skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1; + skt->res_skt.name = skt_names[skt->nr]; + skt->res_skt.flags = IORESOURCE_MEM; + + skt->res_io.start = _PCMCIAIO(skt->nr); + skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1; + skt->res_io.name = "io"; + skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY; + + skt->res_mem.start = _PCMCIAMem(skt->nr); + skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1; + skt->res_mem.name = "memory"; + skt->res_mem.flags = IORESOURCE_MEM; + + skt->res_attr.start = _PCMCIAAttr(skt->nr); + skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1; + skt->res_attr.name = "attribute"; + skt->res_attr.flags = IORESOURCE_MEM; + } + /* Provide our PXA2xx specific timing routines. */ ops->set_timing = pxa2xx_pcmcia_set_timing; #ifdef CONFIG_CPU_FREQ ops->frequency_change = pxa2xx_pcmcia_frequency_change; #endif - ret = soc_common_drv_pcmcia_probe(dev, ops, ops->first, ops->nr); + ret = soc_common_drv_pcmcia_probe(dev, ops, sinfo); if (!ret) pxa2xx_configure_sockets(dev); diff --git a/drivers/pcmcia/pxa2xx_cm_x255.c b/drivers/pcmcia/pxa2xx_cm_x255.c index 7c8bcb47662..4ed64d8e95e 100644 --- a/drivers/pcmcia/pxa2xx_cm_x255.c +++ b/drivers/pcmcia/pxa2xx_cm_x255.c @@ -16,7 +16,6 @@ #include <linux/gpio.h> #include <asm/mach-types.h> -#include <mach/pxa-regs.h> #include "soc_common.h" diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c index 6c3aac37712..a7b943d01e3 100644 --- a/drivers/pcmcia/pxa2xx_cm_x270.c +++ b/drivers/pcmcia/pxa2xx_cm_x270.c @@ -16,7 +16,6 @@ #include <linux/gpio.h> #include <asm/mach-types.h> -#include <mach/pxa-regs.h> #include "soc_common.h" diff --git a/drivers/pcmcia/pxa2xx_e740.c b/drivers/pcmcia/pxa2xx_e740.c index f663a011bf4..d09c0dc4a31 100644 --- a/drivers/pcmcia/pxa2xx_e740.c +++ b/drivers/pcmcia/pxa2xx_e740.c @@ -16,8 +16,6 @@ #include <linux/interrupt.h> #include <linux/platform_device.h> -#include <mach/hardware.h> -#include <mach/pxa-regs.h> #include <mach/eseries-gpio.h> #include <asm/irq.h> diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/pxa2xx_lubbock.c index 37ec55df086..6cbb1b1f7cf 100644 --- a/drivers/pcmcia/pxa2xx_lubbock.c +++ b/drivers/pcmcia/pxa2xx_lubbock.c @@ -24,7 +24,6 @@ #include <mach/hardware.h> #include <asm/hardware/sa1111.h> #include <asm/mach-types.h> -#include <mach/pxa-regs.h> #include <mach/lubbock.h> #include "sa1111_generic.h" diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c index 877001db491..1138551ba8f 100644 --- a/drivers/pcmcia/pxa2xx_mainstone.c +++ b/drivers/pcmcia/pxa2xx_mainstone.c @@ -21,11 +21,10 @@ #include <pcmcia/ss.h> -#include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/irq.h> -#include <mach/pxa-regs.h> +#include <mach/pxa2xx-regs.h> #include <mach/mainstone.h> #include "soc_common.h" diff --git a/drivers/pcmcia/pxa2xx_palmld.c b/drivers/pcmcia/pxa2xx_palmld.c index 1736c67e547..5ba9b3664a0 100644 --- a/drivers/pcmcia/pxa2xx_palmld.c +++ b/drivers/pcmcia/pxa2xx_palmld.c @@ -98,8 +98,8 @@ static void palmld_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) static struct pcmcia_low_level palmld_pcmcia_ops = { .owner = THIS_MODULE, - .first = 0, - .nr = 2, + .first = 1, + .nr = 1, .hw_init = palmld_pcmcia_hw_init, .hw_shutdown = palmld_pcmcia_hw_shutdown, diff --git a/drivers/pcmcia/pxa2xx_trizeps4.c b/drivers/pcmcia/pxa2xx_trizeps4.c index 36c7a0b324d..e0e5cb339b4 100644 --- a/drivers/pcmcia/pxa2xx_trizeps4.c +++ b/drivers/pcmcia/pxa2xx_trizeps4.c @@ -22,8 +22,7 @@ #include <asm/mach-types.h> #include <asm/irq.h> -#include <mach/hardware.h> -#include <mach/pxa-regs.h> +#include <mach/pxa2xx-regs.h> #include <mach/trizeps4.h> #include "soc_common.h" diff --git a/drivers/pcmcia/pxa2xx_viper.c b/drivers/pcmcia/pxa2xx_viper.c index dd10481be7b..17871360fe9 100644 --- a/drivers/pcmcia/pxa2xx_viper.c +++ b/drivers/pcmcia/pxa2xx_viper.c @@ -26,7 +26,6 @@ #include <asm/irq.h> -#include <mach/pxa-regs.h> #include <mach/viper.h> #include <asm/mach-types.h> diff --git a/drivers/pcmcia/sa1100_h3600.c b/drivers/pcmcia/sa1100_h3600.c index 6de4e1b41d6..0cc3748f375 100644 --- a/drivers/pcmcia/sa1100_h3600.c +++ b/drivers/pcmcia/sa1100_h3600.c @@ -37,9 +37,9 @@ static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); /* Disable CF bus: */ - clr_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON); - clr_h3600_egpio(IPAQ_EGPIO_OPT_ON); - set_h3600_egpio(IPAQ_EGPIO_OPT_RESET); + assign_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON, 0); + assign_h3600_egpio(IPAQ_EGPIO_OPT_ON, 0); + assign_h3600_egpio(IPAQ_EGPIO_OPT_RESET, 1); } static void @@ -79,10 +79,7 @@ h3600_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_ return -1; } - if (state->flags & SS_RESET) - set_h3600_egpio(IPAQ_EGPIO_CARD_RESET); - else - clr_h3600_egpio(IPAQ_EGPIO_CARD_RESET); + assign_h3600_egpio(IPAQ_EGPIO_CARD_RESET, !!(state->flags & SS_RESET)); /* Silently ignore Vpp, output enable, speaker enable. */ @@ -92,9 +89,9 @@ h3600_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_ static void h3600_pcmcia_socket_init(struct soc_pcmcia_socket *skt) { /* Enable CF bus: */ - set_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON); - set_h3600_egpio(IPAQ_EGPIO_OPT_ON); - clr_h3600_egpio(IPAQ_EGPIO_OPT_RESET); + assign_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON, 1); + assign_h3600_egpio(IPAQ_EGPIO_OPT_ON, 1); + assign_h3600_egpio(IPAQ_EGPIO_OPT_RESET, 0); msleep(10); @@ -112,10 +109,10 @@ static void h3600_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) * socket 0 then socket 1. */ if (skt->nr == 1) { - clr_h3600_egpio(IPAQ_EGPIO_OPT_ON); - clr_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON); + assign_h3600_egpio(IPAQ_EGPIO_OPT_ON, 0); + assign_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON, 0); /* hmm, does this suck power? */ - set_h3600_egpio(IPAQ_EGPIO_OPT_RESET); + assign_h3600_egpio(IPAQ_EGPIO_OPT_RESET, 1); } } diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c index 6924d0ea8d3..401052a21ce 100644 --- a/drivers/pcmcia/sa1111_generic.c +++ b/drivers/pcmcia/sa1111_generic.c @@ -11,12 +11,12 @@ #include <linux/device.h> #include <linux/interrupt.h> #include <linux/init.h> +#include <linux/io.h> #include <pcmcia/ss.h> #include <mach/hardware.h> #include <asm/hardware/sa1111.h> -#include <asm/io.h> #include <asm/irq.h> #include "sa1111_generic.h" diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c index 7cb1273202c..e15d59f2d8a 100644 --- a/drivers/pcmcia/sa11xx_base.c +++ b/drivers/pcmcia/sa11xx_base.c @@ -36,9 +36,9 @@ #include <linux/ioport.h> #include <linux/kernel.h> #include <linux/spinlock.h> +#include <linux/io.h> #include <mach/hardware.h> -#include <asm/io.h> #include <asm/irq.h> #include <asm/system.h> @@ -163,9 +163,55 @@ sa1100_pcmcia_show_timing(struct soc_pcmcia_socket *skt, char *buf) return p - buf; } +static const char *skt_names[] = { + "PCMCIA socket 0", + "PCMCIA socket 1", +}; + +#define SKT_DEV_INFO_SIZE(n) \ + (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket)) + int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr) { + struct skt_dev_info *sinfo; + struct soc_pcmcia_socket *skt; + int i; + + sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL); + if (!sinfo) + return -ENOMEM; + + sinfo->nskt = nr; + + /* Initiliaze processor specific parameters */ + for (i = 0; i < nr; i++) { + skt = &sinfo->skt[i]; + + skt->nr = first + i; + skt->irq = NO_IRQ; + + skt->res_skt.start = _PCMCIA(skt->nr); + skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1; + skt->res_skt.name = skt_names[skt->nr]; + skt->res_skt.flags = IORESOURCE_MEM; + + skt->res_io.start = _PCMCIAIO(skt->nr); + skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1; + skt->res_io.name = "io"; + skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY; + + skt->res_mem.start = _PCMCIAMem(skt->nr); + skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1; + skt->res_mem.name = "memory"; + skt->res_mem.flags = IORESOURCE_MEM; + + skt->res_attr.start = _PCMCIAAttr(skt->nr); + skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1; + skt->res_attr.name = "attribute"; + skt->res_attr.flags = IORESOURCE_MEM; + } + /* * set default MECR calculation if the board specific * code did not specify one... @@ -180,7 +226,7 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, ops->frequency_change = sa1100_pcmcia_frequency_change; #endif - return soc_common_drv_pcmcia_probe(dev, ops, first, nr); + return soc_common_drv_pcmcia_probe(dev, ops, sinfo); } EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe); diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c index f49ac666615..163cf98e238 100644 --- a/drivers/pcmcia/soc_common.c +++ b/drivers/pcmcia/soc_common.c @@ -49,11 +49,6 @@ #include "soc_common.h" -/* FIXME: platform dependent resource declaration has to move out of this file */ -#ifdef CONFIG_ARCH_PXA -#include <mach/pxa-regs.h> -#endif - #ifdef CONFIG_PCMCIA_DEBUG static int pc_debug; @@ -581,19 +576,6 @@ EXPORT_SYMBOL(soc_pcmcia_enable_irqs); LIST_HEAD(soc_pcmcia_sockets); static DEFINE_MUTEX(soc_pcmcia_sockets_lock); -static const char *skt_names[] = { - "PCMCIA socket 0", - "PCMCIA socket 1", -}; - -struct skt_dev_info { - int nskt; - struct soc_pcmcia_socket skt[0]; -}; - -#define SKT_DEV_INFO_SIZE(n) \ - (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket)) - #ifdef CONFIG_CPU_FREQ static int soc_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data) @@ -637,26 +619,18 @@ static int soc_pcmcia_cpufreq_register(void) { return 0; } static void soc_pcmcia_cpufreq_unregister(void) {} #endif -int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr) +int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, + struct skt_dev_info *sinfo) { - struct skt_dev_info *sinfo; struct soc_pcmcia_socket *skt; int ret, i; mutex_lock(&soc_pcmcia_sockets_lock); - sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL); - if (!sinfo) { - ret = -ENOMEM; - goto out; - } - - sinfo->nskt = nr; - /* * Initialise the per-socket structure. */ - for (i = 0; i < nr; i++) { + for (i = 0; i < sinfo->nskt; i++) { skt = &sinfo->skt[i]; skt->socket.ops = &soc_common_pcmcia_operations; @@ -668,43 +642,21 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops skt->poll_timer.data = (unsigned long)skt; skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD; - skt->nr = first + i; - skt->irq = NO_IRQ; skt->dev = dev; skt->ops = ops; - skt->res_skt.start = _PCMCIA(skt->nr); - skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1; - skt->res_skt.name = skt_names[skt->nr]; - skt->res_skt.flags = IORESOURCE_MEM; - ret = request_resource(&iomem_resource, &skt->res_skt); if (ret) goto out_err_1; - skt->res_io.start = _PCMCIAIO(skt->nr); - skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1; - skt->res_io.name = "io"; - skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY; - ret = request_resource(&skt->res_skt, &skt->res_io); if (ret) goto out_err_2; - skt->res_mem.start = _PCMCIAMem(skt->nr); - skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1; - skt->res_mem.name = "memory"; - skt->res_mem.flags = IORESOURCE_MEM; - ret = request_resource(&skt->res_skt, &skt->res_mem); if (ret) goto out_err_3; - skt->res_attr.start = _PCMCIAAttr(skt->nr); - skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1; - skt->res_attr.name = "attribute"; - skt->res_attr.flags = IORESOURCE_MEM; - ret = request_resource(&skt->res_skt, &skt->res_attr); if (ret) goto out_err_4; diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h index 38c67375f36..290e143839e 100644 --- a/drivers/pcmcia/soc_common.h +++ b/drivers/pcmcia/soc_common.h @@ -58,6 +58,11 @@ struct soc_pcmcia_socket { struct list_head node; }; +struct skt_dev_info { + int nskt; + struct soc_pcmcia_socket skt[0]; +}; + struct pcmcia_state { unsigned detect: 1, ready: 1, @@ -132,7 +137,7 @@ extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_ extern struct list_head soc_pcmcia_sockets; -extern int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr); +extern int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, struct skt_dev_info *sinfo); extern int soc_common_drv_pcmcia_remove(struct device *dev); diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c index 45f12dcd371..e0263d2005e 100644 --- a/drivers/rtc/rtc-mv.c +++ b/drivers/rtc/rtc-mv.c @@ -12,6 +12,7 @@ #include <linux/bcd.h> #include <linux/io.h> #include <linux/platform_device.h> +#include <linux/delay.h> #define RTC_TIME_REG_OFFS 0 @@ -119,6 +120,16 @@ static int __init mv_rtc_probe(struct platform_device *pdev) return -EINVAL; } + /* make sure it is actually functional */ + if (rtc_time == 0x01000000) { + ssleep(1); + rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS); + if (rtc_time == 0x01000000) { + dev_err(&pdev->dev, "internal RTC not ticking\n"); + return -ENODEV; + } + } + platform_set_drvdata(pdev, pdata); pdata->rtc = rtc_device_register(pdev->name, &pdev->dev, &mv_rtc_ops, THIS_MODULE); diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index d26a5f82aab..4f247e4dd3f 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c @@ -35,7 +35,8 @@ #include <asm/irq.h> #ifdef CONFIG_ARCH_PXA -#include <mach/pxa-regs.h> +#include <mach/regs-rtc.h> +#include <mach/regs-ost.h> #endif #define RTC_DEF_DIVIDER 32768 - 1 diff --git a/drivers/scsi/arm/cumana_2.c b/drivers/scsi/arm/cumana_2.c index 68a64123af8..c9902b5c1f2 100644 --- a/drivers/scsi/arm/cumana_2.c +++ b/drivers/scsi/arm/cumana_2.c @@ -318,7 +318,7 @@ cumanascsi_2_set_proc_info(struct Scsi_Host *host, char *buffer, int length) { int ret = length; - if (length >= 11 && strcmp(buffer, "CUMANASCSI2") == 0) { + if (length >= 11 && strncmp(buffer, "CUMANASCSI2", 11) == 0) { buffer += 11; length -= 11; @@ -390,7 +390,8 @@ static struct scsi_host_template cumanascsi2_template = { .eh_abort_handler = fas216_eh_abort, .can_queue = 1, .this_id = 7, - .sg_tablesize = SG_ALL, + .sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS, + .dma_boundary = IOMD_DMA_BOUNDARY, .cmd_per_lun = 1, .use_clustering = DISABLE_CLUSTERING, .proc_name = "cumanascsi2", diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c index bb2477b3fb0..d8435132f46 100644 --- a/drivers/scsi/arm/eesox.c +++ b/drivers/scsi/arm/eesox.c @@ -508,7 +508,8 @@ static struct scsi_host_template eesox_template = { .eh_abort_handler = fas216_eh_abort, .can_queue = 1, .this_id = 7, - .sg_tablesize = SG_ALL, + .sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS, + .dma_boundary = IOMD_DMA_BOUNDARY, .cmd_per_lun = 1, .use_clustering = DISABLE_CLUSTERING, .proc_name = "eesox", diff --git a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c index d9a546d1917..e2297b4c1b9 100644 --- a/drivers/scsi/arm/powertec.c +++ b/drivers/scsi/arm/powertec.c @@ -302,7 +302,8 @@ static struct scsi_host_template powertecscsi_template = { .can_queue = 8, .this_id = 7, - .sg_tablesize = SG_ALL, + .sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS, + .dma_boundary = IOMD_DMA_BOUNDARY, .cmd_per_lun = 2, .use_clustering = ENABLE_CLUSTERING, .proc_name = "powertec", diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c index f31c6698419..cb6d85d7ff4 100644 --- a/drivers/serial/21285.c +++ b/drivers/serial/21285.c @@ -14,8 +14,8 @@ #include <linux/tty_flip.h> #include <linux/serial_core.h> #include <linux/serial.h> +#include <linux/io.h> -#include <asm/io.h> #include <asm/irq.h> #include <asm/mach-types.h> #include <asm/hardware/dec21285.h> diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 7d7f576da20..9be11b0963f 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -628,7 +628,7 @@ config SERIAL_MPSC_CONSOLE config SERIAL_PXA bool "PXA serial port support" - depends on ARM && ARCH_PXA + depends on ARCH_PXA || ARCH_MMP select SERIAL_CORE help If you have a machine based on an Intel XScale PXA2xx CPU you diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c index 459f3420a42..80e76426131 100644 --- a/drivers/serial/clps711x.c +++ b/drivers/serial/clps711x.c @@ -38,9 +38,9 @@ #include <linux/tty_flip.h> #include <linux/serial_core.h> #include <linux/serial.h> +#include <linux/io.h> #include <mach/hardware.h> -#include <asm/io.h> #include <asm/irq.h> #include <asm/hardware/clps7111.h> diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index a50954612b6..9f460b175c5 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c @@ -1129,7 +1129,7 @@ static int serial_imx_probe(struct platform_device *pdev) sport->timer.function = imx_timeout; sport->timer.data = (unsigned long)sport; - sport->clk = clk_get(&pdev->dev, "uart_clk"); + sport->clk = clk_get(&pdev->dev, "uart"); if (IS_ERR(sport->clk)) { ret = PTR_ERR(sport->clk); goto unmap; diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index f6e3b86bb0b..a48a8a13d87 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c @@ -43,13 +43,7 @@ #include <linux/tty_flip.h> #include <linux/serial_core.h> #include <linux/clk.h> - -#include <asm/io.h> -#include <mach/hardware.h> -#include <asm/irq.h> -#include <mach/pxa-regs.h> -#include <mach/regs-uart.h> - +#include <linux/io.h> struct uart_pxa_port { struct uart_port port; @@ -491,7 +485,7 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios, * Ensure the port will be enabled. * This is required especially for serial console. */ - up->ier |= IER_UUE; + up->ier |= UART_IER_UUE; /* * Update the per-port timeout. @@ -784,19 +778,15 @@ static int serial_pxa_probe(struct platform_device *dev) sport->port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; sport->port.uartclk = clk_get_rate(sport->clk); - /* - * Is it worth keeping this? - */ - if (mmres->start == __PREG(FFUART)) - sport->name = "FFUART"; - else if (mmres->start == __PREG(BTUART)) - sport->name = "BTUART"; - else if (mmres->start == __PREG(STUART)) - sport->name = "STUART"; - else if (mmres->start == __PREG(HWUART)) - sport->name = "HWUART"; - else + switch (dev->id) { + case 0: sport->name = "FFUART"; break; + case 1: sport->name = "BTUART"; break; + case 2: sport->name = "STUART"; break; + case 3: sport->name = "HWUART"; break; + default: sport->name = "???"; + break; + } sport->port.membase = ioremap(mmres->start, mmres->end - mmres->start + 1); if (!sport->port.membase) { diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index b24a25ea6bc..94530f01521 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/serial/sa1100.c @@ -36,8 +36,8 @@ #include <linux/tty_flip.h> #include <linux/serial_core.h> #include <linux/serial.h> +#include <linux/io.h> -#include <asm/io.h> #include <asm/irq.h> #include <mach/hardware.h> #include <asm/mach/serial_sa1100.h> diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index 1c65e380c84..d6d0c5d241c 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c @@ -1021,13 +1021,13 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) spin_lock_init(&mcspi->lock); INIT_LIST_HEAD(&mcspi->msg_queue); - mcspi->ick = clk_get(&pdev->dev, "mcspi_ick"); + mcspi->ick = clk_get(&pdev->dev, "ick"); if (IS_ERR(mcspi->ick)) { dev_dbg(&pdev->dev, "can't get mcspi_ick\n"); status = PTR_ERR(mcspi->ick); goto err1a; } - mcspi->fck = clk_get(&pdev->dev, "mcspi_fck"); + mcspi->fck = clk_get(&pdev->dev, "fck"); if (IS_ERR(mcspi->fck)) { dev_dbg(&pdev->dev, "can't get mcspi_fck\n"); status = PTR_ERR(mcspi->fck); diff --git a/drivers/spi/omap_uwire.c b/drivers/spi/omap_uwire.c index 60b5381c65c..fe8b9ac0cce 100644 --- a/drivers/spi/omap_uwire.c +++ b/drivers/spi/omap_uwire.c @@ -506,11 +506,12 @@ static int __init uwire_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, uwire); - uwire->ck = clk_get(&pdev->dev, "armxor_ck"); - if (!uwire->ck || IS_ERR(uwire->ck)) { - dev_dbg(&pdev->dev, "no mpu_xor_clk ?\n"); + uwire->ck = clk_get(&pdev->dev, "fck"); + if (IS_ERR(uwire->ck)) { + status = PTR_ERR(uwire->ck); + dev_dbg(&pdev->dev, "no functional clock?\n"); spi_master_put(master); - return -ENODEV; + return status; } clk_enable(uwire->ck); diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index ec24f2d16f3..33fcef3150d 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -34,8 +34,6 @@ #include <asm/delay.h> #include <mach/dma.h> -#include <mach/hardware.h> -#include <mach/pxa-regs.h> #include <mach/regs-ssp.h> #include <mach/ssp.h> #include <mach/pxa2xx_spi.h> diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c index fb3055f084b..7cf74f8c2db 100644 --- a/drivers/usb/host/ohci-ep93xx.c +++ b/drivers/usb/host/ohci-ep93xx.c @@ -28,8 +28,6 @@ #include <linux/signal.h> #include <linux/platform_device.h> -#include <mach/hardware.h> - static struct clk *usb_host_clock; static void ep93xx_start_hc(struct device *dev) diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index fb19803060c..41c27a44bd8 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -397,7 +397,7 @@ config FB_SA1100 config FB_IMX tristate "Motorola i.MX LCD support" - depends on FB && ARM && ARCH_IMX + depends on FB && (ARCH_IMX || ARCH_MX2) select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT @@ -2120,16 +2120,30 @@ config FB_PRE_INIT_FB the bootloader. config FB_MX3 - tristate "MX3 Framebuffer support" - depends on FB && MX3_IPU - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - default y - help - This is a framebuffer device for the i.MX31 LCD Controller. So - far only synchronous displays are supported. If you plan to use - an LCD display with your i.MX31 system, say Y here. + tristate "MX3 Framebuffer support" + depends on FB && MX3_IPU + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + default y + help + This is a framebuffer device for the i.MX31 LCD Controller. So + far only synchronous displays are supported. If you plan to use + an LCD display with your i.MX31 system, say Y here. + +config FB_BROADSHEET + tristate "E-Ink Broadsheet/Epson S1D13521 controller support" + depends on FB + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYS_FOPS + select FB_DEFERRED_IO + help + This driver implements support for the E-Ink Broadsheet + controller. The release name for this device was Epson S1D13521 + and could also have been called by other names when coupled with + a bridge adapter. source "drivers/video/omap/Kconfig" diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 2a998ca6181..bb265eca7d5 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -106,6 +106,7 @@ obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o obj-$(CONFIG_FB_MAXINE) += maxinefb.o obj-$(CONFIG_FB_METRONOME) += metronomefb.o +obj-$(CONFIG_FB_BROADSHEET) += broadsheetfb.o obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o obj-$(CONFIG_FB_SH7760) += sh7760fb.o obj-$(CONFIG_FB_IMX) += imxfb.o @@ -132,7 +133,7 @@ obj-$(CONFIG_FB_VGA16) += vga16fb.o obj-$(CONFIG_FB_OF) += offb.o obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o -obj-$(CONFIG_FB_MX3) += mx3fb.o +obj-$(CONFIG_FB_MX3) += mx3fb.o # the test framebuffer is last obj-$(CONFIG_FB_VIRTUAL) += vfb.o diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c index 61c3d3f40fd..6995fe1e86d 100644 --- a/drivers/video/acornfb.c +++ b/drivers/video/acornfb.c @@ -28,9 +28,9 @@ #include <linux/fb.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> +#include <linux/io.h> #include <mach/hardware.h> -#include <asm/io.h> #include <asm/irq.h> #include <asm/mach-types.h> #include <asm/pgtable.h> diff --git a/drivers/video/broadsheetfb.c b/drivers/video/broadsheetfb.c new file mode 100644 index 00000000000..509cb92e873 --- /dev/null +++ b/drivers/video/broadsheetfb.c @@ -0,0 +1,568 @@ +/* + * broadsheetfb.c -- FB driver for E-Ink Broadsheet controller + * + * Copyright (C) 2008, Jaya Kumar + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + * + * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven. + * + * This driver is written to be used with the Broadsheet display controller. + * + * It is intended to be architecture independent. A board specific driver + * must be used to perform all the physical IO interactions. + * + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/mm.h> +#include <linux/slab.h> +#include <linux/vmalloc.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/fb.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/list.h> +#include <linux/uaccess.h> + +#include <video/broadsheetfb.h> + +/* Display specific information */ +#define DPY_W 800 +#define DPY_H 600 + +static struct fb_fix_screeninfo broadsheetfb_fix __devinitdata = { + .id = "broadsheetfb", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_STATIC_PSEUDOCOLOR, + .xpanstep = 0, + .ypanstep = 0, + .ywrapstep = 0, + .line_length = DPY_W, + .accel = FB_ACCEL_NONE, +}; + +static struct fb_var_screeninfo broadsheetfb_var __devinitdata = { + .xres = DPY_W, + .yres = DPY_H, + .xres_virtual = DPY_W, + .yres_virtual = DPY_H, + .bits_per_pixel = 8, + .grayscale = 1, + .red = { 0, 4, 0 }, + .green = { 0, 4, 0 }, + .blue = { 0, 4, 0 }, + .transp = { 0, 0, 0 }, +}; + +/* main broadsheetfb functions */ +static void broadsheet_issue_data(struct broadsheetfb_par *par, u16 data) +{ + par->board->set_ctl(par, BS_WR, 0); + par->board->set_hdb(par, data); + par->board->set_ctl(par, BS_WR, 1); +} + +static void broadsheet_issue_cmd(struct broadsheetfb_par *par, u16 data) +{ + par->board->set_ctl(par, BS_DC, 0); + broadsheet_issue_data(par, data); +} + +static void broadsheet_send_command(struct broadsheetfb_par *par, u16 data) +{ + par->board->wait_for_rdy(par); + + par->board->set_ctl(par, BS_CS, 0); + broadsheet_issue_cmd(par, data); + par->board->set_ctl(par, BS_DC, 1); + par->board->set_ctl(par, BS_CS, 1); +} + +static void broadsheet_send_cmdargs(struct broadsheetfb_par *par, u16 cmd, + int argc, u16 *argv) +{ + int i; + + par->board->wait_for_rdy(par); + + par->board->set_ctl(par, BS_CS, 0); + broadsheet_issue_cmd(par, cmd); + par->board->set_ctl(par, BS_DC, 1); + + for (i = 0; i < argc; i++) + broadsheet_issue_data(par, argv[i]); + par->board->set_ctl(par, BS_CS, 1); +} + +static void broadsheet_burst_write(struct broadsheetfb_par *par, int size, + u16 *data) +{ + int i; + u16 tmp; + + par->board->set_ctl(par, BS_CS, 0); + par->board->set_ctl(par, BS_DC, 1); + + for (i = 0; i < size; i++) { + par->board->set_ctl(par, BS_WR, 0); + tmp = (data[i] & 0x0F) << 4; + tmp |= (data[i] & 0x0F00) << 4; + par->board->set_hdb(par, tmp); + par->board->set_ctl(par, BS_WR, 1); + } + + par->board->set_ctl(par, BS_CS, 1); +} + +static u16 broadsheet_get_data(struct broadsheetfb_par *par) +{ + u16 res; + /* wait for ready to go hi. (lo is busy) */ + par->board->wait_for_rdy(par); + + /* cs lo, dc lo for cmd, we lo for each data, db as usual */ + par->board->set_ctl(par, BS_DC, 1); + par->board->set_ctl(par, BS_CS, 0); + par->board->set_ctl(par, BS_WR, 0); + + res = par->board->get_hdb(par); + + /* strobe wr */ + par->board->set_ctl(par, BS_WR, 1); + par->board->set_ctl(par, BS_CS, 1); + + return res; +} + +static void broadsheet_write_reg(struct broadsheetfb_par *par, u16 reg, + u16 data) +{ + /* wait for ready to go hi. (lo is busy) */ + par->board->wait_for_rdy(par); + + /* cs lo, dc lo for cmd, we lo for each data, db as usual */ + par->board->set_ctl(par, BS_CS, 0); + + broadsheet_issue_cmd(par, BS_CMD_WR_REG); + + par->board->set_ctl(par, BS_DC, 1); + + broadsheet_issue_data(par, reg); + broadsheet_issue_data(par, data); + + par->board->set_ctl(par, BS_CS, 1); +} + +static u16 broadsheet_read_reg(struct broadsheetfb_par *par, u16 reg) +{ + broadsheet_send_command(par, reg); + msleep(100); + return broadsheet_get_data(par); +} + +static void __devinit broadsheet_init_display(struct broadsheetfb_par *par) +{ + u16 args[5]; + + args[0] = DPY_W; + args[1] = DPY_H; + args[2] = (100 | (1 << 8) | (1 << 9)); /* sdcfg */ + args[3] = 2; /* gdrv cfg */ + args[4] = (4 | (1 << 7)); /* lut index format */ + broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_CFG, 5, args); + + /* did the controller really set it? */ + broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_CFG, 5, args); + + args[0] = 4; /* fsync len */ + args[1] = (10 << 8) | 4; /* fend/fbegin len */ + args[2] = 10; /* line sync len */ + args[3] = (100 << 8) | 4; /* line end/begin len */ + args[4] = 6; /* pixel clock cfg */ + broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_TMG, 5, args); + + /* setup waveform */ + args[0] = 0x886; + args[1] = 0; + broadsheet_send_cmdargs(par, BS_CMD_RD_WFM_INFO, 2, args); + + broadsheet_send_command(par, BS_CMD_UPD_GDRV_CLR); + + broadsheet_send_command(par, BS_CMD_WAIT_DSPE_TRG); + + broadsheet_write_reg(par, 0x330, 0x84); + + broadsheet_send_command(par, BS_CMD_WAIT_DSPE_TRG); + + args[0] = (0x3 << 4); + broadsheet_send_cmdargs(par, BS_CMD_LD_IMG, 1, args); + + args[0] = 0x154; + broadsheet_send_cmdargs(par, BS_CMD_WR_REG, 1, args); + + broadsheet_burst_write(par, DPY_W*DPY_H/2, + (u16 *) par->info->screen_base); + + broadsheet_send_command(par, BS_CMD_LD_IMG_END); + + args[0] = 0x4300; + broadsheet_send_cmdargs(par, BS_CMD_UPD_FULL, 1, args); + + broadsheet_send_command(par, BS_CMD_WAIT_DSPE_TRG); + + broadsheet_send_command(par, BS_CMD_WAIT_DSPE_FREND); + + par->board->wait_for_rdy(par); +} + +static void __devinit broadsheet_init(struct broadsheetfb_par *par) +{ + broadsheet_send_command(par, BS_CMD_INIT_SYS_RUN); + /* the controller needs a second */ + msleep(1000); + broadsheet_init_display(par); +} + +static void broadsheetfb_dpy_update_pages(struct broadsheetfb_par *par, + u16 y1, u16 y2) +{ + u16 args[5]; + unsigned char *buf = (unsigned char *)par->info->screen_base; + + /* y1 must be a multiple of 4 so drop the lower bits */ + y1 &= 0xFFFC; + /* y2 must be a multiple of 4 , but - 1 so up the lower bits */ + y2 |= 0x0003; + + args[0] = 0x3 << 4; + args[1] = 0; + args[2] = y1; + args[3] = cpu_to_le16(par->info->var.xres); + args[4] = y2; + broadsheet_send_cmdargs(par, BS_CMD_LD_IMG_AREA, 5, args); + + args[0] = 0x154; + broadsheet_send_cmdargs(par, BS_CMD_WR_REG, 1, args); + + buf += y1 * par->info->var.xres; + broadsheet_burst_write(par, ((1 + y2 - y1) * par->info->var.xres)/2, + (u16 *) buf); + + broadsheet_send_command(par, BS_CMD_LD_IMG_END); + + args[0] = 0x4300; + broadsheet_send_cmdargs(par, BS_CMD_UPD_FULL, 1, args); + + broadsheet_send_command(par, BS_CMD_WAIT_DSPE_TRG); + + broadsheet_send_command(par, BS_CMD_WAIT_DSPE_FREND); + + par->board->wait_for_rdy(par); + +} + +static void broadsheetfb_dpy_update(struct broadsheetfb_par *par) +{ + u16 args[5]; + + args[0] = 0x3 << 4; + broadsheet_send_cmdargs(par, BS_CMD_LD_IMG, 1, args); + + args[0] = 0x154; + broadsheet_send_cmdargs(par, BS_CMD_WR_REG, 1, args); + broadsheet_burst_write(par, DPY_W*DPY_H/2, + (u16 *) par->info->screen_base); + + broadsheet_send_command(par, BS_CMD_LD_IMG_END); + + args[0] = 0x4300; + broadsheet_send_cmdargs(par, BS_CMD_UPD_FULL, 1, args); + + broadsheet_send_command(par, BS_CMD_WAIT_DSPE_TRG); + + broadsheet_send_command(par, BS_CMD_WAIT_DSPE_FREND); + + par->board->wait_for_rdy(par); + +} + +/* this is called back from the deferred io workqueue */ +static void broadsheetfb_dpy_deferred_io(struct fb_info *info, + struct list_head *pagelist) +{ + u16 y1 = 0, h = 0; + int prev_index = -1; + struct page *cur; + struct fb_deferred_io *fbdefio = info->fbdefio; + int h_inc; + u16 yres = info->var.yres; + u16 xres = info->var.xres; + + /* height increment is fixed per page */ + h_inc = DIV_ROUND_UP(PAGE_SIZE , xres); + + /* walk the written page list and swizzle the data */ + list_for_each_entry(cur, &fbdefio->pagelist, lru) { + if (prev_index < 0) { + /* just starting so assign first page */ + y1 = (cur->index << PAGE_SHIFT) / xres; + h = h_inc; + } else if ((prev_index + 1) == cur->index) { + /* this page is consecutive so increase our height */ + h += h_inc; + } else { + /* page not consecutive, issue previous update first */ + broadsheetfb_dpy_update_pages(info->par, y1, y1 + h); + /* start over with our non consecutive page */ + y1 = (cur->index << PAGE_SHIFT) / xres; + h = h_inc; + } + prev_index = cur->index; + } + + /* if we still have any pages to update we do so now */ + if (h >= yres) { + /* its a full screen update, just do it */ + broadsheetfb_dpy_update(info->par); + } else { + broadsheetfb_dpy_update_pages(info->par, y1, + min((u16) (y1 + h), yres)); + } +} + +static void broadsheetfb_fillrect(struct fb_info *info, + const struct fb_fillrect *rect) +{ + struct broadsheetfb_par *par = info->par; + + sys_fillrect(info, rect); + + broadsheetfb_dpy_update(par); +} + +static void broadsheetfb_copyarea(struct fb_info *info, + const struct fb_copyarea *area) +{ + struct broadsheetfb_par *par = info->par; + + sys_copyarea(info, area); + + broadsheetfb_dpy_update(par); +} + +static void broadsheetfb_imageblit(struct fb_info *info, + const struct fb_image *image) +{ + struct broadsheetfb_par *par = info->par; + + sys_imageblit(info, image); + + broadsheetfb_dpy_update(par); +} + +/* + * this is the slow path from userspace. they can seek and write to + * the fb. it's inefficient to do anything less than a full screen draw + */ +static ssize_t broadsheetfb_write(struct fb_info *info, const char __user *buf, + size_t count, loff_t *ppos) +{ + struct broadsheetfb_par *par = info->par; + unsigned long p = *ppos; + void *dst; + int err = 0; + unsigned long total_size; + + if (info->state != FBINFO_STATE_RUNNING) + return -EPERM; + + total_size = info->fix.smem_len; + + if (p > total_size) + return -EFBIG; + + if (count > total_size) { + err = -EFBIG; + count = total_size; + } + + if (count + p > total_size) { + if (!err) + err = -ENOSPC; + + count = total_size - p; + } + + dst = (void *)(info->screen_base + p); + + if (copy_from_user(dst, buf, count)) + err = -EFAULT; + + if (!err) + *ppos += count; + + broadsheetfb_dpy_update(par); + + return (err) ? err : count; +} + +static struct fb_ops broadsheetfb_ops = { + .owner = THIS_MODULE, + .fb_read = fb_sys_read, + .fb_write = broadsheetfb_write, + .fb_fillrect = broadsheetfb_fillrect, + .fb_copyarea = broadsheetfb_copyarea, + .fb_imageblit = broadsheetfb_imageblit, +}; + +static struct fb_deferred_io broadsheetfb_defio = { + .delay = HZ/4, + .deferred_io = broadsheetfb_dpy_deferred_io, +}; + +static int __devinit broadsheetfb_probe(struct platform_device *dev) +{ + struct fb_info *info; + struct broadsheet_board *board; + int retval = -ENOMEM; + int videomemorysize; + unsigned char *videomemory; + struct broadsheetfb_par *par; + int i; + + /* pick up board specific routines */ + board = dev->dev.platform_data; + if (!board) + return -EINVAL; + + /* try to count device specific driver, if can't, platform recalls */ + if (!try_module_get(board->owner)) + return -ENODEV; + + info = framebuffer_alloc(sizeof(struct broadsheetfb_par), &dev->dev); + if (!info) + goto err; + + videomemorysize = (DPY_W*DPY_H); + videomemory = vmalloc(videomemorysize); + if (!videomemory) + goto err_fb_rel; + + memset(videomemory, 0, videomemorysize); + + info->screen_base = (char *)videomemory; + info->fbops = &broadsheetfb_ops; + + info->var = broadsheetfb_var; + info->fix = broadsheetfb_fix; + info->fix.smem_len = videomemorysize; + par = info->par; + par->info = info; + par->board = board; + par->write_reg = broadsheet_write_reg; + par->read_reg = broadsheet_read_reg; + init_waitqueue_head(&par->waitq); + + info->flags = FBINFO_FLAG_DEFAULT; + + info->fbdefio = &broadsheetfb_defio; + fb_deferred_io_init(info); + + retval = fb_alloc_cmap(&info->cmap, 16, 0); + if (retval < 0) { + dev_err(&dev->dev, "Failed to allocate colormap\n"); + goto err_vfree; + } + + /* set cmap */ + for (i = 0; i < 16; i++) + info->cmap.red[i] = (((2*i)+1)*(0xFFFF))/32; + memcpy(info->cmap.green, info->cmap.red, sizeof(u16)*16); + memcpy(info->cmap.blue, info->cmap.red, sizeof(u16)*16); + + retval = par->board->setup_irq(info); + if (retval < 0) + goto err_cmap; + + /* this inits the dpy */ + retval = board->init(par); + if (retval < 0) + goto err_free_irq; + + broadsheet_init(par); + + retval = register_framebuffer(info); + if (retval < 0) + goto err_free_irq; + platform_set_drvdata(dev, info); + + printk(KERN_INFO + "fb%d: Broadsheet frame buffer, using %dK of video memory\n", + info->node, videomemorysize >> 10); + + + return 0; + +err_free_irq: + board->cleanup(par); +err_cmap: + fb_dealloc_cmap(&info->cmap); +err_vfree: + vfree(videomemory); +err_fb_rel: + framebuffer_release(info); +err: + module_put(board->owner); + return retval; + +} + +static int __devexit broadsheetfb_remove(struct platform_device *dev) +{ + struct fb_info *info = platform_get_drvdata(dev); + + if (info) { + struct broadsheetfb_par *par = info->par; + unregister_framebuffer(info); + fb_deferred_io_cleanup(info); + par->board->cleanup(par); + fb_dealloc_cmap(&info->cmap); + vfree((void *)info->screen_base); + module_put(par->board->owner); + framebuffer_release(info); + } + return 0; +} + +static struct platform_driver broadsheetfb_driver = { + .probe = broadsheetfb_probe, + .remove = broadsheetfb_remove, + .driver = { + .owner = THIS_MODULE, + .name = "broadsheetfb", + }, +}; + +static int __init broadsheetfb_init(void) +{ + return platform_driver_register(&broadsheetfb_driver); +} + +static void __exit broadsheetfb_exit(void) +{ + platform_driver_unregister(&broadsheetfb_driver); +} + +module_init(broadsheetfb_init); +module_exit(broadsheetfb_exit); + +MODULE_DESCRIPTION("fbdev driver for Broadsheet controller"); +MODULE_AUTHOR("Jaya Kumar"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c index 7a9e42e3a9a..83c5cefc266 100644 --- a/drivers/video/cyber2000fb.c +++ b/drivers/video/cyber2000fb.c @@ -46,8 +46,8 @@ #include <linux/fb.h> #include <linux/pci.h> #include <linux/init.h> +#include <linux/io.h> -#include <asm/io.h> #include <asm/pgtable.h> #include <asm/system.h> @@ -1425,7 +1425,7 @@ static void cyberpro_common_resume(struct cfb_info *cfb) #ifdef CONFIG_ARCH_SHARK -#include <mach/hardware.h> +#include <mach/framebuffer.h> static int __devinit cyberpro_vl_probe(void) { diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index d58c68cd456..15a0ee6d8e2 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -14,7 +14,6 @@ * linux-arm-kernel@lists.arm.linux.org.uk */ - #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -27,9 +26,11 @@ #include <linux/init.h> #include <linux/ioport.h> #include <linux/cpufreq.h> +#include <linux/clk.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> #include <linux/io.h> +#include <linux/math64.h> #include <mach/imxfb.h> @@ -44,7 +45,12 @@ #define LCDC_SIZE 0x04 #define SIZE_XMAX(x) ((((x) >> 4) & 0x3f) << 20) + +#ifdef CONFIG_ARCH_MX1 #define SIZE_YMAX(y) ((y) & 0x1ff) +#else +#define SIZE_YMAX(y) ((y) & 0x3ff) +#endif #define LCDC_VPW 0x08 #define VPW_VPW(x) ((x) & 0x3ff) @@ -54,7 +60,12 @@ #define CPOS_CC0 (1<<30) #define CPOS_OP (1<<28) #define CPOS_CXP(x) (((x) & 3ff) << 16) + +#ifdef CONFIG_ARCH_MX1 #define CPOS_CYP(y) ((y) & 0x1ff) +#else +#define CPOS_CYP(y) ((y) & 0x3ff) +#endif #define LCDC_LCWHB 0x10 #define LCWHB_BK_EN (1<<31) @@ -63,9 +74,16 @@ #define LCWHB_BD(x) ((x) & 0xff) #define LCDC_LCHCC 0x14 + +#ifdef CONFIG_ARCH_MX1 #define LCHCC_CUR_COL_R(r) (((r) & 0x1f) << 11) #define LCHCC_CUR_COL_G(g) (((g) & 0x3f) << 5) #define LCHCC_CUR_COL_B(b) ((b) & 0x1f) +#else +#define LCHCC_CUR_COL_R(r) (((r) & 0x3f) << 12) +#define LCHCC_CUR_COL_G(g) (((g) & 0x3f) << 6) +#define LCHCC_CUR_COL_B(b) ((b) & 0x3f) +#endif #define LCDC_PCR 0x18 @@ -92,7 +110,13 @@ /* bit fields in imxfb.h */ #define LCDC_RMCR 0x34 + +#ifdef CONFIG_ARCH_MX1 #define RMCR_LCDC_EN (1<<1) +#else +#define RMCR_LCDC_EN 0 +#endif + #define RMCR_SELF_REF (1<<0) #define LCDC_LCDICR 0x38 @@ -119,6 +143,7 @@ struct imxfb_rgb { struct imxfb_info { struct platform_device *pdev; void __iomem *regs; + struct clk *clk; u_int max_bpp; u_int max_xres; @@ -159,6 +184,17 @@ struct imxfb_info { #define MIN_XRES 64 #define MIN_YRES 64 +/* Actually this really is 18bit support, the lowest 2 bits of each colour + * are unused in hardware. We claim to have 24bit support to make software + * like X work, which does not support 18bit. + */ +static struct imxfb_rgb def_rgb_18 = { + .red = {.offset = 16, .length = 8,}, + .green = {.offset = 8, .length = 8,}, + .blue = {.offset = 0, .length = 8,}, + .transp = {.offset = 0, .length = 0,}, +}; + static struct imxfb_rgb def_rgb_16_tft = { .red = {.offset = 11, .length = 5,}, .green = {.offset = 5, .length = 6,}, @@ -286,9 +322,12 @@ static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel); switch (var->bits_per_pixel) { + case 32: + rgb = &def_rgb_18; + break; case 16: default: - if (readl(fbi->regs + LCDC_PCR) & PCR_TFT) + if (fbi->pcr & PCR_TFT) rgb = &def_rgb_16_tft; else rgb = &def_rgb_16_stn; @@ -327,9 +366,7 @@ static int imxfb_set_par(struct fb_info *info) struct imxfb_info *fbi = info->par; struct fb_var_screeninfo *var = &info->var; - pr_debug("set_par\n"); - - if (var->bits_per_pixel == 16) + if (var->bits_per_pixel == 16 || var->bits_per_pixel == 32) info->fix.visual = FB_VISUAL_TRUECOLOR; else if (!fbi->cmap_static) info->fix.visual = FB_VISUAL_PSEUDOCOLOR; @@ -354,10 +391,6 @@ static void imxfb_enable_controller(struct imxfb_info *fbi) { pr_debug("Enabling LCD controller\n"); - /* initialize LCDC */ - writel(readl(fbi->regs + LCDC_RMCR) & ~RMCR_LCDC_EN, - fbi->regs + LCDC_RMCR); /* just to be safe... */ - writel(fbi->screen_dma, fbi->regs + LCDC_SSA); /* physical screen start address */ @@ -373,6 +406,8 @@ static void imxfb_enable_controller(struct imxfb_info *fbi) writel(RMCR_LCDC_EN, fbi->regs + LCDC_RMCR); + clk_enable(fbi->clk); + if (fbi->backlight_power) fbi->backlight_power(1); if (fbi->lcd_power) @@ -388,6 +423,8 @@ static void imxfb_disable_controller(struct imxfb_info *fbi) if (fbi->lcd_power) fbi->lcd_power(0); + clk_disable(fbi->clk); + writel(0, fbi->regs + LCDC_RMCR); } @@ -431,6 +468,9 @@ static struct fb_ops imxfb_ops = { static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info) { struct imxfb_info *fbi = info->par; + unsigned int pcr, lcd_clk; + unsigned long long tmp; + pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n", var->xres, var->hsync_len, var->left_margin, var->right_margin); @@ -465,9 +505,9 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf info->fix.id, var->lower_margin); #endif - writel(HCR_H_WIDTH(var->hsync_len) | - HCR_H_WAIT_1(var->right_margin) | - HCR_H_WAIT_2(var->left_margin), + writel(HCR_H_WIDTH(var->hsync_len - 1) | + HCR_H_WAIT_1(var->right_margin - 1) | + HCR_H_WAIT_2(var->left_margin - 3), fbi->regs + LCDC_HCR); writel(VCR_V_WIDTH(var->vsync_len) | @@ -477,7 +517,23 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf writel(SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres), fbi->regs + LCDC_SIZE); - writel(fbi->pcr, fbi->regs + LCDC_PCR); + + lcd_clk = clk_get_rate(fbi->clk); + tmp = var->pixclock * (unsigned long long)lcd_clk; + do_div(tmp, 1000000); + if (do_div(tmp, 1000000) > 500000) + tmp++; + pcr = (unsigned int)tmp; + if (--pcr > 0x3F) { + pcr = 0x3F; + printk(KERN_WARNING "Must limit pixel clock to %uHz\n", + lcd_clk / pcr); + } + + /* add sync polarities */ + pcr |= fbi->pcr & ~0x3F; + + writel(pcr, fbi->regs + LCDC_PCR); writel(fbi->pwmr, fbi->regs + LCDC_PWMR); writel(fbi->lscr1, fbi->regs + LCDC_LSCR1); writel(fbi->dmacr, fbi->regs + LCDC_DMACR); @@ -619,6 +675,13 @@ static int __init imxfb_probe(struct platform_device *pdev) goto failed_req; } + fbi->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(fbi->clk)) { + ret = PTR_ERR(fbi->clk);; + dev_err(&pdev->dev, "unable to get clock: %d\n", ret); + goto failed_getclock; + } + fbi->regs = ioremap(res->start, resource_size(res)); if (fbi->regs == NULL) { printk(KERN_ERR"Cannot map frame buffer registers\n"); @@ -650,6 +713,12 @@ static int __init imxfb_probe(struct platform_device *pdev) info->fix.smem_start = fbi->screen_dma; } + if (pdata->init) { + ret = pdata->init(fbi->pdev); + if (ret) + goto failed_platform_init; + } + /* * This makes sure that our colour bitfield * descriptors are correctly initialised. @@ -674,10 +743,15 @@ static int __init imxfb_probe(struct platform_device *pdev) failed_register: fb_dealloc_cmap(&info->cmap); failed_cmap: + if (pdata->exit) + pdata->exit(fbi->pdev); +failed_platform_init: if (!pdata->fixed_screen_cpu) dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu, fbi->map_dma); failed_map: + clk_put(fbi->clk); +failed_getclock: iounmap(fbi->regs); failed_ioremap: release_mem_region(res->start, res->end - res->start); @@ -691,6 +765,7 @@ failed_init: static int __devexit imxfb_remove(struct platform_device *pdev) { + struct imx_fb_platform_data *pdata; struct fb_info *info = platform_get_drvdata(pdev); struct imxfb_info *fbi = info->par; struct resource *res; @@ -701,12 +776,19 @@ static int __devexit imxfb_remove(struct platform_device *pdev) unregister_framebuffer(info); + pdata = pdev->dev.platform_data; + if (pdata->exit) + pdata->exit(fbi->pdev); + fb_dealloc_cmap(&info->cmap); kfree(info->pseudo_palette); framebuffer_release(info); iounmap(fbi->regs); release_mem_region(res->start, res->end - res->start + 1); + clk_disable(fbi->clk); + clk_put(fbi->clk); + platform_set_drvdata(pdev, NULL); return 0; diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c index 8a75d05f433..fa1a512ce03 100644 --- a/drivers/video/mx3fb.c +++ b/drivers/video/mx3fb.c @@ -34,240 +34,240 @@ #include <asm/io.h> #include <asm/uaccess.h> -#define MX3FB_NAME "mx3_sdc_fb" +#define MX3FB_NAME "mx3_sdc_fb" -#define MX3FB_REG_OFFSET 0xB4 +#define MX3FB_REG_OFFSET 0xB4 /* SDC Registers */ -#define SDC_COM_CONF (0xB4 - MX3FB_REG_OFFSET) -#define SDC_GW_CTRL (0xB8 - MX3FB_REG_OFFSET) -#define SDC_FG_POS (0xBC - MX3FB_REG_OFFSET) -#define SDC_BG_POS (0xC0 - MX3FB_REG_OFFSET) -#define SDC_CUR_POS (0xC4 - MX3FB_REG_OFFSET) -#define SDC_PWM_CTRL (0xC8 - MX3FB_REG_OFFSET) -#define SDC_CUR_MAP (0xCC - MX3FB_REG_OFFSET) -#define SDC_HOR_CONF (0xD0 - MX3FB_REG_OFFSET) -#define SDC_VER_CONF (0xD4 - MX3FB_REG_OFFSET) -#define SDC_SHARP_CONF_1 (0xD8 - MX3FB_REG_OFFSET) -#define SDC_SHARP_CONF_2 (0xDC - MX3FB_REG_OFFSET) +#define SDC_COM_CONF (0xB4 - MX3FB_REG_OFFSET) +#define SDC_GW_CTRL (0xB8 - MX3FB_REG_OFFSET) +#define SDC_FG_POS (0xBC - MX3FB_REG_OFFSET) +#define SDC_BG_POS (0xC0 - MX3FB_REG_OFFSET) +#define SDC_CUR_POS (0xC4 - MX3FB_REG_OFFSET) +#define SDC_PWM_CTRL (0xC8 - MX3FB_REG_OFFSET) +#define SDC_CUR_MAP (0xCC - MX3FB_REG_OFFSET) +#define SDC_HOR_CONF (0xD0 - MX3FB_REG_OFFSET) +#define SDC_VER_CONF (0xD4 - MX3FB_REG_OFFSET) +#define SDC_SHARP_CONF_1 (0xD8 - MX3FB_REG_OFFSET) +#define SDC_SHARP_CONF_2 (0xDC - MX3FB_REG_OFFSET) /* Register bits */ -#define SDC_COM_TFT_COLOR 0x00000001UL -#define SDC_COM_FG_EN 0x00000010UL -#define SDC_COM_GWSEL 0x00000020UL -#define SDC_COM_GLB_A 0x00000040UL -#define SDC_COM_KEY_COLOR_G 0x00000080UL -#define SDC_COM_BG_EN 0x00000200UL -#define SDC_COM_SHARP 0x00001000UL +#define SDC_COM_TFT_COLOR 0x00000001UL +#define SDC_COM_FG_EN 0x00000010UL +#define SDC_COM_GWSEL 0x00000020UL +#define SDC_COM_GLB_A 0x00000040UL +#define SDC_COM_KEY_COLOR_G 0x00000080UL +#define SDC_COM_BG_EN 0x00000200UL +#define SDC_COM_SHARP 0x00001000UL -#define SDC_V_SYNC_WIDTH_L 0x00000001UL +#define SDC_V_SYNC_WIDTH_L 0x00000001UL /* Display Interface registers */ -#define DI_DISP_IF_CONF (0x0124 - MX3FB_REG_OFFSET) -#define DI_DISP_SIG_POL (0x0128 - MX3FB_REG_OFFSET) -#define DI_SER_DISP1_CONF (0x012C - MX3FB_REG_OFFSET) -#define DI_SER_DISP2_CONF (0x0130 - MX3FB_REG_OFFSET) -#define DI_HSP_CLK_PER (0x0134 - MX3FB_REG_OFFSET) -#define DI_DISP0_TIME_CONF_1 (0x0138 - MX3FB_REG_OFFSET) -#define DI_DISP0_TIME_CONF_2 (0x013C - MX3FB_REG_OFFSET) -#define DI_DISP0_TIME_CONF_3 (0x0140 - MX3FB_REG_OFFSET) -#define DI_DISP1_TIME_CONF_1 (0x0144 - MX3FB_REG_OFFSET) -#define DI_DISP1_TIME_CONF_2 (0x0148 - MX3FB_REG_OFFSET) -#define DI_DISP1_TIME_CONF_3 (0x014C - MX3FB_REG_OFFSET) -#define DI_DISP2_TIME_CONF_1 (0x0150 - MX3FB_REG_OFFSET) -#define DI_DISP2_TIME_CONF_2 (0x0154 - MX3FB_REG_OFFSET) -#define DI_DISP2_TIME_CONF_3 (0x0158 - MX3FB_REG_OFFSET) -#define DI_DISP3_TIME_CONF (0x015C - MX3FB_REG_OFFSET) -#define DI_DISP0_DB0_MAP (0x0160 - MX3FB_REG_OFFSET) -#define DI_DISP0_DB1_MAP (0x0164 - MX3FB_REG_OFFSET) -#define DI_DISP0_DB2_MAP (0x0168 - MX3FB_REG_OFFSET) -#define DI_DISP0_CB0_MAP (0x016C - MX3FB_REG_OFFSET) -#define DI_DISP0_CB1_MAP (0x0170 - MX3FB_REG_OFFSET) -#define DI_DISP0_CB2_MAP (0x0174 - MX3FB_REG_OFFSET) -#define DI_DISP1_DB0_MAP (0x0178 - MX3FB_REG_OFFSET) -#define DI_DISP1_DB1_MAP (0x017C - MX3FB_REG_OFFSET) -#define DI_DISP1_DB2_MAP (0x0180 - MX3FB_REG_OFFSET) -#define DI_DISP1_CB0_MAP (0x0184 - MX3FB_REG_OFFSET) -#define DI_DISP1_CB1_MAP (0x0188 - MX3FB_REG_OFFSET) -#define DI_DISP1_CB2_MAP (0x018C - MX3FB_REG_OFFSET) -#define DI_DISP2_DB0_MAP (0x0190 - MX3FB_REG_OFFSET) -#define DI_DISP2_DB1_MAP (0x0194 - MX3FB_REG_OFFSET) -#define DI_DISP2_DB2_MAP (0x0198 - MX3FB_REG_OFFSET) -#define DI_DISP2_CB0_MAP (0x019C - MX3FB_REG_OFFSET) -#define DI_DISP2_CB1_MAP (0x01A0 - MX3FB_REG_OFFSET) -#define DI_DISP2_CB2_MAP (0x01A4 - MX3FB_REG_OFFSET) -#define DI_DISP3_B0_MAP (0x01A8 - MX3FB_REG_OFFSET) -#define DI_DISP3_B1_MAP (0x01AC - MX3FB_REG_OFFSET) -#define DI_DISP3_B2_MAP (0x01B0 - MX3FB_REG_OFFSET) -#define DI_DISP_ACC_CC (0x01B4 - MX3FB_REG_OFFSET) -#define DI_DISP_LLA_CONF (0x01B8 - MX3FB_REG_OFFSET) -#define DI_DISP_LLA_DATA (0x01BC - MX3FB_REG_OFFSET) +#define DI_DISP_IF_CONF (0x0124 - MX3FB_REG_OFFSET) +#define DI_DISP_SIG_POL (0x0128 - MX3FB_REG_OFFSET) +#define DI_SER_DISP1_CONF (0x012C - MX3FB_REG_OFFSET) +#define DI_SER_DISP2_CONF (0x0130 - MX3FB_REG_OFFSET) +#define DI_HSP_CLK_PER (0x0134 - MX3FB_REG_OFFSET) +#define DI_DISP0_TIME_CONF_1 (0x0138 - MX3FB_REG_OFFSET) +#define DI_DISP0_TIME_CONF_2 (0x013C - MX3FB_REG_OFFSET) +#define DI_DISP0_TIME_CONF_3 (0x0140 - MX3FB_REG_OFFSET) +#define DI_DISP1_TIME_CONF_1 (0x0144 - MX3FB_REG_OFFSET) +#define DI_DISP1_TIME_CONF_2 (0x0148 - MX3FB_REG_OFFSET) +#define DI_DISP1_TIME_CONF_3 (0x014C - MX3FB_REG_OFFSET) +#define DI_DISP2_TIME_CONF_1 (0x0150 - MX3FB_REG_OFFSET) +#define DI_DISP2_TIME_CONF_2 (0x0154 - MX3FB_REG_OFFSET) +#define DI_DISP2_TIME_CONF_3 (0x0158 - MX3FB_REG_OFFSET) +#define DI_DISP3_TIME_CONF (0x015C - MX3FB_REG_OFFSET) +#define DI_DISP0_DB0_MAP (0x0160 - MX3FB_REG_OFFSET) +#define DI_DISP0_DB1_MAP (0x0164 - MX3FB_REG_OFFSET) +#define DI_DISP0_DB2_MAP (0x0168 - MX3FB_REG_OFFSET) +#define DI_DISP0_CB0_MAP (0x016C - MX3FB_REG_OFFSET) +#define DI_DISP0_CB1_MAP (0x0170 - MX3FB_REG_OFFSET) +#define DI_DISP0_CB2_MAP (0x0174 - MX3FB_REG_OFFSET) +#define DI_DISP1_DB0_MAP (0x0178 - MX3FB_REG_OFFSET) +#define DI_DISP1_DB1_MAP (0x017C - MX3FB_REG_OFFSET) +#define DI_DISP1_DB2_MAP (0x0180 - MX3FB_REG_OFFSET) +#define DI_DISP1_CB0_MAP (0x0184 - MX3FB_REG_OFFSET) +#define DI_DISP1_CB1_MAP (0x0188 - MX3FB_REG_OFFSET) +#define DI_DISP1_CB2_MAP (0x018C - MX3FB_REG_OFFSET) +#define DI_DISP2_DB0_MAP (0x0190 - MX3FB_REG_OFFSET) +#define DI_DISP2_DB1_MAP (0x0194 - MX3FB_REG_OFFSET) +#define DI_DISP2_DB2_MAP (0x0198 - MX3FB_REG_OFFSET) +#define DI_DISP2_CB0_MAP (0x019C - MX3FB_REG_OFFSET) +#define DI_DISP2_CB1_MAP (0x01A0 - MX3FB_REG_OFFSET) +#define DI_DISP2_CB2_MAP (0x01A4 - MX3FB_REG_OFFSET) +#define DI_DISP3_B0_MAP (0x01A8 - MX3FB_REG_OFFSET) +#define DI_DISP3_B1_MAP (0x01AC - MX3FB_REG_OFFSET) +#define DI_DISP3_B2_MAP (0x01B0 - MX3FB_REG_OFFSET) +#define DI_DISP_ACC_CC (0x01B4 - MX3FB_REG_OFFSET) +#define DI_DISP_LLA_CONF (0x01B8 - MX3FB_REG_OFFSET) +#define DI_DISP_LLA_DATA (0x01BC - MX3FB_REG_OFFSET) /* DI_DISP_SIG_POL bits */ -#define DI_D3_VSYNC_POL_SHIFT 28 -#define DI_D3_HSYNC_POL_SHIFT 27 -#define DI_D3_DRDY_SHARP_POL_SHIFT 26 -#define DI_D3_CLK_POL_SHIFT 25 -#define DI_D3_DATA_POL_SHIFT 24 +#define DI_D3_VSYNC_POL_SHIFT 28 +#define DI_D3_HSYNC_POL_SHIFT 27 +#define DI_D3_DRDY_SHARP_POL_SHIFT 26 +#define DI_D3_CLK_POL_SHIFT 25 +#define DI_D3_DATA_POL_SHIFT 24 /* DI_DISP_IF_CONF bits */ -#define DI_D3_CLK_IDLE_SHIFT 26 -#define DI_D3_CLK_SEL_SHIFT 25 -#define DI_D3_DATAMSK_SHIFT 24 +#define DI_D3_CLK_IDLE_SHIFT 26 +#define DI_D3_CLK_SEL_SHIFT 25 +#define DI_D3_DATAMSK_SHIFT 24 enum ipu_panel { - IPU_PANEL_SHARP_TFT, - IPU_PANEL_TFT, + IPU_PANEL_SHARP_TFT, + IPU_PANEL_TFT, }; struct ipu_di_signal_cfg { - unsigned datamask_en:1; - unsigned clksel_en:1; - unsigned clkidle_en:1; - unsigned data_pol:1; /* true = inverted */ - unsigned clk_pol:1; /* true = rising edge */ - unsigned enable_pol:1; - unsigned Hsync_pol:1; /* true = active high */ - unsigned Vsync_pol:1; + unsigned datamask_en:1; + unsigned clksel_en:1; + unsigned clkidle_en:1; + unsigned data_pol:1; /* true = inverted */ + unsigned clk_pol:1; /* true = rising edge */ + unsigned enable_pol:1; + unsigned Hsync_pol:1; /* true = active high */ + unsigned Vsync_pol:1; }; static const struct fb_videomode mx3fb_modedb[] = { - { - /* 240x320 @ 60 Hz */ - .name = "Sharp-QVGA", - .refresh = 60, - .xres = 240, - .yres = 320, - .pixclock = 185925, - .left_margin = 9, - .right_margin = 16, - .upper_margin = 7, - .lower_margin = 9, - .hsync_len = 1, - .vsync_len = 1, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE | - FB_SYNC_CLK_INVERT | FB_SYNC_DATA_INVERT | - FB_SYNC_CLK_IDLE_EN, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, { - /* 240x33 @ 60 Hz */ - .name = "Sharp-CLI", - .refresh = 60, - .xres = 240, - .yres = 33, - .pixclock = 185925, - .left_margin = 9, - .right_margin = 16, - .upper_margin = 7, - .lower_margin = 9 + 287, - .hsync_len = 1, - .vsync_len = 1, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE | - FB_SYNC_CLK_INVERT | FB_SYNC_DATA_INVERT | - FB_SYNC_CLK_IDLE_EN, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, { - /* 640x480 @ 60 Hz */ - .name = "NEC-VGA", - .refresh = 60, - .xres = 640, - .yres = 480, - .pixclock = 38255, - .left_margin = 144, - .right_margin = 0, - .upper_margin = 34, - .lower_margin = 40, - .hsync_len = 1, - .vsync_len = 1, - .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, { - /* NTSC TV output */ - .name = "TV-NTSC", - .refresh = 60, - .xres = 640, - .yres = 480, - .pixclock = 37538, - .left_margin = 38, - .right_margin = 858 - 640 - 38 - 3, - .upper_margin = 36, - .lower_margin = 518 - 480 - 36 - 1, - .hsync_len = 3, - .vsync_len = 1, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, { - /* PAL TV output */ - .name = "TV-PAL", - .refresh = 50, - .xres = 640, - .yres = 480, - .pixclock = 37538, - .left_margin = 38, - .right_margin = 960 - 640 - 38 - 32, - .upper_margin = 32, - .lower_margin = 555 - 480 - 32 - 3, - .hsync_len = 32, - .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, { - /* TV output VGA mode, 640x480 @ 65 Hz */ - .name = "TV-VGA", - .refresh = 60, - .xres = 640, - .yres = 480, - .pixclock = 40574, - .left_margin = 35, - .right_margin = 45, - .upper_margin = 9, - .lower_margin = 1, - .hsync_len = 46, - .vsync_len = 5, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, + { + /* 240x320 @ 60 Hz */ + .name = "Sharp-QVGA", + .refresh = 60, + .xres = 240, + .yres = 320, + .pixclock = 185925, + .left_margin = 9, + .right_margin = 16, + .upper_margin = 7, + .lower_margin = 9, + .hsync_len = 1, + .vsync_len = 1, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE | + FB_SYNC_CLK_INVERT | FB_SYNC_DATA_INVERT | + FB_SYNC_CLK_IDLE_EN, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, + }, { + /* 240x33 @ 60 Hz */ + .name = "Sharp-CLI", + .refresh = 60, + .xres = 240, + .yres = 33, + .pixclock = 185925, + .left_margin = 9, + .right_margin = 16, + .upper_margin = 7, + .lower_margin = 9 + 287, + .hsync_len = 1, + .vsync_len = 1, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE | + FB_SYNC_CLK_INVERT | FB_SYNC_DATA_INVERT | + FB_SYNC_CLK_IDLE_EN, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, + }, { + /* 640x480 @ 60 Hz */ + .name = "NEC-VGA", + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 38255, + .left_margin = 144, + .right_margin = 0, + .upper_margin = 34, + .lower_margin = 40, + .hsync_len = 1, + .vsync_len = 1, + .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, + }, { + /* NTSC TV output */ + .name = "TV-NTSC", + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 37538, + .left_margin = 38, + .right_margin = 858 - 640 - 38 - 3, + .upper_margin = 36, + .lower_margin = 518 - 480 - 36 - 1, + .hsync_len = 3, + .vsync_len = 1, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, + }, { + /* PAL TV output */ + .name = "TV-PAL", + .refresh = 50, + .xres = 640, + .yres = 480, + .pixclock = 37538, + .left_margin = 38, + .right_margin = 960 - 640 - 38 - 32, + .upper_margin = 32, + .lower_margin = 555 - 480 - 32 - 3, + .hsync_len = 32, + .vsync_len = 3, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, + }, { + /* TV output VGA mode, 640x480 @ 65 Hz */ + .name = "TV-VGA", + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 40574, + .left_margin = 35, + .right_margin = 45, + .upper_margin = 9, + .lower_margin = 1, + .hsync_len = 46, + .vsync_len = 5, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, + }, }; struct mx3fb_data { - struct fb_info *fbi; - int backlight_level; - void __iomem *reg_base; - spinlock_t lock; - struct device *dev; - - uint32_t h_start_width; - uint32_t v_start_width; + struct fb_info *fbi; + int backlight_level; + void __iomem *reg_base; + spinlock_t lock; + struct device *dev; + + uint32_t h_start_width; + uint32_t v_start_width; }; struct dma_chan_request { - struct mx3fb_data *mx3fb; - enum ipu_channel id; + struct mx3fb_data *mx3fb; + enum ipu_channel id; }; /* MX3 specific framebuffer information. */ struct mx3fb_info { - int blank; - enum ipu_channel ipu_ch; - uint32_t cur_ipu_buf; + int blank; + enum ipu_channel ipu_ch; + uint32_t cur_ipu_buf; - u32 pseudo_palette[16]; + u32 pseudo_palette[16]; - struct completion flip_cmpl; - struct mutex mutex; /* Protects fb-ops */ - struct mx3fb_data *mx3fb; - struct idmac_channel *idmac_channel; - struct dma_async_tx_descriptor *txd; - dma_cookie_t cookie; - struct scatterlist sg[2]; + struct completion flip_cmpl; + struct mutex mutex; /* Protects fb-ops */ + struct mx3fb_data *mx3fb; + struct idmac_channel *idmac_channel; + struct dma_async_tx_descriptor *txd; + dma_cookie_t cookie; + struct scatterlist sg[2]; - u32 sync; /* preserve var->sync flags */ + u32 sync; /* preserve var->sync flags */ }; static void mx3fb_dma_done(void *); @@ -278,389 +278,389 @@ static unsigned long default_bpp = 16; static u32 mx3fb_read_reg(struct mx3fb_data *mx3fb, unsigned long reg) { - return __raw_readl(mx3fb->reg_base + reg); + return __raw_readl(mx3fb->reg_base + reg); } static void mx3fb_write_reg(struct mx3fb_data *mx3fb, u32 value, unsigned long reg) { - __raw_writel(value, mx3fb->reg_base + reg); + __raw_writel(value, mx3fb->reg_base + reg); } static const uint32_t di_mappings[] = { - 0x1600AAAA, 0x00E05555, 0x00070000, 3, /* RGB888 */ - 0x0005000F, 0x000B000F, 0x0011000F, 1, /* RGB666 */ - 0x0011000F, 0x000B000F, 0x0005000F, 1, /* BGR666 */ - 0x0004003F, 0x000A000F, 0x000F003F, 1 /* RGB565 */ + 0x1600AAAA, 0x00E05555, 0x00070000, 3, /* RGB888 */ + 0x0005000F, 0x000B000F, 0x0011000F, 1, /* RGB666 */ + 0x0011000F, 0x000B000F, 0x0005000F, 1, /* BGR666 */ + 0x0004003F, 0x000A000F, 0x000F003F, 1 /* RGB565 */ }; static void sdc_fb_init(struct mx3fb_info *fbi) { - struct mx3fb_data *mx3fb = fbi->mx3fb; - uint32_t reg; + struct mx3fb_data *mx3fb = fbi->mx3fb; + uint32_t reg; - reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); + reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); - mx3fb_write_reg(mx3fb, reg | SDC_COM_BG_EN, SDC_COM_CONF); + mx3fb_write_reg(mx3fb, reg | SDC_COM_BG_EN, SDC_COM_CONF); } /* Returns enabled flag before uninit */ static uint32_t sdc_fb_uninit(struct mx3fb_info *fbi) { - struct mx3fb_data *mx3fb = fbi->mx3fb; - uint32_t reg; + struct mx3fb_data *mx3fb = fbi->mx3fb; + uint32_t reg; - reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); + reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); - mx3fb_write_reg(mx3fb, reg & ~SDC_COM_BG_EN, SDC_COM_CONF); + mx3fb_write_reg(mx3fb, reg & ~SDC_COM_BG_EN, SDC_COM_CONF); - return reg & SDC_COM_BG_EN; + return reg & SDC_COM_BG_EN; } static void sdc_enable_channel(struct mx3fb_info *mx3_fbi) { - struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; - struct idmac_channel *ichan = mx3_fbi->idmac_channel; - struct dma_chan *dma_chan = &ichan->dma_chan; - unsigned long flags; - dma_cookie_t cookie; - - dev_dbg(mx3fb->dev, "mx3fbi %p, desc %p, sg %p\n", mx3_fbi, - to_tx_desc(mx3_fbi->txd), to_tx_desc(mx3_fbi->txd)->sg); - - /* This enables the channel */ - if (mx3_fbi->cookie < 0) { - mx3_fbi->txd = dma_chan->device->device_prep_slave_sg(dma_chan, - &mx3_fbi->sg[0], 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT); - if (!mx3_fbi->txd) { - dev_err(mx3fb->dev, "Cannot allocate descriptor on %d\n", - dma_chan->chan_id); - return; - } - - mx3_fbi->txd->callback_param = mx3_fbi->txd; - mx3_fbi->txd->callback = mx3fb_dma_done; - - cookie = mx3_fbi->txd->tx_submit(mx3_fbi->txd); - dev_dbg(mx3fb->dev, "%d: Submit %p #%d [%c]\n", __LINE__, - mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+'); - } else { - if (!mx3_fbi->txd || !mx3_fbi->txd->tx_submit) { - dev_err(mx3fb->dev, "Cannot enable channel %d\n", - dma_chan->chan_id); - return; - } - - /* Just re-activate the same buffer */ - dma_async_issue_pending(dma_chan); - cookie = mx3_fbi->cookie; - dev_dbg(mx3fb->dev, "%d: Re-submit %p #%d [%c]\n", __LINE__, - mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+'); - } - - if (cookie >= 0) { - spin_lock_irqsave(&mx3fb->lock, flags); - sdc_fb_init(mx3_fbi); - mx3_fbi->cookie = cookie; - spin_unlock_irqrestore(&mx3fb->lock, flags); - } - - /* - * Attention! Without this msleep the channel keeps generating - * interrupts. Next sdc_set_brightness() is going to be called - * from mx3fb_blank(). - */ - msleep(2); + struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; + struct idmac_channel *ichan = mx3_fbi->idmac_channel; + struct dma_chan *dma_chan = &ichan->dma_chan; + unsigned long flags; + dma_cookie_t cookie; + + dev_dbg(mx3fb->dev, "mx3fbi %p, desc %p, sg %p\n", mx3_fbi, + to_tx_desc(mx3_fbi->txd), to_tx_desc(mx3_fbi->txd)->sg); + + /* This enables the channel */ + if (mx3_fbi->cookie < 0) { + mx3_fbi->txd = dma_chan->device->device_prep_slave_sg(dma_chan, + &mx3_fbi->sg[0], 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT); + if (!mx3_fbi->txd) { + dev_err(mx3fb->dev, "Cannot allocate descriptor on %d\n", + dma_chan->chan_id); + return; + } + + mx3_fbi->txd->callback_param = mx3_fbi->txd; + mx3_fbi->txd->callback = mx3fb_dma_done; + + cookie = mx3_fbi->txd->tx_submit(mx3_fbi->txd); + dev_dbg(mx3fb->dev, "%d: Submit %p #%d [%c]\n", __LINE__, + mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+'); + } else { + if (!mx3_fbi->txd || !mx3_fbi->txd->tx_submit) { + dev_err(mx3fb->dev, "Cannot enable channel %d\n", + dma_chan->chan_id); + return; + } + + /* Just re-activate the same buffer */ + dma_async_issue_pending(dma_chan); + cookie = mx3_fbi->cookie; + dev_dbg(mx3fb->dev, "%d: Re-submit %p #%d [%c]\n", __LINE__, + mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+'); + } + + if (cookie >= 0) { + spin_lock_irqsave(&mx3fb->lock, flags); + sdc_fb_init(mx3_fbi); + mx3_fbi->cookie = cookie; + spin_unlock_irqrestore(&mx3fb->lock, flags); + } + + /* + * Attention! Without this msleep the channel keeps generating + * interrupts. Next sdc_set_brightness() is going to be called + * from mx3fb_blank(). + */ + msleep(2); } static void sdc_disable_channel(struct mx3fb_info *mx3_fbi) { - struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; - uint32_t enabled; - unsigned long flags; + struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; + uint32_t enabled; + unsigned long flags; - spin_lock_irqsave(&mx3fb->lock, flags); + spin_lock_irqsave(&mx3fb->lock, flags); - enabled = sdc_fb_uninit(mx3_fbi); + enabled = sdc_fb_uninit(mx3_fbi); - spin_unlock_irqrestore(&mx3fb->lock, flags); + spin_unlock_irqrestore(&mx3fb->lock, flags); - mx3_fbi->txd->chan->device->device_terminate_all(mx3_fbi->txd->chan); - mx3_fbi->txd = NULL; - mx3_fbi->cookie = -EINVAL; + mx3_fbi->txd->chan->device->device_terminate_all(mx3_fbi->txd->chan); + mx3_fbi->txd = NULL; + mx3_fbi->cookie = -EINVAL; } /** * sdc_set_window_pos() - set window position of the respective plane. - * @mx3fb: mx3fb context. - * @channel: IPU DMAC channel ID. - * @x_pos: X coordinate relative to the top left corner to place window at. - * @y_pos: Y coordinate relative to the top left corner to place window at. - * @return: 0 on success or negative error code on failure. + * @mx3fb: mx3fb context. + * @channel: IPU DMAC channel ID. + * @x_pos: X coordinate relative to the top left corner to place window at. + * @y_pos: Y coordinate relative to the top left corner to place window at. + * @return: 0 on success or negative error code on failure. */ static int sdc_set_window_pos(struct mx3fb_data *mx3fb, enum ipu_channel channel, - int16_t x_pos, int16_t y_pos) + int16_t x_pos, int16_t y_pos) { - x_pos += mx3fb->h_start_width; - y_pos += mx3fb->v_start_width; + x_pos += mx3fb->h_start_width; + y_pos += mx3fb->v_start_width; - if (channel != IDMAC_SDC_0) - return -EINVAL; + if (channel != IDMAC_SDC_0) + return -EINVAL; - mx3fb_write_reg(mx3fb, (x_pos << 16) | y_pos, SDC_BG_POS); - return 0; + mx3fb_write_reg(mx3fb, (x_pos << 16) | y_pos, SDC_BG_POS); + return 0; } /** * sdc_init_panel() - initialize a synchronous LCD panel. - * @mx3fb: mx3fb context. - * @panel: panel type. - * @pixel_clk: desired pixel clock frequency in Hz. - * @width: width of panel in pixels. - * @height: height of panel in pixels. - * @pixel_fmt: pixel format of buffer as FOURCC ASCII code. - * @h_start_width: number of pixel clocks between the HSYNC signal pulse - * and the start of valid data. - * @h_sync_width: width of the HSYNC signal in units of pixel clocks. - * @h_end_width: number of pixel clocks between the end of valid data - * and the HSYNC signal for next line. - * @v_start_width: number of lines between the VSYNC signal pulse and the - * start of valid data. - * @v_sync_width: width of the VSYNC signal in units of lines - * @v_end_width: number of lines between the end of valid data and the - * VSYNC signal for next frame. - * @sig: bitfield of signal polarities for LCD interface. - * @return: 0 on success or negative error code on failure. + * @mx3fb: mx3fb context. + * @panel: panel type. + * @pixel_clk: desired pixel clock frequency in Hz. + * @width: width of panel in pixels. + * @height: height of panel in pixels. + * @pixel_fmt: pixel format of buffer as FOURCC ASCII code. + * @h_start_width: number of pixel clocks between the HSYNC signal pulse + * and the start of valid data. + * @h_sync_width: width of the HSYNC signal in units of pixel clocks. + * @h_end_width: number of pixel clocks between the end of valid data + * and the HSYNC signal for next line. + * @v_start_width: number of lines between the VSYNC signal pulse and the + * start of valid data. + * @v_sync_width: width of the VSYNC signal in units of lines + * @v_end_width: number of lines between the end of valid data and the + * VSYNC signal for next frame. + * @sig: bitfield of signal polarities for LCD interface. + * @return: 0 on success or negative error code on failure. */ static int sdc_init_panel(struct mx3fb_data *mx3fb, enum ipu_panel panel, - uint32_t pixel_clk, - uint16_t width, uint16_t height, - enum pixel_fmt pixel_fmt, - uint16_t h_start_width, uint16_t h_sync_width, - uint16_t h_end_width, uint16_t v_start_width, - uint16_t v_sync_width, uint16_t v_end_width, - struct ipu_di_signal_cfg sig) + uint32_t pixel_clk, + uint16_t width, uint16_t height, + enum pixel_fmt pixel_fmt, + uint16_t h_start_width, uint16_t h_sync_width, + uint16_t h_end_width, uint16_t v_start_width, + uint16_t v_sync_width, uint16_t v_end_width, + struct ipu_di_signal_cfg sig) { - unsigned long lock_flags; - uint32_t reg; - uint32_t old_conf; - uint32_t div; - struct clk *ipu_clk; + unsigned long lock_flags; + uint32_t reg; + uint32_t old_conf; + uint32_t div; + struct clk *ipu_clk; - dev_dbg(mx3fb->dev, "panel size = %d x %d", width, height); + dev_dbg(mx3fb->dev, "panel size = %d x %d", width, height); - if (v_sync_width == 0 || h_sync_width == 0) - return -EINVAL; + if (v_sync_width == 0 || h_sync_width == 0) + return -EINVAL; - /* Init panel size and blanking periods */ - reg = ((uint32_t) (h_sync_width - 1) << 26) | - ((uint32_t) (width + h_start_width + h_end_width - 1) << 16); - mx3fb_write_reg(mx3fb, reg, SDC_HOR_CONF); + /* Init panel size and blanking periods */ + reg = ((uint32_t) (h_sync_width - 1) << 26) | + ((uint32_t) (width + h_start_width + h_end_width - 1) << 16); + mx3fb_write_reg(mx3fb, reg, SDC_HOR_CONF); #ifdef DEBUG - printk(KERN_CONT " hor_conf %x,", reg); + printk(KERN_CONT " hor_conf %x,", reg); #endif - reg = ((uint32_t) (v_sync_width - 1) << 26) | SDC_V_SYNC_WIDTH_L | - ((uint32_t) (height + v_start_width + v_end_width - 1) << 16); - mx3fb_write_reg(mx3fb, reg, SDC_VER_CONF); + reg = ((uint32_t) (v_sync_width - 1) << 26) | SDC_V_SYNC_WIDTH_L | + ((uint32_t) (height + v_start_width + v_end_width - 1) << 16); + mx3fb_write_reg(mx3fb, reg, SDC_VER_CONF); #ifdef DEBUG - printk(KERN_CONT " ver_conf %x\n", reg); + printk(KERN_CONT " ver_conf %x\n", reg); #endif - mx3fb->h_start_width = h_start_width; - mx3fb->v_start_width = v_start_width; - - switch (panel) { - case IPU_PANEL_SHARP_TFT: - mx3fb_write_reg(mx3fb, 0x00FD0102L, SDC_SHARP_CONF_1); - mx3fb_write_reg(mx3fb, 0x00F500F4L, SDC_SHARP_CONF_2); - mx3fb_write_reg(mx3fb, SDC_COM_SHARP | SDC_COM_TFT_COLOR, SDC_COM_CONF); - break; - case IPU_PANEL_TFT: - mx3fb_write_reg(mx3fb, SDC_COM_TFT_COLOR, SDC_COM_CONF); - break; - default: - return -EINVAL; - } - - /* Init clocking */ - - /* - * Calculate divider: fractional part is 4 bits so simply multiple by - * 24 to get fractional part, as long as we stay under ~250MHz and on - * i.MX31 it (HSP_CLK) is <= 178MHz. Currently 128.267MHz - */ - dev_dbg(mx3fb->dev, "pixel clk = %d\n", pixel_clk); - - ipu_clk = clk_get(mx3fb->dev, "ipu_clk"); - div = clk_get_rate(ipu_clk) * 16 / pixel_clk; - clk_put(ipu_clk); - - if (div < 0x40) { /* Divider less than 4 */ - dev_dbg(mx3fb->dev, - "InitPanel() - Pixel clock divider less than 4\n"); - div = 0x40; - } - - spin_lock_irqsave(&mx3fb->lock, lock_flags); - - /* - * DISP3_IF_CLK_DOWN_WR is half the divider value and 2 fraction bits - * fewer. Subtract 1 extra from DISP3_IF_CLK_DOWN_WR based on timing - * debug. DISP3_IF_CLK_UP_WR is 0 - */ - mx3fb_write_reg(mx3fb, (((div / 8) - 1) << 22) | div, DI_DISP3_TIME_CONF); - - /* DI settings */ - old_conf = mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF) & 0x78FFFFFF; - old_conf |= sig.datamask_en << DI_D3_DATAMSK_SHIFT | - sig.clksel_en << DI_D3_CLK_SEL_SHIFT | - sig.clkidle_en << DI_D3_CLK_IDLE_SHIFT; - mx3fb_write_reg(mx3fb, old_conf, DI_DISP_IF_CONF); - - old_conf = mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL) & 0xE0FFFFFF; - old_conf |= sig.data_pol << DI_D3_DATA_POL_SHIFT | - sig.clk_pol << DI_D3_CLK_POL_SHIFT | - sig.enable_pol << DI_D3_DRDY_SHARP_POL_SHIFT | - sig.Hsync_pol << DI_D3_HSYNC_POL_SHIFT | - sig.Vsync_pol << DI_D3_VSYNC_POL_SHIFT; - mx3fb_write_reg(mx3fb, old_conf, DI_DISP_SIG_POL); - - switch (pixel_fmt) { - case IPU_PIX_FMT_RGB24: - mx3fb_write_reg(mx3fb, di_mappings[0], DI_DISP3_B0_MAP); - mx3fb_write_reg(mx3fb, di_mappings[1], DI_DISP3_B1_MAP); - mx3fb_write_reg(mx3fb, di_mappings[2], DI_DISP3_B2_MAP); - mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) | - ((di_mappings[3] - 1) << 12), DI_DISP_ACC_CC); - break; - case IPU_PIX_FMT_RGB666: - mx3fb_write_reg(mx3fb, di_mappings[4], DI_DISP3_B0_MAP); - mx3fb_write_reg(mx3fb, di_mappings[5], DI_DISP3_B1_MAP); - mx3fb_write_reg(mx3fb, di_mappings[6], DI_DISP3_B2_MAP); - mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) | - ((di_mappings[7] - 1) << 12), DI_DISP_ACC_CC); - break; - case IPU_PIX_FMT_BGR666: - mx3fb_write_reg(mx3fb, di_mappings[8], DI_DISP3_B0_MAP); - mx3fb_write_reg(mx3fb, di_mappings[9], DI_DISP3_B1_MAP); - mx3fb_write_reg(mx3fb, di_mappings[10], DI_DISP3_B2_MAP); - mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) | - ((di_mappings[11] - 1) << 12), DI_DISP_ACC_CC); - break; - default: - mx3fb_write_reg(mx3fb, di_mappings[12], DI_DISP3_B0_MAP); - mx3fb_write_reg(mx3fb, di_mappings[13], DI_DISP3_B1_MAP); - mx3fb_write_reg(mx3fb, di_mappings[14], DI_DISP3_B2_MAP); - mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) | - ((di_mappings[15] - 1) << 12), DI_DISP_ACC_CC); - break; - } - - spin_unlock_irqrestore(&mx3fb->lock, lock_flags); - - dev_dbg(mx3fb->dev, "DI_DISP_IF_CONF = 0x%08X\n", - mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF)); - dev_dbg(mx3fb->dev, "DI_DISP_SIG_POL = 0x%08X\n", - mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL)); - dev_dbg(mx3fb->dev, "DI_DISP3_TIME_CONF = 0x%08X\n", - mx3fb_read_reg(mx3fb, DI_DISP3_TIME_CONF)); - - return 0; + mx3fb->h_start_width = h_start_width; + mx3fb->v_start_width = v_start_width; + + switch (panel) { + case IPU_PANEL_SHARP_TFT: + mx3fb_write_reg(mx3fb, 0x00FD0102L, SDC_SHARP_CONF_1); + mx3fb_write_reg(mx3fb, 0x00F500F4L, SDC_SHARP_CONF_2); + mx3fb_write_reg(mx3fb, SDC_COM_SHARP | SDC_COM_TFT_COLOR, SDC_COM_CONF); + break; + case IPU_PANEL_TFT: + mx3fb_write_reg(mx3fb, SDC_COM_TFT_COLOR, SDC_COM_CONF); + break; + default: + return -EINVAL; + } + + /* Init clocking */ + + /* + * Calculate divider: fractional part is 4 bits so simply multiple by + * 2^4 to get fractional part, as long as we stay under ~250MHz and on + * i.MX31 it (HSP_CLK) is <= 178MHz. Currently 128.267MHz + */ + dev_dbg(mx3fb->dev, "pixel clk = %d\n", pixel_clk); + + ipu_clk = clk_get(mx3fb->dev, NULL); + div = clk_get_rate(ipu_clk) * 16 / pixel_clk; + clk_put(ipu_clk); + + if (div < 0x40) { /* Divider less than 4 */ + dev_dbg(mx3fb->dev, + "InitPanel() - Pixel clock divider less than 4\n"); + div = 0x40; + } + + spin_lock_irqsave(&mx3fb->lock, lock_flags); + + /* + * DISP3_IF_CLK_DOWN_WR is half the divider value and 2 fraction bits + * fewer. Subtract 1 extra from DISP3_IF_CLK_DOWN_WR based on timing + * debug. DISP3_IF_CLK_UP_WR is 0 + */ + mx3fb_write_reg(mx3fb, (((div / 8) - 1) << 22) | div, DI_DISP3_TIME_CONF); + + /* DI settings */ + old_conf = mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF) & 0x78FFFFFF; + old_conf |= sig.datamask_en << DI_D3_DATAMSK_SHIFT | + sig.clksel_en << DI_D3_CLK_SEL_SHIFT | + sig.clkidle_en << DI_D3_CLK_IDLE_SHIFT; + mx3fb_write_reg(mx3fb, old_conf, DI_DISP_IF_CONF); + + old_conf = mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL) & 0xE0FFFFFF; + old_conf |= sig.data_pol << DI_D3_DATA_POL_SHIFT | + sig.clk_pol << DI_D3_CLK_POL_SHIFT | + sig.enable_pol << DI_D3_DRDY_SHARP_POL_SHIFT | + sig.Hsync_pol << DI_D3_HSYNC_POL_SHIFT | + sig.Vsync_pol << DI_D3_VSYNC_POL_SHIFT; + mx3fb_write_reg(mx3fb, old_conf, DI_DISP_SIG_POL); + + switch (pixel_fmt) { + case IPU_PIX_FMT_RGB24: + mx3fb_write_reg(mx3fb, di_mappings[0], DI_DISP3_B0_MAP); + mx3fb_write_reg(mx3fb, di_mappings[1], DI_DISP3_B1_MAP); + mx3fb_write_reg(mx3fb, di_mappings[2], DI_DISP3_B2_MAP); + mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) | + ((di_mappings[3] - 1) << 12), DI_DISP_ACC_CC); + break; + case IPU_PIX_FMT_RGB666: + mx3fb_write_reg(mx3fb, di_mappings[4], DI_DISP3_B0_MAP); + mx3fb_write_reg(mx3fb, di_mappings[5], DI_DISP3_B1_MAP); + mx3fb_write_reg(mx3fb, di_mappings[6], DI_DISP3_B2_MAP); + mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) | + ((di_mappings[7] - 1) << 12), DI_DISP_ACC_CC); + break; + case IPU_PIX_FMT_BGR666: + mx3fb_write_reg(mx3fb, di_mappings[8], DI_DISP3_B0_MAP); + mx3fb_write_reg(mx3fb, di_mappings[9], DI_DISP3_B1_MAP); + mx3fb_write_reg(mx3fb, di_mappings[10], DI_DISP3_B2_MAP); + mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) | + ((di_mappings[11] - 1) << 12), DI_DISP_ACC_CC); + break; + default: + mx3fb_write_reg(mx3fb, di_mappings[12], DI_DISP3_B0_MAP); + mx3fb_write_reg(mx3fb, di_mappings[13], DI_DISP3_B1_MAP); + mx3fb_write_reg(mx3fb, di_mappings[14], DI_DISP3_B2_MAP); + mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) | + ((di_mappings[15] - 1) << 12), DI_DISP_ACC_CC); + break; + } + + spin_unlock_irqrestore(&mx3fb->lock, lock_flags); + + dev_dbg(mx3fb->dev, "DI_DISP_IF_CONF = 0x%08X\n", + mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF)); + dev_dbg(mx3fb->dev, "DI_DISP_SIG_POL = 0x%08X\n", + mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL)); + dev_dbg(mx3fb->dev, "DI_DISP3_TIME_CONF = 0x%08X\n", + mx3fb_read_reg(mx3fb, DI_DISP3_TIME_CONF)); + + return 0; } /** * sdc_set_color_key() - set the transparent color key for SDC graphic plane. - * @mx3fb: mx3fb context. - * @channel: IPU DMAC channel ID. - * @enable: boolean to enable or disable color keyl. - * @color_key: 24-bit RGB color to use as transparent color key. - * @return: 0 on success or negative error code on failure. + * @mx3fb: mx3fb context. + * @channel: IPU DMAC channel ID. + * @enable: boolean to enable or disable color keyl. + * @color_key: 24-bit RGB color to use as transparent color key. + * @return: 0 on success or negative error code on failure. */ static int sdc_set_color_key(struct mx3fb_data *mx3fb, enum ipu_channel channel, - bool enable, uint32_t color_key) + bool enable, uint32_t color_key) { - uint32_t reg, sdc_conf; - unsigned long lock_flags; + uint32_t reg, sdc_conf; + unsigned long lock_flags; - spin_lock_irqsave(&mx3fb->lock, lock_flags); + spin_lock_irqsave(&mx3fb->lock, lock_flags); - sdc_conf = mx3fb_read_reg(mx3fb, SDC_COM_CONF); - if (channel == IDMAC_SDC_0) - sdc_conf &= ~SDC_COM_GWSEL; - else - sdc_conf |= SDC_COM_GWSEL; + sdc_conf = mx3fb_read_reg(mx3fb, SDC_COM_CONF); + if (channel == IDMAC_SDC_0) + sdc_conf &= ~SDC_COM_GWSEL; + else + sdc_conf |= SDC_COM_GWSEL; - if (enable) { - reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0xFF000000L; - mx3fb_write_reg(mx3fb, reg | (color_key & 0x00FFFFFFL), - SDC_GW_CTRL); + if (enable) { + reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0xFF000000L; + mx3fb_write_reg(mx3fb, reg | (color_key & 0x00FFFFFFL), + SDC_GW_CTRL); - sdc_conf |= SDC_COM_KEY_COLOR_G; - } else { - sdc_conf &= ~SDC_COM_KEY_COLOR_G; - } - mx3fb_write_reg(mx3fb, sdc_conf, SDC_COM_CONF); + sdc_conf |= SDC_COM_KEY_COLOR_G; + } else { + sdc_conf &= ~SDC_COM_KEY_COLOR_G; + } + mx3fb_write_reg(mx3fb, sdc_conf, SDC_COM_CONF); - spin_unlock_irqrestore(&mx3fb->lock, lock_flags); + spin_unlock_irqrestore(&mx3fb->lock, lock_flags); - return 0; + return 0; } /** * sdc_set_global_alpha() - set global alpha blending modes. - * @mx3fb: mx3fb context. - * @enable: boolean to enable or disable global alpha blending. If disabled, - * per pixel blending is used. - * @alpha: global alpha value. - * @return: 0 on success or negative error code on failure. + * @mx3fb: mx3fb context. + * @enable: boolean to enable or disable global alpha blending. If disabled, + * per pixel blending is used. + * @alpha: global alpha value. + * @return: 0 on success or negative error code on failure. */ static int sdc_set_global_alpha(struct mx3fb_data *mx3fb, bool enable, uint8_t alpha) { - uint32_t reg; - unsigned long lock_flags; + uint32_t reg; + unsigned long lock_flags; - spin_lock_irqsave(&mx3fb->lock, lock_flags); + spin_lock_irqsave(&mx3fb->lock, lock_flags); - if (enable) { - reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0x00FFFFFFL; - mx3fb_write_reg(mx3fb, reg | ((uint32_t) alpha << 24), SDC_GW_CTRL); + if (enable) { + reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0x00FFFFFFL; + mx3fb_write_reg(mx3fb, reg | ((uint32_t) alpha << 24), SDC_GW_CTRL); - reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); - mx3fb_write_reg(mx3fb, reg | SDC_COM_GLB_A, SDC_COM_CONF); - } else { - reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); - mx3fb_write_reg(mx3fb, reg & ~SDC_COM_GLB_A, SDC_COM_CONF); - } + reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); + mx3fb_write_reg(mx3fb, reg | SDC_COM_GLB_A, SDC_COM_CONF); + } else { + reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); + mx3fb_write_reg(mx3fb, reg & ~SDC_COM_GLB_A, SDC_COM_CONF); + } - spin_unlock_irqrestore(&mx3fb->lock, lock_flags); + spin_unlock_irqrestore(&mx3fb->lock, lock_flags); - return 0; + return 0; } static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value) { - /* This might be board-specific */ - mx3fb_write_reg(mx3fb, 0x03000000UL | value << 16, SDC_PWM_CTRL); - return; + /* This might be board-specific */ + mx3fb_write_reg(mx3fb, 0x03000000UL | value << 16, SDC_PWM_CTRL); + return; } static uint32_t bpp_to_pixfmt(int bpp) { - uint32_t pixfmt = 0; - switch (bpp) { - case 24: - pixfmt = IPU_PIX_FMT_BGR24; - break; - case 32: - pixfmt = IPU_PIX_FMT_BGR32; - break; - case 16: - pixfmt = IPU_PIX_FMT_RGB565; - break; - } - return pixfmt; + uint32_t pixfmt = 0; + switch (bpp) { + case 24: + pixfmt = IPU_PIX_FMT_BGR24; + break; + case 32: + pixfmt = IPU_PIX_FMT_BGR32; + break; + case 16: + pixfmt = IPU_PIX_FMT_RGB565; + break; + } + return pixfmt; } static int mx3fb_blank(int blank, struct fb_info *fbi); @@ -669,300 +669,300 @@ static int mx3fb_unmap_video_memory(struct fb_info *fbi); /** * mx3fb_set_fix() - set fixed framebuffer parameters from variable settings. - * @info: framebuffer information pointer - * @return: 0 on success or negative error code on failure. + * @info: framebuffer information pointer + * @return: 0 on success or negative error code on failure. */ static int mx3fb_set_fix(struct fb_info *fbi) { - struct fb_fix_screeninfo *fix = &fbi->fix; - struct fb_var_screeninfo *var = &fbi->var; + struct fb_fix_screeninfo *fix = &fbi->fix; + struct fb_var_screeninfo *var = &fbi->var; - strncpy(fix->id, "DISP3 BG", 8); + strncpy(fix->id, "DISP3 BG", 8); - fix->line_length = var->xres_virtual * var->bits_per_pixel / 8; + fix->line_length = var->xres_virtual * var->bits_per_pixel / 8; - fix->type = FB_TYPE_PACKED_PIXELS; - fix->accel = FB_ACCEL_NONE; - fix->visual = FB_VISUAL_TRUECOLOR; - fix->xpanstep = 1; - fix->ypanstep = 1; + fix->type = FB_TYPE_PACKED_PIXELS; + fix->accel = FB_ACCEL_NONE; + fix->visual = FB_VISUAL_TRUECOLOR; + fix->xpanstep = 1; + fix->ypanstep = 1; - return 0; + return 0; } static void mx3fb_dma_done(void *arg) { - struct idmac_tx_desc *tx_desc = to_tx_desc(arg); - struct dma_chan *chan = tx_desc->txd.chan; - struct idmac_channel *ichannel = to_idmac_chan(chan); - struct mx3fb_data *mx3fb = ichannel->client; - struct mx3fb_info *mx3_fbi = mx3fb->fbi->par; + struct idmac_tx_desc *tx_desc = to_tx_desc(arg); + struct dma_chan *chan = tx_desc->txd.chan; + struct idmac_channel *ichannel = to_idmac_chan(chan); + struct mx3fb_data *mx3fb = ichannel->client; + struct mx3fb_info *mx3_fbi = mx3fb->fbi->par; - dev_dbg(mx3fb->dev, "irq %d callback\n", ichannel->eof_irq); + dev_dbg(mx3fb->dev, "irq %d callback\n", ichannel->eof_irq); - /* We only need one interrupt, it will be re-enabled as needed */ - disable_irq(ichannel->eof_irq); + /* We only need one interrupt, it will be re-enabled as needed */ + disable_irq(ichannel->eof_irq); - complete(&mx3_fbi->flip_cmpl); + complete(&mx3_fbi->flip_cmpl); } /** * mx3fb_set_par() - set framebuffer parameters and change the operating mode. - * @fbi: framebuffer information pointer. - * @return: 0 on success or negative error code on failure. + * @fbi: framebuffer information pointer. + * @return: 0 on success or negative error code on failure. */ static int mx3fb_set_par(struct fb_info *fbi) { - u32 mem_len; - struct ipu_di_signal_cfg sig_cfg; - enum ipu_panel mode = IPU_PANEL_TFT; - struct mx3fb_info *mx3_fbi = fbi->par; - struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; - struct idmac_channel *ichan = mx3_fbi->idmac_channel; - struct idmac_video_param *video = &ichan->params.video; - struct scatterlist *sg = mx3_fbi->sg; - size_t screen_size; - - dev_dbg(mx3fb->dev, "%s [%c]\n", __func__, list_empty(&ichan->queue) ? '-' : '+'); - - mutex_lock(&mx3_fbi->mutex); - - /* Total cleanup */ - if (mx3_fbi->txd) - sdc_disable_channel(mx3_fbi); - - mx3fb_set_fix(fbi); - - mem_len = fbi->var.yres_virtual * fbi->fix.line_length; - if (mem_len > fbi->fix.smem_len) { - if (fbi->fix.smem_start) - mx3fb_unmap_video_memory(fbi); - - fbi->fix.smem_len = mem_len; - if (mx3fb_map_video_memory(fbi) < 0) { - mutex_unlock(&mx3_fbi->mutex); - return -ENOMEM; - } - } - - screen_size = fbi->fix.line_length * fbi->var.yres; - - sg_init_table(&sg[0], 1); - sg_init_table(&sg[1], 1); - - sg_dma_address(&sg[0]) = fbi->fix.smem_start; - sg_set_page(&sg[0], virt_to_page(fbi->screen_base), - fbi->fix.smem_len, - offset_in_page(fbi->screen_base)); - - if (mx3_fbi->ipu_ch == IDMAC_SDC_0) { - memset(&sig_cfg, 0, sizeof(sig_cfg)); - if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT) - sig_cfg.Hsync_pol = true; - if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT) - sig_cfg.Vsync_pol = true; - if (fbi->var.sync & FB_SYNC_CLK_INVERT) - sig_cfg.clk_pol = true; - if (fbi->var.sync & FB_SYNC_DATA_INVERT) - sig_cfg.data_pol = true; - if (fbi->var.sync & FB_SYNC_OE_ACT_HIGH) - sig_cfg.enable_pol = true; - if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN) - sig_cfg.clkidle_en = true; - if (fbi->var.sync & FB_SYNC_CLK_SEL_EN) - sig_cfg.clksel_en = true; - if (fbi->var.sync & FB_SYNC_SHARP_MODE) - mode = IPU_PANEL_SHARP_TFT; - - dev_dbg(fbi->device, "pixclock = %ul Hz\n", - (u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL)); - - if (sdc_init_panel(mx3fb, mode, - (PICOS2KHZ(fbi->var.pixclock)) * 1000UL, - fbi->var.xres, fbi->var.yres, - (fbi->var.sync & FB_SYNC_SWAP_RGB) ? - IPU_PIX_FMT_BGR666 : IPU_PIX_FMT_RGB666, - fbi->var.left_margin, - fbi->var.hsync_len, - fbi->var.right_margin + - fbi->var.hsync_len, - fbi->var.upper_margin, - fbi->var.vsync_len, - fbi->var.lower_margin + - fbi->var.vsync_len, sig_cfg) != 0) { - mutex_unlock(&mx3_fbi->mutex); - dev_err(fbi->device, - "mx3fb: Error initializing panel.\n"); - return -EINVAL; - } - } - - sdc_set_window_pos(mx3fb, mx3_fbi->ipu_ch, 0, 0); - - mx3_fbi->cur_ipu_buf = 0; - - video->out_pixel_fmt = bpp_to_pixfmt(fbi->var.bits_per_pixel); - video->out_width = fbi->var.xres; - video->out_height = fbi->var.yres; - video->out_stride = fbi->var.xres_virtual; - - if (mx3_fbi->blank == FB_BLANK_UNBLANK) - sdc_enable_channel(mx3_fbi); - - mutex_unlock(&mx3_fbi->mutex); - - return 0; + u32 mem_len; + struct ipu_di_signal_cfg sig_cfg; + enum ipu_panel mode = IPU_PANEL_TFT; + struct mx3fb_info *mx3_fbi = fbi->par; + struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; + struct idmac_channel *ichan = mx3_fbi->idmac_channel; + struct idmac_video_param *video = &ichan->params.video; + struct scatterlist *sg = mx3_fbi->sg; + size_t screen_size; + + dev_dbg(mx3fb->dev, "%s [%c]\n", __func__, list_empty(&ichan->queue) ? '-' : '+'); + + mutex_lock(&mx3_fbi->mutex); + + /* Total cleanup */ + if (mx3_fbi->txd) + sdc_disable_channel(mx3_fbi); + + mx3fb_set_fix(fbi); + + mem_len = fbi->var.yres_virtual * fbi->fix.line_length; + if (mem_len > fbi->fix.smem_len) { + if (fbi->fix.smem_start) + mx3fb_unmap_video_memory(fbi); + + fbi->fix.smem_len = mem_len; + if (mx3fb_map_video_memory(fbi) < 0) { + mutex_unlock(&mx3_fbi->mutex); + return -ENOMEM; + } + } + + screen_size = fbi->fix.line_length * fbi->var.yres; + + sg_init_table(&sg[0], 1); + sg_init_table(&sg[1], 1); + + sg_dma_address(&sg[0]) = fbi->fix.smem_start; + sg_set_page(&sg[0], virt_to_page(fbi->screen_base), + fbi->fix.smem_len, + offset_in_page(fbi->screen_base)); + + if (mx3_fbi->ipu_ch == IDMAC_SDC_0) { + memset(&sig_cfg, 0, sizeof(sig_cfg)); + if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT) + sig_cfg.Hsync_pol = true; + if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT) + sig_cfg.Vsync_pol = true; + if (fbi->var.sync & FB_SYNC_CLK_INVERT) + sig_cfg.clk_pol = true; + if (fbi->var.sync & FB_SYNC_DATA_INVERT) + sig_cfg.data_pol = true; + if (fbi->var.sync & FB_SYNC_OE_ACT_HIGH) + sig_cfg.enable_pol = true; + if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN) + sig_cfg.clkidle_en = true; + if (fbi->var.sync & FB_SYNC_CLK_SEL_EN) + sig_cfg.clksel_en = true; + if (fbi->var.sync & FB_SYNC_SHARP_MODE) + mode = IPU_PANEL_SHARP_TFT; + + dev_dbg(fbi->device, "pixclock = %ul Hz\n", + (u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL)); + + if (sdc_init_panel(mx3fb, mode, + (PICOS2KHZ(fbi->var.pixclock)) * 1000UL, + fbi->var.xres, fbi->var.yres, + (fbi->var.sync & FB_SYNC_SWAP_RGB) ? + IPU_PIX_FMT_BGR666 : IPU_PIX_FMT_RGB666, + fbi->var.left_margin, + fbi->var.hsync_len, + fbi->var.right_margin + + fbi->var.hsync_len, + fbi->var.upper_margin, + fbi->var.vsync_len, + fbi->var.lower_margin + + fbi->var.vsync_len, sig_cfg) != 0) { + mutex_unlock(&mx3_fbi->mutex); + dev_err(fbi->device, + "mx3fb: Error initializing panel.\n"); + return -EINVAL; + } + } + + sdc_set_window_pos(mx3fb, mx3_fbi->ipu_ch, 0, 0); + + mx3_fbi->cur_ipu_buf = 0; + + video->out_pixel_fmt = bpp_to_pixfmt(fbi->var.bits_per_pixel); + video->out_width = fbi->var.xres; + video->out_height = fbi->var.yres; + video->out_stride = fbi->var.xres_virtual; + + if (mx3_fbi->blank == FB_BLANK_UNBLANK) + sdc_enable_channel(mx3_fbi); + + mutex_unlock(&mx3_fbi->mutex); + + return 0; } /** * mx3fb_check_var() - check and adjust framebuffer variable parameters. - * @var: framebuffer variable parameters - * @fbi: framebuffer information pointer + * @var: framebuffer variable parameters + * @fbi: framebuffer information pointer */ static int mx3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi) { - struct mx3fb_info *mx3_fbi = fbi->par; - u32 vtotal; - u32 htotal; - - dev_dbg(fbi->device, "%s\n", __func__); - - if (var->xres_virtual < var->xres) - var->xres_virtual = var->xres; - if (var->yres_virtual < var->yres) - var->yres_virtual = var->yres; - - if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 24) && - (var->bits_per_pixel != 16)) - var->bits_per_pixel = default_bpp; - - switch (var->bits_per_pixel) { - case 16: - var->red.length = 5; - var->red.offset = 11; - var->red.msb_right = 0; - - var->green.length = 6; - var->green.offset = 5; - var->green.msb_right = 0; - - var->blue.length = 5; - var->blue.offset = 0; - var->blue.msb_right = 0; - - var->transp.length = 0; - var->transp.offset = 0; - var->transp.msb_right = 0; - break; - case 24: - var->red.length = 8; - var->red.offset = 16; - var->red.msb_right = 0; - - var->green.length = 8; - var->green.offset = 8; - var->green.msb_right = 0; - - var->blue.length = 8; - var->blue.offset = 0; - var->blue.msb_right = 0; - - var->transp.length = 0; - var->transp.offset = 0; - var->transp.msb_right = 0; - break; - case 32: - var->red.length = 8; - var->red.offset = 16; - var->red.msb_right = 0; - - var->green.length = 8; - var->green.offset = 8; - var->green.msb_right = 0; - - var->blue.length = 8; - var->blue.offset = 0; - var->blue.msb_right = 0; - - var->transp.length = 8; - var->transp.offset = 24; - var->transp.msb_right = 0; - break; - } - - if (var->pixclock < 1000) { - htotal = var->xres + var->right_margin + var->hsync_len + - var->left_margin; - vtotal = var->yres + var->lower_margin + var->vsync_len + - var->upper_margin; - var->pixclock = (vtotal * htotal * 6UL) / 100UL; - var->pixclock = KHZ2PICOS(var->pixclock); - dev_dbg(fbi->device, "pixclock set for 60Hz refresh = %u ps\n", - var->pixclock); - } - - var->height = -1; - var->width = -1; - var->grayscale = 0; - - /* Preserve sync flags */ - var->sync |= mx3_fbi->sync; - mx3_fbi->sync |= var->sync; - - return 0; + struct mx3fb_info *mx3_fbi = fbi->par; + u32 vtotal; + u32 htotal; + + dev_dbg(fbi->device, "%s\n", __func__); + + if (var->xres_virtual < var->xres) + var->xres_virtual = var->xres; + if (var->yres_virtual < var->yres) + var->yres_virtual = var->yres; + + if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 24) && + (var->bits_per_pixel != 16)) + var->bits_per_pixel = default_bpp; + + switch (var->bits_per_pixel) { + case 16: + var->red.length = 5; + var->red.offset = 11; + var->red.msb_right = 0; + + var->green.length = 6; + var->green.offset = 5; + var->green.msb_right = 0; + + var->blue.length = 5; + var->blue.offset = 0; + var->blue.msb_right = 0; + + var->transp.length = 0; + var->transp.offset = 0; + var->transp.msb_right = 0; + break; + case 24: + var->red.length = 8; + var->red.offset = 16; + var->red.msb_right = 0; + + var->green.length = 8; + var->green.offset = 8; + var->green.msb_right = 0; + + var->blue.length = 8; + var->blue.offset = 0; + var->blue.msb_right = 0; + + var->transp.length = 0; + var->transp.offset = 0; + var->transp.msb_right = 0; + break; + case 32: + var->red.length = 8; + var->red.offset = 16; + var->red.msb_right = 0; + + var->green.length = 8; + var->green.offset = 8; + var->green.msb_right = 0; + + var->blue.length = 8; + var->blue.offset = 0; + var->blue.msb_right = 0; + + var->transp.length = 8; + var->transp.offset = 24; + var->transp.msb_right = 0; + break; + } + + if (var->pixclock < 1000) { + htotal = var->xres + var->right_margin + var->hsync_len + + var->left_margin; + vtotal = var->yres + var->lower_margin + var->vsync_len + + var->upper_margin; + var->pixclock = (vtotal * htotal * 6UL) / 100UL; + var->pixclock = KHZ2PICOS(var->pixclock); + dev_dbg(fbi->device, "pixclock set for 60Hz refresh = %u ps\n", + var->pixclock); + } + + var->height = -1; + var->width = -1; + var->grayscale = 0; + + /* Preserve sync flags */ + var->sync |= mx3_fbi->sync; + mx3_fbi->sync |= var->sync; + + return 0; } static u32 chan_to_field(unsigned int chan, struct fb_bitfield *bf) { - chan &= 0xffff; - chan >>= 16 - bf->length; - return chan << bf->offset; + chan &= 0xffff; + chan >>= 16 - bf->length; + return chan << bf->offset; } static int mx3fb_setcolreg(unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue, - unsigned int trans, struct fb_info *fbi) + unsigned int green, unsigned int blue, + unsigned int trans, struct fb_info *fbi) { - struct mx3fb_info *mx3_fbi = fbi->par; - u32 val; - int ret = 1; - - dev_dbg(fbi->device, "%s\n", __func__); - - mutex_lock(&mx3_fbi->mutex); - /* - * If greyscale is true, then we convert the RGB value - * to greyscale no matter what visual we are using. - */ - if (fbi->var.grayscale) - red = green = blue = (19595 * red + 38470 * green + - 7471 * blue) >> 16; - switch (fbi->fix.visual) { - case FB_VISUAL_TRUECOLOR: - /* - * 16-bit True Colour. We encode the RGB value - * according to the RGB bitfield information. - */ - if (regno < 16) { - u32 *pal = fbi->pseudo_palette; - - val = chan_to_field(red, &fbi->var.red); - val |= chan_to_field(green, &fbi->var.green); - val |= chan_to_field(blue, &fbi->var.blue); - - pal[regno] = val; - - ret = 0; - } - break; - - case FB_VISUAL_STATIC_PSEUDOCOLOR: - case FB_VISUAL_PSEUDOCOLOR: - break; - } - mutex_unlock(&mx3_fbi->mutex); - - return ret; + struct mx3fb_info *mx3_fbi = fbi->par; + u32 val; + int ret = 1; + + dev_dbg(fbi->device, "%s\n", __func__); + + mutex_lock(&mx3_fbi->mutex); + /* + * If greyscale is true, then we convert the RGB value + * to greyscale no matter what visual we are using. + */ + if (fbi->var.grayscale) + red = green = blue = (19595 * red + 38470 * green + + 7471 * blue) >> 16; + switch (fbi->fix.visual) { + case FB_VISUAL_TRUECOLOR: + /* + * 16-bit True Colour. We encode the RGB value + * according to the RGB bitfield information. + */ + if (regno < 16) { + u32 *pal = fbi->pseudo_palette; + + val = chan_to_field(red, &fbi->var.red); + val |= chan_to_field(green, &fbi->var.green); + val |= chan_to_field(blue, &fbi->var.blue); + + pal[regno] = val; + + ret = 0; + } + break; + + case FB_VISUAL_STATIC_PSEUDOCOLOR: + case FB_VISUAL_PSEUDOCOLOR: + break; + } + mutex_unlock(&mx3_fbi->mutex); + + return ret; } /** @@ -970,152 +970,152 @@ static int mx3fb_setcolreg(unsigned int regno, unsigned int red, */ static int mx3fb_blank(int blank, struct fb_info *fbi) { - struct mx3fb_info *mx3_fbi = fbi->par; - struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; - - dev_dbg(fbi->device, "%s\n", __func__); - - dev_dbg(fbi->device, "blank = %d\n", blank); - - if (mx3_fbi->blank == blank) - return 0; - - mutex_lock(&mx3_fbi->mutex); - mx3_fbi->blank = blank; - - switch (blank) { - case FB_BLANK_POWERDOWN: - case FB_BLANK_VSYNC_SUSPEND: - case FB_BLANK_HSYNC_SUSPEND: - case FB_BLANK_NORMAL: - sdc_disable_channel(mx3_fbi); - sdc_set_brightness(mx3fb, 0); - break; - case FB_BLANK_UNBLANK: - sdc_enable_channel(mx3_fbi); - sdc_set_brightness(mx3fb, mx3fb->backlight_level); - break; - } - mutex_unlock(&mx3_fbi->mutex); - - return 0; + struct mx3fb_info *mx3_fbi = fbi->par; + struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; + + dev_dbg(fbi->device, "%s\n", __func__); + + dev_dbg(fbi->device, "blank = %d\n", blank); + + if (mx3_fbi->blank == blank) + return 0; + + mutex_lock(&mx3_fbi->mutex); + mx3_fbi->blank = blank; + + switch (blank) { + case FB_BLANK_POWERDOWN: + case FB_BLANK_VSYNC_SUSPEND: + case FB_BLANK_HSYNC_SUSPEND: + case FB_BLANK_NORMAL: + sdc_disable_channel(mx3_fbi); + sdc_set_brightness(mx3fb, 0); + break; + case FB_BLANK_UNBLANK: + sdc_enable_channel(mx3_fbi); + sdc_set_brightness(mx3fb, mx3fb->backlight_level); + break; + } + mutex_unlock(&mx3_fbi->mutex); + + return 0; } /** * mx3fb_pan_display() - pan or wrap the display - * @var: variable screen buffer information. - * @info: framebuffer information pointer. + * @var: variable screen buffer information. + * @info: framebuffer information pointer. * * We look only at xoffset, yoffset and the FB_VMODE_YWRAP flag */ static int mx3fb_pan_display(struct fb_var_screeninfo *var, - struct fb_info *fbi) + struct fb_info *fbi) { - struct mx3fb_info *mx3_fbi = fbi->par; - u32 y_bottom; - unsigned long base; - off_t offset; - dma_cookie_t cookie; - struct scatterlist *sg = mx3_fbi->sg; - struct dma_chan *dma_chan = &mx3_fbi->idmac_channel->dma_chan; - struct dma_async_tx_descriptor *txd; - int ret; - - dev_dbg(fbi->device, "%s [%c]\n", __func__, - list_empty(&mx3_fbi->idmac_channel->queue) ? '-' : '+'); - - if (var->xoffset > 0) { - dev_dbg(fbi->device, "x panning not supported\n"); - return -EINVAL; - } - - if (fbi->var.xoffset == var->xoffset && - fbi->var.yoffset == var->yoffset) - return 0; /* No change, do nothing */ - - y_bottom = var->yoffset; - - if (!(var->vmode & FB_VMODE_YWRAP)) - y_bottom += var->yres; - - if (y_bottom > fbi->var.yres_virtual) - return -EINVAL; - - mutex_lock(&mx3_fbi->mutex); - - offset = (var->yoffset * var->xres_virtual + var->xoffset) * - (var->bits_per_pixel / 8); - base = fbi->fix.smem_start + offset; - - dev_dbg(fbi->device, "Updating SDC BG buf %d address=0x%08lX\n", - mx3_fbi->cur_ipu_buf, base); - - /* - * We enable the End of Frame interrupt, which will free a tx-descriptor, - * which we will need for the next device_prep_slave_sg(). The - * IRQ-handler will disable the IRQ again. - */ - init_completion(&mx3_fbi->flip_cmpl); - enable_irq(mx3_fbi->idmac_channel->eof_irq); - - ret = wait_for_completion_timeout(&mx3_fbi->flip_cmpl, HZ / 10); - if (ret <= 0) { - mutex_unlock(&mx3_fbi->mutex); - dev_info(fbi->device, "Panning failed due to %s\n", ret < 0 ? - "user interrupt" : "timeout"); - return ret ? : -ETIMEDOUT; - } - - mx3_fbi->cur_ipu_buf = !mx3_fbi->cur_ipu_buf; - - sg_dma_address(&sg[mx3_fbi->cur_ipu_buf]) = base; - sg_set_page(&sg[mx3_fbi->cur_ipu_buf], - virt_to_page(fbi->screen_base + offset), fbi->fix.smem_len, - offset_in_page(fbi->screen_base + offset)); - - txd = dma_chan->device->device_prep_slave_sg(dma_chan, sg + - mx3_fbi->cur_ipu_buf, 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT); - if (!txd) { - dev_err(fbi->device, - "Error preparing a DMA transaction descriptor.\n"); - mutex_unlock(&mx3_fbi->mutex); - return -EIO; - } - - txd->callback_param = txd; - txd->callback = mx3fb_dma_done; - - /* - * Emulate original mx3fb behaviour: each new call to idmac_tx_submit() - * should switch to another buffer - */ - cookie = txd->tx_submit(txd); - dev_dbg(fbi->device, "%d: Submit %p #%d\n", __LINE__, txd, cookie); - if (cookie < 0) { - dev_err(fbi->device, - "Error updating SDC buf %d to address=0x%08lX\n", - mx3_fbi->cur_ipu_buf, base); - mutex_unlock(&mx3_fbi->mutex); - return -EIO; - } - - if (mx3_fbi->txd) - async_tx_ack(mx3_fbi->txd); - mx3_fbi->txd = txd; - - fbi->var.xoffset = var->xoffset; - fbi->var.yoffset = var->yoffset; - - if (var->vmode & FB_VMODE_YWRAP) - fbi->var.vmode |= FB_VMODE_YWRAP; - else - fbi->var.vmode &= ~FB_VMODE_YWRAP; - - mutex_unlock(&mx3_fbi->mutex); - - dev_dbg(fbi->device, "Update complete\n"); - - return 0; + struct mx3fb_info *mx3_fbi = fbi->par; + u32 y_bottom; + unsigned long base; + off_t offset; + dma_cookie_t cookie; + struct scatterlist *sg = mx3_fbi->sg; + struct dma_chan *dma_chan = &mx3_fbi->idmac_channel->dma_chan; + struct dma_async_tx_descriptor *txd; + int ret; + + dev_dbg(fbi->device, "%s [%c]\n", __func__, + list_empty(&mx3_fbi->idmac_channel->queue) ? '-' : '+'); + + if (var->xoffset > 0) { + dev_dbg(fbi->device, "x panning not supported\n"); + return -EINVAL; + } + + if (fbi->var.xoffset == var->xoffset && + fbi->var.yoffset == var->yoffset) + return 0; /* No change, do nothing */ + + y_bottom = var->yoffset; + + if (!(var->vmode & FB_VMODE_YWRAP)) + y_bottom += var->yres; + + if (y_bottom > fbi->var.yres_virtual) + return -EINVAL; + + mutex_lock(&mx3_fbi->mutex); + + offset = (var->yoffset * var->xres_virtual + var->xoffset) * + (var->bits_per_pixel / 8); + base = fbi->fix.smem_start + offset; + + dev_dbg(fbi->device, "Updating SDC BG buf %d address=0x%08lX\n", + mx3_fbi->cur_ipu_buf, base); + + /* + * We enable the End of Frame interrupt, which will free a tx-descriptor, + * which we will need for the next device_prep_slave_sg(). The + * IRQ-handler will disable the IRQ again. + */ + init_completion(&mx3_fbi->flip_cmpl); + enable_irq(mx3_fbi->idmac_channel->eof_irq); + + ret = wait_for_completion_timeout(&mx3_fbi->flip_cmpl, HZ / 10); + if (ret <= 0) { + mutex_unlock(&mx3_fbi->mutex); + dev_info(fbi->device, "Panning failed due to %s\n", ret < 0 ? + "user interrupt" : "timeout"); + return ret ? : -ETIMEDOUT; + } + + mx3_fbi->cur_ipu_buf = !mx3_fbi->cur_ipu_buf; + + sg_dma_address(&sg[mx3_fbi->cur_ipu_buf]) = base; + sg_set_page(&sg[mx3_fbi->cur_ipu_buf], + virt_to_page(fbi->screen_base + offset), fbi->fix.smem_len, + offset_in_page(fbi->screen_base + offset)); + + txd = dma_chan->device->device_prep_slave_sg(dma_chan, sg + + mx3_fbi->cur_ipu_buf, 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT); + if (!txd) { + dev_err(fbi->device, + "Error preparing a DMA transaction descriptor.\n"); + mutex_unlock(&mx3_fbi->mutex); + return -EIO; + } + + txd->callback_param = txd; + txd->callback = mx3fb_dma_done; + + /* + * Emulate original mx3fb behaviour: each new call to idmac_tx_submit() + * should switch to another buffer + */ + cookie = txd->tx_submit(txd); + dev_dbg(fbi->device, "%d: Submit %p #%d\n", __LINE__, txd, cookie); + if (cookie < 0) { + dev_err(fbi->device, + "Error updating SDC buf %d to address=0x%08lX\n", + mx3_fbi->cur_ipu_buf, base); + mutex_unlock(&mx3_fbi->mutex); + return -EIO; + } + + if (mx3_fbi->txd) + async_tx_ack(mx3_fbi->txd); + mx3_fbi->txd = txd; + + fbi->var.xoffset = var->xoffset; + fbi->var.yoffset = var->yoffset; + + if (var->vmode & FB_VMODE_YWRAP) + fbi->var.vmode |= FB_VMODE_YWRAP; + else + fbi->var.vmode &= ~FB_VMODE_YWRAP; + + mutex_unlock(&mx3_fbi->mutex); + + dev_dbg(fbi->device, "Update complete\n"); + + return 0; } /* @@ -1124,15 +1124,15 @@ static int mx3fb_pan_display(struct fb_var_screeninfo *var, * blitting, rectangle filling, copy regions and cursor definition. */ static struct fb_ops mx3fb_ops = { - .owner = THIS_MODULE, - .fb_set_par = mx3fb_set_par, - .fb_check_var = mx3fb_check_var, - .fb_setcolreg = mx3fb_setcolreg, - .fb_pan_display = mx3fb_pan_display, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, - .fb_blank = mx3fb_blank, + .owner = THIS_MODULE, + .fb_set_par = mx3fb_set_par, + .fb_check_var = mx3fb_check_var, + .fb_setcolreg = mx3fb_setcolreg, + .fb_pan_display = mx3fb_pan_display, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_blank = mx3fb_blank, }; #ifdef CONFIG_PM @@ -1146,19 +1146,19 @@ static struct fb_ops mx3fb_ops = { */ static int mx3fb_suspend(struct platform_device *pdev, pm_message_t state) { - struct mx3fb_data *drv_data = platform_get_drvdata(pdev); - struct mx3fb_info *mx3_fbi = drv_data->fbi->par; + struct mx3fb_data *drv_data = platform_get_drvdata(pdev); + struct mx3fb_info *mx3_fbi = drv_data->fbi->par; - acquire_console_sem(); - fb_set_suspend(drv_data->fbi, 1); - release_console_sem(); + acquire_console_sem(); + fb_set_suspend(drv_data->fbi, 1); + release_console_sem(); - if (mx3_fbi->blank == FB_BLANK_UNBLANK) { - sdc_disable_channel(mx3_fbi); - sdc_set_brightness(mx3fb, 0); + if (mx3_fbi->blank == FB_BLANK_UNBLANK) { + sdc_disable_channel(mx3_fbi); + sdc_set_brightness(mx3fb, 0); - } - return 0; + } + return 0; } /* @@ -1166,19 +1166,19 @@ static int mx3fb_suspend(struct platform_device *pdev, pm_message_t state) */ static int mx3fb_resume(struct platform_device *pdev) { - struct mx3fb_data *drv_data = platform_get_drvdata(pdev); - struct mx3fb_info *mx3_fbi = drv_data->fbi->par; + struct mx3fb_data *drv_data = platform_get_drvdata(pdev); + struct mx3fb_info *mx3_fbi = drv_data->fbi->par; - if (mx3_fbi->blank == FB_BLANK_UNBLANK) { - sdc_enable_channel(mx3_fbi); - sdc_set_brightness(mx3fb, drv_data->backlight_level); - } + if (mx3_fbi->blank == FB_BLANK_UNBLANK) { + sdc_enable_channel(mx3_fbi); + sdc_set_brightness(mx3fb, drv_data->backlight_level); + } - acquire_console_sem(); - fb_set_suspend(drv_data->fbi, 0); - release_console_sem(); + acquire_console_sem(); + fb_set_suspend(drv_data->fbi, 0); + release_console_sem(); - return 0; + return 0; } #else #define mx3fb_suspend NULL @@ -1191,8 +1191,8 @@ static int mx3fb_resume(struct platform_device *pdev) /** * mx3fb_map_video_memory() - allocates the DRAM memory for the frame buffer. - * @fbi: framebuffer information pointer - * @return: Error code indicating success or failure + * @fbi: framebuffer information pointer + * @return: Error code indicating success or failure * * This buffer is remapped into a non-cached, non-buffered, memory region to * allow palette and pixel writes to occur without flushing the cache. Once this @@ -1201,349 +1201,349 @@ static int mx3fb_resume(struct platform_device *pdev) */ static int mx3fb_map_video_memory(struct fb_info *fbi) { - int retval = 0; - dma_addr_t addr; + int retval = 0; + dma_addr_t addr; - fbi->screen_base = dma_alloc_writecombine(fbi->device, - fbi->fix.smem_len, - &addr, GFP_DMA); + fbi->screen_base = dma_alloc_writecombine(fbi->device, + fbi->fix.smem_len, + &addr, GFP_DMA); - if (!fbi->screen_base) { - dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n", - fbi->fix.smem_len); - retval = -EBUSY; - goto err0; - } + if (!fbi->screen_base) { + dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n", + fbi->fix.smem_len); + retval = -EBUSY; + goto err0; + } - fbi->fix.smem_start = addr; + fbi->fix.smem_start = addr; - dev_dbg(fbi->device, "allocated fb @ p=0x%08x, v=0x%p, size=%d.\n", - (uint32_t) fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len); + dev_dbg(fbi->device, "allocated fb @ p=0x%08x, v=0x%p, size=%d.\n", + (uint32_t) fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len); - fbi->screen_size = fbi->fix.smem_len; + fbi->screen_size = fbi->fix.smem_len; - /* Clear the screen */ - memset((char *)fbi->screen_base, 0, fbi->fix.smem_len); + /* Clear the screen */ + memset((char *)fbi->screen_base, 0, fbi->fix.smem_len); - return 0; + return 0; err0: - fbi->fix.smem_len = 0; - fbi->fix.smem_start = 0; - fbi->screen_base = NULL; - return retval; + fbi->fix.smem_len = 0; + fbi->fix.smem_start = 0; + fbi->screen_base = NULL; + return retval; } /** * mx3fb_unmap_video_memory() - de-allocate frame buffer memory. - * @fbi: framebuffer information pointer - * @return: error code indicating success or failure + * @fbi: framebuffer information pointer + * @return: error code indicating success or failure */ static int mx3fb_unmap_video_memory(struct fb_info *fbi) { - dma_free_writecombine(fbi->device, fbi->fix.smem_len, - fbi->screen_base, fbi->fix.smem_start); + dma_free_writecombine(fbi->device, fbi->fix.smem_len, + fbi->screen_base, fbi->fix.smem_start); - fbi->screen_base = 0; - fbi->fix.smem_start = 0; - fbi->fix.smem_len = 0; - return 0; + fbi->screen_base = 0; + fbi->fix.smem_start = 0; + fbi->fix.smem_len = 0; + return 0; } /** * mx3fb_init_fbinfo() - initialize framebuffer information object. - * @return: initialized framebuffer structure. + * @return: initialized framebuffer structure. */ static struct fb_info *mx3fb_init_fbinfo(struct device *dev, struct fb_ops *ops) { - struct fb_info *fbi; - struct mx3fb_info *mx3fbi; - int ret; + struct fb_info *fbi; + struct mx3fb_info *mx3fbi; + int ret; - /* Allocate sufficient memory for the fb structure */ - fbi = framebuffer_alloc(sizeof(struct mx3fb_info), dev); - if (!fbi) - return NULL; + /* Allocate sufficient memory for the fb structure */ + fbi = framebuffer_alloc(sizeof(struct mx3fb_info), dev); + if (!fbi) + return NULL; - mx3fbi = fbi->par; - mx3fbi->cookie = -EINVAL; - mx3fbi->cur_ipu_buf = 0; + mx3fbi = fbi->par; + mx3fbi->cookie = -EINVAL; + mx3fbi->cur_ipu_buf = 0; - fbi->var.activate = FB_ACTIVATE_NOW; + fbi->var.activate = FB_ACTIVATE_NOW; - fbi->fbops = ops; - fbi->flags = FBINFO_FLAG_DEFAULT; - fbi->pseudo_palette = mx3fbi->pseudo_palette; + fbi->fbops = ops; + fbi->flags = FBINFO_FLAG_DEFAULT; + fbi->pseudo_palette = mx3fbi->pseudo_palette; - mutex_init(&mx3fbi->mutex); + mutex_init(&mx3fbi->mutex); - /* Allocate colormap */ - ret = fb_alloc_cmap(&fbi->cmap, 16, 0); - if (ret < 0) { - framebuffer_release(fbi); - return NULL; - } + /* Allocate colormap */ + ret = fb_alloc_cmap(&fbi->cmap, 16, 0); + if (ret < 0) { + framebuffer_release(fbi); + return NULL; + } - return fbi; + return fbi; } static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan) { - struct device *dev = mx3fb->dev; - struct mx3fb_platform_data *mx3fb_pdata = dev->platform_data; - const char *name = mx3fb_pdata->name; - unsigned int irq; - struct fb_info *fbi; - struct mx3fb_info *mx3fbi; - const struct fb_videomode *mode; - int ret, num_modes; + struct device *dev = mx3fb->dev; + struct mx3fb_platform_data *mx3fb_pdata = dev->platform_data; + const char *name = mx3fb_pdata->name; + unsigned int irq; + struct fb_info *fbi; + struct mx3fb_info *mx3fbi; + const struct fb_videomode *mode; + int ret, num_modes; - ichan->client = mx3fb; - irq = ichan->eof_irq; + ichan->client = mx3fb; + irq = ichan->eof_irq; - if (ichan->dma_chan.chan_id != IDMAC_SDC_0) - return -EINVAL; + if (ichan->dma_chan.chan_id != IDMAC_SDC_0) + return -EINVAL; - fbi = mx3fb_init_fbinfo(dev, &mx3fb_ops); - if (!fbi) - return -ENOMEM; + fbi = mx3fb_init_fbinfo(dev, &mx3fb_ops); + if (!fbi) + return -ENOMEM; - if (!fb_mode) - fb_mode = name; + if (!fb_mode) + fb_mode = name; - if (!fb_mode) { - ret = -EINVAL; - goto emode; - } + if (!fb_mode) { + ret = -EINVAL; + goto emode; + } - if (mx3fb_pdata->mode && mx3fb_pdata->num_modes) { - mode = mx3fb_pdata->mode; - num_modes = mx3fb_pdata->num_modes; - } else { - mode = mx3fb_modedb; - num_modes = ARRAY_SIZE(mx3fb_modedb); - } + if (mx3fb_pdata->mode && mx3fb_pdata->num_modes) { + mode = mx3fb_pdata->mode; + num_modes = mx3fb_pdata->num_modes; + } else { + mode = mx3fb_modedb; + num_modes = ARRAY_SIZE(mx3fb_modedb); + } - if (!fb_find_mode(&fbi->var, fbi, fb_mode, mode, - num_modes, NULL, default_bpp)) { - ret = -EBUSY; - goto emode; - } + if (!fb_find_mode(&fbi->var, fbi, fb_mode, mode, + num_modes, NULL, default_bpp)) { + ret = -EBUSY; + goto emode; + } - fb_videomode_to_modelist(mode, num_modes, &fbi->modelist); + fb_videomode_to_modelist(mode, num_modes, &fbi->modelist); - /* Default Y virtual size is 2x panel size */ - fbi->var.yres_virtual = fbi->var.yres * 2; + /* Default Y virtual size is 2x panel size */ + fbi->var.yres_virtual = fbi->var.yres * 2; - mx3fb->fbi = fbi; + mx3fb->fbi = fbi; - /* set Display Interface clock period */ - mx3fb_write_reg(mx3fb, 0x00100010L, DI_HSP_CLK_PER); - /* Might need to trigger HSP clock change - see 44.3.3.8.5 */ + /* set Display Interface clock period */ + mx3fb_write_reg(mx3fb, 0x00100010L, DI_HSP_CLK_PER); + /* Might need to trigger HSP clock change - see 44.3.3.8.5 */ - sdc_set_brightness(mx3fb, 255); - sdc_set_global_alpha(mx3fb, true, 0xFF); - sdc_set_color_key(mx3fb, IDMAC_SDC_0, false, 0); + sdc_set_brightness(mx3fb, 255); + sdc_set_global_alpha(mx3fb, true, 0xFF); + sdc_set_color_key(mx3fb, IDMAC_SDC_0, false, 0); - mx3fbi = fbi->par; - mx3fbi->idmac_channel = ichan; - mx3fbi->ipu_ch = ichan->dma_chan.chan_id; - mx3fbi->mx3fb = mx3fb; - mx3fbi->blank = FB_BLANK_NORMAL; + mx3fbi = fbi->par; + mx3fbi->idmac_channel = ichan; + mx3fbi->ipu_ch = ichan->dma_chan.chan_id; + mx3fbi->mx3fb = mx3fb; + mx3fbi->blank = FB_BLANK_NORMAL; - init_completion(&mx3fbi->flip_cmpl); - disable_irq(ichan->eof_irq); - dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq); - ret = mx3fb_set_par(fbi); - if (ret < 0) - goto esetpar; + init_completion(&mx3fbi->flip_cmpl); + disable_irq(ichan->eof_irq); + dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq); + ret = mx3fb_set_par(fbi); + if (ret < 0) + goto esetpar; - mx3fb_blank(FB_BLANK_UNBLANK, fbi); + mx3fb_blank(FB_BLANK_UNBLANK, fbi); - dev_info(dev, "mx3fb: fb registered, using mode %s\n", fb_mode); + dev_info(dev, "mx3fb: fb registered, using mode %s\n", fb_mode); - ret = register_framebuffer(fbi); - if (ret < 0) - goto erfb; + ret = register_framebuffer(fbi); + if (ret < 0) + goto erfb; - return 0; + return 0; erfb: esetpar: emode: - fb_dealloc_cmap(&fbi->cmap); - framebuffer_release(fbi); + fb_dealloc_cmap(&fbi->cmap); + framebuffer_release(fbi); - return ret; + return ret; } static bool chan_filter(struct dma_chan *chan, void *arg) { - struct dma_chan_request *rq = arg; - struct device *dev; - struct mx3fb_platform_data *mx3fb_pdata; + struct dma_chan_request *rq = arg; + struct device *dev; + struct mx3fb_platform_data *mx3fb_pdata; - if (!rq) - return false; + if (!rq) + return false; - dev = rq->mx3fb->dev; - mx3fb_pdata = dev->platform_data; + dev = rq->mx3fb->dev; + mx3fb_pdata = dev->platform_data; - return rq->id == chan->chan_id && - mx3fb_pdata->dma_dev == chan->device->dev; + return rq->id == chan->chan_id && + mx3fb_pdata->dma_dev == chan->device->dev; } static void release_fbi(struct fb_info *fbi) { - mx3fb_unmap_video_memory(fbi); + mx3fb_unmap_video_memory(fbi); - fb_dealloc_cmap(&fbi->cmap); + fb_dealloc_cmap(&fbi->cmap); - unregister_framebuffer(fbi); - framebuffer_release(fbi); + unregister_framebuffer(fbi); + framebuffer_release(fbi); } static int mx3fb_probe(struct platform_device *pdev) { - struct device *dev = &pdev->dev; - int ret; - struct resource *sdc_reg; - struct mx3fb_data *mx3fb; - dma_cap_mask_t mask; - struct dma_chan *chan; - struct dma_chan_request rq; - - /* - * Display Interface (DI) and Synchronous Display Controller (SDC) - * registers - */ - sdc_reg = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!sdc_reg) - return -EINVAL; - - mx3fb = kzalloc(sizeof(*mx3fb), GFP_KERNEL); - if (!mx3fb) - return -ENOMEM; - - spin_lock_init(&mx3fb->lock); - - mx3fb->reg_base = ioremap(sdc_reg->start, resource_size(sdc_reg)); - if (!mx3fb->reg_base) { - ret = -ENOMEM; - goto eremap; - } - - pr_debug("Remapped %x to %x at %p\n", sdc_reg->start, sdc_reg->end, - mx3fb->reg_base); - - /* IDMAC interface */ - dmaengine_get(); - - mx3fb->dev = dev; - platform_set_drvdata(pdev, mx3fb); - - rq.mx3fb = mx3fb; - - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - dma_cap_set(DMA_PRIVATE, mask); - rq.id = IDMAC_SDC_0; - chan = dma_request_channel(mask, chan_filter, &rq); - if (!chan) { - ret = -EBUSY; - goto ersdc0; - } - - ret = init_fb_chan(mx3fb, to_idmac_chan(chan)); - if (ret < 0) - goto eisdc0; - - mx3fb->backlight_level = 255; - - return 0; + struct device *dev = &pdev->dev; + int ret; + struct resource *sdc_reg; + struct mx3fb_data *mx3fb; + dma_cap_mask_t mask; + struct dma_chan *chan; + struct dma_chan_request rq; + + /* + * Display Interface (DI) and Synchronous Display Controller (SDC) + * registers + */ + sdc_reg = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!sdc_reg) + return -EINVAL; + + mx3fb = kzalloc(sizeof(*mx3fb), GFP_KERNEL); + if (!mx3fb) + return -ENOMEM; + + spin_lock_init(&mx3fb->lock); + + mx3fb->reg_base = ioremap(sdc_reg->start, resource_size(sdc_reg)); + if (!mx3fb->reg_base) { + ret = -ENOMEM; + goto eremap; + } + + pr_debug("Remapped %x to %x at %p\n", sdc_reg->start, sdc_reg->end, + mx3fb->reg_base); + + /* IDMAC interface */ + dmaengine_get(); + + mx3fb->dev = dev; + platform_set_drvdata(pdev, mx3fb); + + rq.mx3fb = mx3fb; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + dma_cap_set(DMA_PRIVATE, mask); + rq.id = IDMAC_SDC_0; + chan = dma_request_channel(mask, chan_filter, &rq); + if (!chan) { + ret = -EBUSY; + goto ersdc0; + } + + ret = init_fb_chan(mx3fb, to_idmac_chan(chan)); + if (ret < 0) + goto eisdc0; + + mx3fb->backlight_level = 255; + + return 0; eisdc0: - dma_release_channel(chan); + dma_release_channel(chan); ersdc0: - dmaengine_put(); - iounmap(mx3fb->reg_base); + dmaengine_put(); + iounmap(mx3fb->reg_base); eremap: - kfree(mx3fb); - dev_err(dev, "mx3fb: failed to register fb\n"); - return ret; + kfree(mx3fb); + dev_err(dev, "mx3fb: failed to register fb\n"); + return ret; } static int mx3fb_remove(struct platform_device *dev) { - struct mx3fb_data *mx3fb = platform_get_drvdata(dev); - struct fb_info *fbi = mx3fb->fbi; - struct mx3fb_info *mx3_fbi = fbi->par; - struct dma_chan *chan; + struct mx3fb_data *mx3fb = platform_get_drvdata(dev); + struct fb_info *fbi = mx3fb->fbi; + struct mx3fb_info *mx3_fbi = fbi->par; + struct dma_chan *chan; - chan = &mx3_fbi->idmac_channel->dma_chan; - release_fbi(fbi); + chan = &mx3_fbi->idmac_channel->dma_chan; + release_fbi(fbi); - dma_release_channel(chan); - dmaengine_put(); + dma_release_channel(chan); + dmaengine_put(); - iounmap(mx3fb->reg_base); - kfree(mx3fb); - return 0; + iounmap(mx3fb->reg_base); + kfree(mx3fb); + return 0; } static struct platform_driver mx3fb_driver = { - .driver = { - .name = MX3FB_NAME, - }, - .probe = mx3fb_probe, - .remove = mx3fb_remove, - .suspend = mx3fb_suspend, - .resume = mx3fb_resume, + .driver = { + .name = MX3FB_NAME, + }, + .probe = mx3fb_probe, + .remove = mx3fb_remove, + .suspend = mx3fb_suspend, + .resume = mx3fb_resume, }; /* * Parse user specified options (`video=mx3fb:') * example: - * video=mx3fb:bpp=16 + * video=mx3fb:bpp=16 */ static int mx3fb_setup(void) { #ifndef MODULE - char *opt, *options = NULL; - - if (fb_get_options("mx3fb", &options)) - return -ENODEV; - - if (!options || !*options) - return 0; - - while ((opt = strsep(&options, ",")) != NULL) { - if (!*opt) - continue; - if (!strncmp(opt, "bpp=", 4)) - default_bpp = simple_strtoul(opt + 4, NULL, 0); - else - fb_mode = opt; - } + char *opt, *options = NULL; + + if (fb_get_options("mx3fb", &options)) + return -ENODEV; + + if (!options || !*options) + return 0; + + while ((opt = strsep(&options, ",")) != NULL) { + if (!*opt) + continue; + if (!strncmp(opt, "bpp=", 4)) + default_bpp = simple_strtoul(opt + 4, NULL, 0); + else + fb_mode = opt; + } #endif - return 0; + return 0; } static int __init mx3fb_init(void) { - int ret = mx3fb_setup(); + int ret = mx3fb_setup(); - if (ret < 0) - return ret; + if (ret < 0) + return ret; - ret = platform_driver_register(&mx3fb_driver); - return ret; + ret = platform_driver_register(&mx3fb_driver); + return ret; } static void __exit mx3fb_exit(void) { - platform_driver_unregister(&mx3fb_driver); + platform_driver_unregister(&mx3fb_driver); } module_init(mx3fb_init); diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 2552b9f325e..84f63205c46 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -59,7 +59,6 @@ #include <asm/io.h> #include <asm/irq.h> #include <asm/div64.h> -#include <mach/pxa-regs.h> #include <mach/bitfield.h> #include <mach/pxafb.h> @@ -883,10 +882,21 @@ static void __devinit init_pxafb_overlay(struct pxafb_info *fbi, init_completion(&ofb->branch_done); } +static inline int pxafb_overlay_supported(void) +{ + if (cpu_is_pxa27x() || cpu_is_pxa3xx()) + return 1; + + return 0; +} + static int __devinit pxafb_overlay_init(struct pxafb_info *fbi) { int i, ret; + if (!pxafb_overlay_supported()) + return 0; + for (i = 0; i < 2; i++) { init_pxafb_overlay(fbi, &fbi->overlay[i], i); ret = register_framebuffer(&fbi->overlay[i].fb); @@ -909,6 +919,9 @@ static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi) { int i; + if (!pxafb_overlay_supported()) + return; + for (i = 0; i < 2; i++) unregister_framebuffer(&fbi->overlay[i].fb); } diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index 79cf0b1976a..b0b4513ba53 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/s3c2410fb.c @@ -1017,6 +1017,10 @@ static int s3c2410fb_resume(struct platform_device *dev) s3c2410fb_init_registers(fbinfo); + /* re-activate our display after resume */ + s3c2410fb_activate_var(fbinfo); + s3c2410fb_blank(FB_BLANK_UNBLANK, fbinfo); + return 0; } diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c index 076f946fa0f..fad58cf9ef7 100644 --- a/drivers/video/sa1100fb.c +++ b/drivers/video/sa1100fb.c @@ -176,9 +176,9 @@ #include <linux/platform_device.h> #include <linux/dma-mapping.h> #include <linux/mutex.h> +#include <linux/io.h> #include <mach/hardware.h> -#include <asm/io.h> #include <asm/mach-types.h> #include <mach/assabet.h> #include <mach/shannon.h> @@ -251,22 +251,6 @@ static struct sa1100fb_mach_info pal_info __initdata = { #endif #endif -#ifdef CONFIG_SA1100_H3800 -static struct sa1100fb_mach_info h3800_info __initdata = { - .pixclock = 174757, .bpp = 16, - .xres = 320, .yres = 240, - - .hsync_len = 3, .vsync_len = 3, - .left_margin = 12, .upper_margin = 10, - .right_margin = 17, .lower_margin = 1, - - .cmap_static = 1, - - .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, - .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2), -}; -#endif - #ifdef CONFIG_SA1100_H3600 static struct sa1100fb_mach_info h3600_info __initdata = { .pixclock = 174757, .bpp = 16, @@ -432,11 +416,6 @@ sa1100fb_get_machine_info(struct sa1100fb_info *fbi) fbi->rgb[RGB_16] = &h3600_rgb_16; } #endif -#ifdef CONFIG_SA1100_H3800 - if (machine_is_h3800()) { - inf = &h3800_info; - } -#endif #ifdef CONFIG_SA1100_COLLIE if (machine_is_collie()) { inf = &collie_info; diff --git a/drivers/w1/masters/mxc_w1.c b/drivers/w1/masters/mxc_w1.c index b9d74d0b353..65244c02551 100644 --- a/drivers/w1/masters/mxc_w1.c +++ b/drivers/w1/masters/mxc_w1.c @@ -116,7 +116,7 @@ static int __init mxc_w1_probe(struct platform_device *pdev) if (!mdev) return -ENOMEM; - mdev->clk = clk_get(&pdev->dev, "owire_clk"); + mdev->clk = clk_get(&pdev->dev, "owire"); if (!mdev->clk) { err = -ENODEV; goto failed_clk; diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c index c973889110c..a7e3b706b9d 100644 --- a/drivers/w1/masters/omap_hdq.c +++ b/drivers/w1/masters/omap_hdq.c @@ -590,8 +590,8 @@ static int __init omap_hdq_probe(struct platform_device *pdev) } /* get interface & functional clock objects */ - hdq_data->hdq_ick = clk_get(&pdev->dev, "hdq_ick"); - hdq_data->hdq_fck = clk_get(&pdev->dev, "hdq_fck"); + hdq_data->hdq_ick = clk_get(&pdev->dev, "ick"); + hdq_data->hdq_fck = clk_get(&pdev->dev, "fck"); if (IS_ERR(hdq_data->hdq_ick) || IS_ERR(hdq_data->hdq_fck)) { dev_dbg(&pdev->dev, "Can't get HDQ clock objects\n"); diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c index 2f2ce7429f5..aa5ad6e33f0 100644 --- a/drivers/watchdog/omap_wdt.c +++ b/drivers/watchdog/omap_wdt.c @@ -60,9 +60,8 @@ struct omap_wdt_dev { void __iomem *base; /* physical */ struct device *dev; int omap_wdt_users; - struct clk *armwdt_ck; - struct clk *mpu_wdt_ick; - struct clk *mpu_wdt_fck; + struct clk *ick; + struct clk *fck; struct resource *mem; struct miscdevice omap_wdt_miscdev; }; @@ -146,13 +145,8 @@ static int omap_wdt_open(struct inode *inode, struct file *file) if (test_and_set_bit(1, (unsigned long *)&(wdev->omap_wdt_users))) return -EBUSY; - if (cpu_is_omap16xx()) - clk_enable(wdev->armwdt_ck); /* Enable the clock */ - - if (cpu_is_omap24xx() || cpu_is_omap34xx()) { - clk_enable(wdev->mpu_wdt_ick); /* Enable the interface clock */ - clk_enable(wdev->mpu_wdt_fck); /* Enable the functional clock */ - } + clk_enable(wdev->ick); /* Enable the interface clock */ + clk_enable(wdev->fck); /* Enable the functional clock */ /* initialize prescaler */ while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01) @@ -181,13 +175,8 @@ static int omap_wdt_release(struct inode *inode, struct file *file) omap_wdt_disable(wdev); - if (cpu_is_omap16xx()) - clk_disable(wdev->armwdt_ck); /* Disable the clock */ - - if (cpu_is_omap24xx() || cpu_is_omap34xx()) { - clk_disable(wdev->mpu_wdt_ick); /* Disable the clock */ - clk_disable(wdev->mpu_wdt_fck); /* Disable the clock */ - } + clk_disable(wdev->ick); + clk_disable(wdev->fck); #else printk(KERN_CRIT "omap_wdt: Unexpected close, not stopping!\n"); #endif @@ -303,44 +292,19 @@ static int __init omap_wdt_probe(struct platform_device *pdev) wdev->omap_wdt_users = 0; wdev->mem = mem; - if (cpu_is_omap16xx()) { - wdev->armwdt_ck = clk_get(&pdev->dev, "armwdt_ck"); - if (IS_ERR(wdev->armwdt_ck)) { - ret = PTR_ERR(wdev->armwdt_ck); - wdev->armwdt_ck = NULL; - goto err_clk; - } + wdev->ick = clk_get(&pdev->dev, "ick"); + if (IS_ERR(wdev->ick)) { + ret = PTR_ERR(wdev->ick); + wdev->ick = NULL; + goto err_clk; } - - if (cpu_is_omap24xx()) { - wdev->mpu_wdt_ick = clk_get(&pdev->dev, "mpu_wdt_ick"); - if (IS_ERR(wdev->mpu_wdt_ick)) { - ret = PTR_ERR(wdev->mpu_wdt_ick); - wdev->mpu_wdt_ick = NULL; - goto err_clk; - } - wdev->mpu_wdt_fck = clk_get(&pdev->dev, "mpu_wdt_fck"); - if (IS_ERR(wdev->mpu_wdt_fck)) { - ret = PTR_ERR(wdev->mpu_wdt_fck); - wdev->mpu_wdt_fck = NULL; - goto err_clk; - } + wdev->fck = clk_get(&pdev->dev, "fck"); + if (IS_ERR(wdev->fck)) { + ret = PTR_ERR(wdev->fck); + wdev->fck = NULL; + goto err_clk; } - if (cpu_is_omap34xx()) { - wdev->mpu_wdt_ick = clk_get(&pdev->dev, "wdt2_ick"); - if (IS_ERR(wdev->mpu_wdt_ick)) { - ret = PTR_ERR(wdev->mpu_wdt_ick); - wdev->mpu_wdt_ick = NULL; - goto err_clk; - } - wdev->mpu_wdt_fck = clk_get(&pdev->dev, "wdt2_fck"); - if (IS_ERR(wdev->mpu_wdt_fck)) { - ret = PTR_ERR(wdev->mpu_wdt_fck); - wdev->mpu_wdt_fck = NULL; - goto err_clk; - } - } wdev->base = ioremap(res->start, res->end - res->start + 1); if (!wdev->base) { ret = -ENOMEM; @@ -380,12 +344,10 @@ err_ioremap: wdev->base = NULL; err_clk: - if (wdev->armwdt_ck) - clk_put(wdev->armwdt_ck); - if (wdev->mpu_wdt_ick) - clk_put(wdev->mpu_wdt_ick); - if (wdev->mpu_wdt_fck) - clk_put(wdev->mpu_wdt_fck); + if (wdev->ick) + clk_put(wdev->ick); + if (wdev->fck) + clk_put(wdev->fck); kfree(wdev); err_kzalloc: @@ -417,20 +379,8 @@ static int omap_wdt_remove(struct platform_device *pdev) release_mem_region(res->start, res->end - res->start + 1); platform_set_drvdata(pdev, NULL); - if (wdev->armwdt_ck) { - clk_put(wdev->armwdt_ck); - wdev->armwdt_ck = NULL; - } - - if (wdev->mpu_wdt_ick) { - clk_put(wdev->mpu_wdt_ick); - wdev->mpu_wdt_ick = NULL; - } - - if (wdev->mpu_wdt_fck) { - clk_put(wdev->mpu_wdt_fck); - wdev->mpu_wdt_fck = NULL; - } + clk_put(wdev->ick); + clk_put(wdev->fck); iounmap(wdev->base); kfree(wdev); diff --git a/drivers/watchdog/sa1100_wdt.c b/drivers/watchdog/sa1100_wdt.c index 5bd782f2783..ee1caae4d33 100644 --- a/drivers/watchdog/sa1100_wdt.c +++ b/drivers/watchdog/sa1100_wdt.c @@ -30,7 +30,7 @@ #include <linux/timex.h> #ifdef CONFIG_ARCH_PXA -#include <mach/pxa-regs.h> +#include <mach/regs-ost.h> #endif #include <mach/reset.h> |