Commit 440eed43 authored by Dominik Brodowski's avatar Dominik Brodowski
Browse files

pcmcia: introduce autoconfiguration feature



Introduce an autoconfiguration feature to set certain values in
pcmcia_loop_config(), instead of copying the same code over and over
in each PCMCIA driver. At first, introduce the following options:

CONF_AUTO_CHECK_VCC	check or matching Vcc entry
CONF_AUTO_SET_VPP	set Vpp
CONF_AUTO_AUDIO		enable the speaker line

CC: netdev@vger.kernel.org
CC: linux-wireless@vger.kernel.org
CC: linux-ide@vger.kernel.org
CC: linux-usb@vger.kernel.org
CC: laforge@gnumonks.org
CC: linux-mtd@lists.infradead.org
CC: alsa-devel@alsa-project.org
CC: linux-serial@vger.kernel.org
CC: Jiri Kosina <jkosina@suse.cz>
CC: linux-scsi@vger.kernel.org
Acked-by: Gustavo F. Padovan <padovan@profusion.mobi> (for drivers/bluetooth)
Tested-by: default avatarWolfram Sang <w.sang@pengutronix.de>
Signed-off-by: default avatarDominik Brodowski <linux@dominikbrodowski.net>
parent 9485ee14
Loading
Loading
Loading
Loading
+3 −20
Original line number Diff line number Diff line
@@ -169,34 +169,16 @@ static struct ata_port_operations pcmcia_8bit_port_ops = {

struct pcmcia_config_check {
	unsigned long ctl_base;
	int skip_vcc;
	int is_kme;
};

static int pcmcia_check_one_config(struct pcmcia_device *pdev,
				   cistpl_cftable_entry_t *cfg,
				   cistpl_cftable_entry_t *dflt,
				   unsigned int vcc,
				   void *priv_data)
{
	struct pcmcia_config_check *stk = priv_data;

	/* Check for matching Vcc, unless we're desperate */
	if (!stk->skip_vcc) {
		if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
			if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
				return -ENODEV;
		} else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
			if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000)
				return -ENODEV;
		}
	}

	if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
		pdev->vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
	else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
		pdev->vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;

	if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
		cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
		pdev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
@@ -249,6 +231,7 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
	pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
	pdev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
	pdev->config_flags |= CONF_ENABLE_IRQ;
	pdev->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC;

	/* See if we have a manufacturer identifier. Use it to set is_kme for
	   vendor quirks */
@@ -262,10 +245,10 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
	if (!stk)
		goto out1;
	stk->is_kme = is_kme;
	stk->skip_vcc = io_base = ctl_base = 0;
	io_base = ctl_base = 0;

	if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk)) {
		stk->skip_vcc = 1;
		pdev->config_flags &= ~CONF_AUTO_CHECK_VCC;
		if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk))
			goto failed; /* No suitable config found */
	}
+1 −6
Original line number Diff line number Diff line
@@ -659,7 +659,7 @@ static int bt3c_probe(struct pcmcia_device *link)
	link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
	link->resource[0]->end = 8;

	link->config_flags |= CONF_ENABLE_IRQ;
	link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP;

	return bt3c_config(link);
}
@@ -676,15 +676,11 @@ static void bt3c_detach(struct pcmcia_device *link)
static int bt3c_check_config(struct pcmcia_device *p_dev,
			     cistpl_cftable_entry_t *cf,
			     cistpl_cftable_entry_t *dflt,
			     unsigned int vcc,
			     void *priv_data)
{
	unsigned long try = (unsigned long) priv_data;

	p_dev->io_lines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;

	if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
		p_dev->vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
	if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
	    (cf->io.win[0].base != 0)) {
		p_dev->resource[0]->start = cf->io.win[0].base;
@@ -697,7 +693,6 @@ static int bt3c_check_config(struct pcmcia_device *p_dev,
static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev,
				      cistpl_cftable_entry_t *cf,
				      cistpl_cftable_entry_t *dflt,
				      unsigned int vcc,
				      void *priv_data)
{
	static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
+1 −6
Original line number Diff line number Diff line
@@ -588,7 +588,7 @@ static int btuart_probe(struct pcmcia_device *link)
	link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
	link->resource[0]->end = 8;

	link->config_flags |= CONF_ENABLE_IRQ;
	link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP;

	return btuart_config(link);
}
@@ -605,15 +605,11 @@ static void btuart_detach(struct pcmcia_device *link)
static int btuart_check_config(struct pcmcia_device *p_dev,
			       cistpl_cftable_entry_t *cf,
			       cistpl_cftable_entry_t *dflt,
			       unsigned int vcc,
			       void *priv_data)
{
	int *try = priv_data;

	p_dev->io_lines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;

	if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
		p_dev->vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
	if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
	    (cf->io.win[0].base != 0)) {
		p_dev->resource[0]->start = cf->io.win[0].base;
@@ -626,7 +622,6 @@ static int btuart_check_config(struct pcmcia_device *p_dev,
static int btuart_check_config_notpicky(struct pcmcia_device *p_dev,
					cistpl_cftable_entry_t *cf,
					cistpl_cftable_entry_t *dflt,
					unsigned int vcc,
					void *priv_data)
{
	static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
+0 −1
Original line number Diff line number Diff line
@@ -592,7 +592,6 @@ static void dtl1_detach(struct pcmcia_device *link)
static int dtl1_confcheck(struct pcmcia_device *p_dev,
			  cistpl_cftable_entry_t *cf,
			  cistpl_cftable_entry_t *dflt,
			  unsigned int vcc,
			  void *priv_data)
{
	if ((cf->io.nwin != 1) || (cf->io.win[0].len <= 8))
+0 −1
Original line number Diff line number Diff line
@@ -1744,7 +1744,6 @@ static void cmm_cm4000_release(struct pcmcia_device * link)
static int cm4000_config_check(struct pcmcia_device *p_dev,
			       cistpl_cftable_entry_t *cfg,
			       cistpl_cftable_entry_t *dflt,
			       unsigned int vcc,
			       void *priv_data)
{
	if (!cfg->io.nwin)
Loading